From 5cb0695f8783f201d93b798d9f17b8188905759f Mon Sep 17 00:00:00 2001 From: Jukka-Matti Turtiainen Date: Tue, 17 Mar 2026 18:10:36 +0200 Subject: [PATCH 1/3] docs: migrate from MkDocs + Structurizr to Starlight + LikeC4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace MkDocs (unmaintained since Aug 2024) with Astro Starlight at apps/docs/, and Structurizr DSL (archived CLI) with LikeC4 for C4 architecture diagrams. Starlight: - New apps/docs/ Astro app with full sidebar config matching old nav - Symlinks to existing docs/ — no file moves needed - Pagefind search, Mermaid rendering via rehype-mermaid - Workaround for zod v4 incompatibility (vite.ssr.noExternal) - Add title frontmatter to all 218 doc files for Starlight schema - Convert MkDocs !!! admonitions to Starlight ::: syntax (11 files) LikeC4: - 6 split model files at docs/architecture/likec4/ (L1-L3) - `pnpm docs:c4` exports 8 Mermaid diagrams - `pnpm docs:c4:serve` launches interactive C4 browser - Delete workspace.dsl Also includes: - Storybook scaffolding (.storybook/) - TypeDoc config for @variscout/core API docs - New architecture maps (system, component, data-pipeline) - New workflow maps (analysis-journey, investigation-lifecycle) - Documentation methodology doc Co-Authored-By: Claude Opus 4.6 (1M context) --- .storybook/main.ts | 16 + .storybook/manager.ts | 10 + .storybook/preview.tsx | 50 + .storybook/stories/README.md | 72 + .storybook/stories/charts/Boxplot.stories.tsx | 93 + .../charts/BoxplotStatsTable.stories.tsx | 63 + .../charts/CapabilityHistogram.stories.tsx | 51 + .../stories/charts/ChartLegend.stories.tsx | 54 + .../stories/charts/ChartSignature.stories.tsx | 25 + .../stories/charts/ChartSourceBar.stories.tsx | 47 + .storybook/stories/charts/IChart.stories.tsx | 81 + .../stories/charts/ParetoChart.stories.tsx | 66 + .../charts/PerformanceBoxplot.stories.tsx | 71 + .../charts/PerformanceCapability.stories.tsx | 70 + .../charts/PerformanceIChart.stories.tsx | 77 + .../charts/PerformancePareto.stories.tsx | 65 + .../charts/ProbabilityPlot.stories.tsx | 46 + .../stories/charts/ScatterPlot.stories.tsx | 56 + .../ui/analysis/AnovaResults.stories.tsx | 65 + .../ui/analysis/AxisEditor.stories.tsx | 33 + .../analysis/BoxplotDisplayToggle.stories.tsx | 47 + .../ui/analysis/FactorSelector.stories.tsx | 41 + .../analysis/InvestigationPrompt.stories.tsx | 41 + .../ui/analysis/StatsPanelBase.stories.tsx | 54 + .../ui/analysis/VariationBar.stories.tsx | 39 + .../ui/analysis/YAxisPopover.stories.tsx | 35 + .../charts/AnnotationContextMenu.stories.tsx | 35 + .../ui/charts/BoxplotWrapperBase.stories.tsx | 48 + .../charts/ChartAnnotationLayer.stories.tsx | 48 + .../stories/ui/charts/ChartCard.stories.tsx | 53 + .../ui/charts/ChartDownloadMenu.stories.tsx | 22 + .../ui/charts/EditableChartTitle.stories.tsx | 33 + .../charts/FocusedChartViewBase.stories.tsx | 38 + .../ui/charts/IChartWrapperBase.stories.tsx | 34 + .../charts/ParetoChartWrapperBase.stories.tsx | 39 + .../dashboard/DashboardChartCard.stories.tsx | 33 + .../ui/dashboard/DashboardGrid.stories.tsx | 33 + .../ui/dashboard/FocusedChartCard.stories.tsx | 32 + .../dashboard/FocusedViewOverlay.stories.tsx | 41 + .../PerformanceSetupPanelBase.stories.tsx | 50 + .../dashboard/SettingsPanelBase.stories.tsx | 42 + .../ui/data/DataQualityBanner.stories.tsx | 43 + .../stories/ui/data/DataTableBase.stories.tsx | 35 + .../ui/data/MobileCategorySheet.stories.tsx | 36 + .../data/PerformanceDetectedModal.stories.tsx | 31 + .../ui/findings/FindingBoardView.stories.tsx | 73 + .../ui/findings/FindingCard.stories.tsx | 77 + .../ui/findings/FindingComments.stories.tsx | 49 + .../ui/findings/FindingEditor.stories.tsx | 40 + .../findings/FindingStatusBadge.stories.tsx | 29 + .../ui/findings/FindingsLog.stories.tsx | 72 + .../ui/findings/FindingsPanel.stories.tsx | 72 + .../ui/findings/FindingsWindow.stories.tsx | 55 + .../CharacteristicTypeSelector.stories.tsx | 32 + .../ui/input/ColumnMapping.stories.tsx | 50 + .../ui/input/CreateFactorModal.stories.tsx | 33 + .../ui/input/ManualEntryBase.stories.tsx | 35 + .../ui/input/ManualEntrySetupBase.stories.tsx | 26 + .../input/MeasureColumnSelector.stories.tsx | 27 + .../ui/input/PasteScreenBase.stories.tsx | 22 + .../stories/ui/input/Slider.stories.tsx | 43 + .../stories/ui/input/SpecEditor.stories.tsx | 35 + .../stories/ui/input/SpecsPopover.stories.tsx | 31 + .../navigation/FilterBreadcrumb.stories.tsx | 45 + .../navigation/FilterChipDropdown.stories.tsx | 44 + .../navigation/FilterContextBar.stories.tsx | 43 + .../ui/navigation/SelectionPanel.stories.tsx | 32 + .../ui/simulation/WhatIfPageBase.stories.tsx | 22 + .../ui/simulation/WhatIfSimulator.stories.tsx | 27 + .../ui/utilities/ErrorBoundary.stories.tsx | 33 + .../ui/utilities/HelpTooltip.stories.tsx | 36 + .../ui/utilities/UpgradePrompt.stories.tsx | 29 + CLAUDE.md | 126 +- apps/docs/.astro/collections/docs.schema.json | 595 + apps/docs/.astro/content-assets.mjs | 1 + apps/docs/.astro/content-modules.mjs | 1 + apps/docs/.astro/content.d.ts | 218 + apps/docs/.astro/data-store.json | 17703 ++++++++++++++++ apps/docs/.astro/settings.json | 5 + apps/docs/.astro/types.d.ts | 2 + apps/docs/astro.config.mjs | 853 + apps/docs/package.json | 17 + apps/docs/src/content.config.ts | 10 + apps/docs/src/content/docs | 1 + apps/docs/src/styles/custom.css | 118 + apps/docs/tsconfig.json | 3 + .../evaluations/bottleneck-flow-map.md | 4 + .../competitive/edascout-benchmark.md | 4 + .../evaluations/competitive/jmp-benchmark.md | 4 + .../competitive/minitab-benchmark.md | 4 + .../competitive/minor-competitors.md | 4 + .../competitive/powerbi-benchmark.md | 4 + .../competitive/tableau-benchmark.md | 4 + .../design-brief-guided-investigation.md | 4 + .../design-spec-investigation-mindmap.md | 4 + .../evaluations/hospital-ward-flow-map.md | 4 + docs/01-vision/evaluations/index.md | 4 + .../evaluations/investigation-flow-map.md | 4 + .../evaluations/mindmap-chrome-evaluation.md | 4 + .../patterns/auto-combination-finder.md | 4 + .../evaluations/patterns/factor-map.md | 4 + .../evaluations/patterns/factor-suggestion.md | 4 + .../patterns/interaction-heatmap.md | 4 + .../patterns/investigation-mindmap.md | 4 + .../patterns/investigation-narrative.md | 4 + .../patterns/parallel-path-comparison.md | 4 + .../patterns/sidebar-filter-panel.md | 4 + .../evaluations/patterns/small-multiples.md | 4 + .../evaluations/tensions/discoverability.md | 4 + .../evaluations/tensions/factor-ordering.md | 4 + .../tensions/hierarchy-assumption.md | 4 + .../tensions/mobile-screen-budget.md | 4 + .../evaluations/tensions/path-dependency.md | 4 + .../evaluations/tensions/when-to-stop.md | 4 + docs/01-vision/four-lenses/change.md | 4 + docs/01-vision/four-lenses/drilldown.md | 10 +- docs/01-vision/four-lenses/failure.md | 4 + docs/01-vision/four-lenses/flow.md | 4 + docs/01-vision/four-lenses/index.md | 7 +- docs/01-vision/four-lenses/value.md | 4 + docs/01-vision/index.md | 4 + docs/01-vision/market-analysis.md | 7 +- docs/01-vision/philosophy.md | 4 + docs/01-vision/product-overview.md | 4 + docs/01-vision/progressive-stratification.md | 4 + docs/01-vision/two-voices/control-limits.md | 4 + docs/01-vision/two-voices/index.md | 4 + docs/01-vision/two-voices/scenarios.md | 7 +- docs/01-vision/two-voices/spec-limits.md | 4 + docs/01-vision/two-voices/variation-types.md | 7 +- docs/02-journeys/flows/azure-daily-use.md | 4 + .../02-journeys/flows/azure-first-analysis.md | 4 + .../flows/azure-team-collaboration.md | 4 + docs/02-journeys/flows/azure-teams-mobile.md | 4 + docs/02-journeys/flows/content-youtube.md | 4 + docs/02-journeys/flows/enterprise.md | 4 + docs/02-journeys/flows/return-visitor.md | 4 + docs/02-journeys/flows/seo-learner.md | 4 + docs/02-journeys/flows/social-discovery.md | 4 + docs/02-journeys/index.md | 4 + docs/02-journeys/personas/curious-carlos.md | 4 + docs/02-journeys/personas/evaluator-erik.md | 4 + docs/02-journeys/personas/field-fiona.md | 4 + docs/02-journeys/personas/green-belt-gary.md | 4 + docs/02-journeys/personas/opex-olivia.md | 4 + docs/02-journeys/personas/student-sara.md | 4 + docs/02-journeys/personas/trainer-tina.md | 4 + .../use-cases/batch-consistency.md | 4 + .../use-cases/bottleneck-analysis.md | 4 + .../use-cases/call-center-performance.md | 4 + .../use-cases/complaint-investigation.md | 4 + .../use-cases/consultant-delivery.md | 4 + docs/02-journeys/use-cases/copq-drilldown.md | 4 + docs/02-journeys/use-cases/index.md | 4 + .../use-cases/lead-time-variation.md | 4 + .../02-journeys/use-cases/on-time-delivery.md | 4 + .../use-cases/patient-wait-time.md | 4 + docs/02-journeys/use-cases/pharma-oos.md | 4 + .../use-cases/supplier-performance.md | 4 + docs/02-journeys/use-cases/supplier-ppap.md | 4 + docs/02-journeys/use-cases/university-spc.md | 4 + docs/02-journeys/ux-research.md | 4 + docs/03-features/analysis/boxplot.md | 6 + docs/03-features/analysis/capability.md | 6 + .../analysis/characteristic-types.md | 4 + docs/03-features/analysis/i-chart.md | 6 + docs/03-features/analysis/nelson-rules.md | 4 + docs/03-features/analysis/pareto.md | 6 + docs/03-features/analysis/performance-mode.md | 4 + docs/03-features/analysis/probability-plot.md | 4 + docs/03-features/analysis/staged-analysis.md | 6 + .../analysis/variation-decomposition.md | 4 + docs/03-features/data/data-input.md | 6 + docs/03-features/data/storage.md | 4 + docs/03-features/data/validation.md | 4 + docs/03-features/index.md | 11 + .../learning/case-based-learning.md | 4 + docs/03-features/learning/glossary.md | 4 + docs/03-features/learning/help-tooltips.md | 4 + docs/03-features/navigation/breadcrumbs.md | 4 + docs/03-features/navigation/drill-down.md | 4 + .../navigation/linked-filtering.md | 4 + docs/03-features/specifications.md | 4 + docs/03-features/user-guide.md | 4 + .../workflows/analysis-journey-map.md | 432 + docs/03-features/workflows/decision-trees.md | 4 + docs/03-features/workflows/deep-dive.md | 6 + .../workflows/drill-down-workflow.md | 9 +- .../workflows/four-lenses-workflow.md | 9 +- docs/03-features/workflows/index.md | 24 +- .../workflows/investigation-lifecycle-map.md | 155 + .../workflows/investigation-to-action.md | 6 + .../workflows/performance-mode-workflow.md | 7 +- docs/03-features/workflows/process-maps.md | 748 +- docs/03-features/workflows/quick-check.md | 9 +- docs/04-cases/avocado/index.md | 4 + docs/04-cases/bottleneck/index.md | 4 + docs/04-cases/coffee/index.md | 4 + docs/04-cases/hospital-ward/index.md | 4 + docs/04-cases/index.md | 4 + docs/04-cases/machine-utilization/index.md | 4 + docs/04-cases/oven-zones/index.md | 4 + docs/04-cases/packaging/index.md | 4 + docs/05-technical/architecture.md | 4 + .../architecture/component-map.md | 416 + .../architecture/component-patterns.md | 4 + docs/05-technical/architecture/data-flow.md | 16 +- .../architecture/data-pipeline-map.md | 502 + .../generated/ChartsComponents.mmd | 31 + .../architecture/generated/Containers.mmd | 41 + .../architecture/generated/CoreComponents.mmd | 34 + .../architecture/generated/DataComponents.mmd | 11 + .../generated/HooksComponents.mmd | 29 + .../architecture/generated/SystemContext.mmd | 41 + .../architecture/generated/UIComponents.mmd | 56 + .../architecture/generated/index.mmd | 16 + docs/05-technical/architecture/monorepo.md | 4 + .../architecture/offline-first.md | 4 + .../architecture/shared-packages.md | 4 + docs/05-technical/architecture/system-map.md | 122 + .../05-technical/documentation-methodology.md | 418 + .../implementation/azure-testing-plan.md | 4 + .../05-technical/implementation/data-input.md | 4 + .../05-technical/implementation/deployment.md | 4 + .../implementation/glm-roadmap.md | 4 + .../phase2-regression-roadmap.md | 4 + docs/05-technical/implementation/ruflo.md | 4 + .../implementation/security-scanning.md | 4 + .../implementation/system-limits.md | 4 + docs/05-technical/implementation/testing.md | 4 + docs/05-technical/index.md | 23 +- .../integrations/embed-messaging.md | 4 + docs/05-technical/integrations/shared-ui.md | 4 + docs/05-technical/statistics-reference.md | 6 +- docs/06-design-system/charts/boxplot.md | 4 + docs/06-design-system/charts/capability.md | 4 + docs/06-design-system/charts/colors.md | 4 + .../06-design-system/charts/executive-mode.md | 4 + docs/06-design-system/charts/hooks.md | 4 + docs/06-design-system/charts/ichart.md | 4 + docs/06-design-system/charts/overview.md | 4 + docs/06-design-system/charts/pareto.md | 4 + .../charts/performance-mode.md | 4 + .../charts/probability-plot.md | 4 + docs/06-design-system/charts/responsive.md | 4 + .../charts/shared-components.md | 4 + docs/06-design-system/components/buttons.md | 4 + docs/06-design-system/components/cards.md | 4 + docs/06-design-system/components/forms.md | 4 + docs/06-design-system/components/modals.md | 4 + .../components/variation-funnel.md | 4 + .../components/what-if-simulator.md | 4 + .../foundations/accessibility.md | 4 + docs/06-design-system/foundations/colors.md | 4 + docs/06-design-system/foundations/spacing.md | 4 + .../foundations/typography.md | 4 + docs/06-design-system/index.md | 4 + docs/06-design-system/patterns/feedback.md | 4 + .../06-design-system/patterns/interactions.md | 4 + docs/06-design-system/patterns/layout.md | 4 + docs/06-design-system/patterns/navigation.md | 4 + .../patterns/panels-and-drawers.md | 4 + docs/07-decisions/adr-001-monorepo.md | 4 + docs/07-decisions/adr-002-visx-charts.md | 4 + docs/07-decisions/adr-003-indexeddb.md | 4 + docs/07-decisions/adr-004-offline-first.md | 4 + .../adr-005-props-based-charts.md | 4 + docs/07-decisions/adr-006-edition-system.md | 4 + .../adr-007-azure-marketplace-distribution.md | 4 + .../adr-008-website-content-architecture.md | 4 + .../adr-009-boxplot-violin-mode.md | 4 + docs/07-decisions/adr-010-gagerr-deferral.md | 4 + .../adr-011-ai-development-tooling.md | 4 + docs/07-decisions/adr-012-pwa-browser-only.md | 4 + ...-013-architecture-evaluation-ddd-swarms.md | 4 + .../adr-014-regression-deferral.md | 4 + .../adr-015-investigation-board.md | 4 + .../adr-016-security-evaluation.md | 4 + .../07-decisions/adr-016-teams-integration.md | 4 + .../adr-017-fluent-design-alignment.md | 4 + .../adr-018-channel-mention-workflow.md | 4 + .../audit-2026-02-state-of-product.md | 4 + docs/07-decisions/index.md | 63 + docs/08-products/azure/arm-template.md | 4 + docs/08-products/azure/authentication.md | 4 + docs/08-products/azure/certification-guide.md | 4 + docs/08-products/azure/how-it-works.md | 4 + docs/08-products/azure/index.md | 4 + docs/08-products/azure/marketplace.md | 4 + docs/08-products/azure/onedrive-sync.md | 4 + docs/08-products/azure/pricing-tiers.md | 4 + docs/08-products/azure/storage.md | 4 + .../08-products/azure/submission-checklist.md | 4 + docs/08-products/feature-parity.md | 4 + docs/08-products/index.md | 7 +- docs/08-products/powerbi/index.md | 4 + docs/08-products/pwa/index.md | 4 + docs/08-products/pwa/storage.md | 4 + .../website/content-architecture.md | 4 + docs/08-products/website/design-philosophy.md | 4 + docs/08-products/website/index.md | 4 + docs/architecture/likec4/charts.c4 | 94 + docs/architecture/likec4/core.c4 | 63 + docs/architecture/likec4/hooks.c4 | 94 + docs/architecture/likec4/model.c4 | 144 + docs/architecture/likec4/ui.c4 | 267 + docs/architecture/likec4/views.c4 | 69 + docs/archive/brushing-usage-example.md | 4 + docs/archive/create-factor-guide.md | 4 + docs/archive/implementation-summary.md | 4 + docs/archive/minitab-brushing.md | 4 + docs/archive/performance-mode-optimization.md | 4 + docs/archive/phase1-complete.md | 4 + docs/archive/phases3-5-complete.md | 4 + docs/archive/regression.md | 7 +- .../archive/special-cause-education-phase2.md | 4 + docs/glossary.md | 4 + docs/index.md | 48 +- docs/stylesheets/extra.css | 283 - mkdocs.yml | 287 - package.json | 18 +- packages/core/package.json | 5 +- packages/core/typedoc.json | 13 + pnpm-lock.yaml | 3741 +++- 324 files changed, 30562 insertions(+), 1492 deletions(-) create mode 100644 .storybook/main.ts create mode 100644 .storybook/manager.ts create mode 100644 .storybook/preview.tsx create mode 100644 .storybook/stories/README.md create mode 100644 .storybook/stories/charts/Boxplot.stories.tsx create mode 100644 .storybook/stories/charts/BoxplotStatsTable.stories.tsx create mode 100644 .storybook/stories/charts/CapabilityHistogram.stories.tsx create mode 100644 .storybook/stories/charts/ChartLegend.stories.tsx create mode 100644 .storybook/stories/charts/ChartSignature.stories.tsx create mode 100644 .storybook/stories/charts/ChartSourceBar.stories.tsx create mode 100644 .storybook/stories/charts/IChart.stories.tsx create mode 100644 .storybook/stories/charts/ParetoChart.stories.tsx create mode 100644 .storybook/stories/charts/PerformanceBoxplot.stories.tsx create mode 100644 .storybook/stories/charts/PerformanceCapability.stories.tsx create mode 100644 .storybook/stories/charts/PerformanceIChart.stories.tsx create mode 100644 .storybook/stories/charts/PerformancePareto.stories.tsx create mode 100644 .storybook/stories/charts/ProbabilityPlot.stories.tsx create mode 100644 .storybook/stories/charts/ScatterPlot.stories.tsx create mode 100644 .storybook/stories/ui/analysis/AnovaResults.stories.tsx create mode 100644 .storybook/stories/ui/analysis/AxisEditor.stories.tsx create mode 100644 .storybook/stories/ui/analysis/BoxplotDisplayToggle.stories.tsx create mode 100644 .storybook/stories/ui/analysis/FactorSelector.stories.tsx create mode 100644 .storybook/stories/ui/analysis/InvestigationPrompt.stories.tsx create mode 100644 .storybook/stories/ui/analysis/StatsPanelBase.stories.tsx create mode 100644 .storybook/stories/ui/analysis/VariationBar.stories.tsx create mode 100644 .storybook/stories/ui/analysis/YAxisPopover.stories.tsx create mode 100644 .storybook/stories/ui/charts/AnnotationContextMenu.stories.tsx create mode 100644 .storybook/stories/ui/charts/BoxplotWrapperBase.stories.tsx create mode 100644 .storybook/stories/ui/charts/ChartAnnotationLayer.stories.tsx create mode 100644 .storybook/stories/ui/charts/ChartCard.stories.tsx create mode 100644 .storybook/stories/ui/charts/ChartDownloadMenu.stories.tsx create mode 100644 .storybook/stories/ui/charts/EditableChartTitle.stories.tsx create mode 100644 .storybook/stories/ui/charts/FocusedChartViewBase.stories.tsx create mode 100644 .storybook/stories/ui/charts/IChartWrapperBase.stories.tsx create mode 100644 .storybook/stories/ui/charts/ParetoChartWrapperBase.stories.tsx create mode 100644 .storybook/stories/ui/dashboard/DashboardChartCard.stories.tsx create mode 100644 .storybook/stories/ui/dashboard/DashboardGrid.stories.tsx create mode 100644 .storybook/stories/ui/dashboard/FocusedChartCard.stories.tsx create mode 100644 .storybook/stories/ui/dashboard/FocusedViewOverlay.stories.tsx create mode 100644 .storybook/stories/ui/dashboard/PerformanceSetupPanelBase.stories.tsx create mode 100644 .storybook/stories/ui/dashboard/SettingsPanelBase.stories.tsx create mode 100644 .storybook/stories/ui/data/DataQualityBanner.stories.tsx create mode 100644 .storybook/stories/ui/data/DataTableBase.stories.tsx create mode 100644 .storybook/stories/ui/data/MobileCategorySheet.stories.tsx create mode 100644 .storybook/stories/ui/data/PerformanceDetectedModal.stories.tsx create mode 100644 .storybook/stories/ui/findings/FindingBoardView.stories.tsx create mode 100644 .storybook/stories/ui/findings/FindingCard.stories.tsx create mode 100644 .storybook/stories/ui/findings/FindingComments.stories.tsx create mode 100644 .storybook/stories/ui/findings/FindingEditor.stories.tsx create mode 100644 .storybook/stories/ui/findings/FindingStatusBadge.stories.tsx create mode 100644 .storybook/stories/ui/findings/FindingsLog.stories.tsx create mode 100644 .storybook/stories/ui/findings/FindingsPanel.stories.tsx create mode 100644 .storybook/stories/ui/findings/FindingsWindow.stories.tsx create mode 100644 .storybook/stories/ui/input/CharacteristicTypeSelector.stories.tsx create mode 100644 .storybook/stories/ui/input/ColumnMapping.stories.tsx create mode 100644 .storybook/stories/ui/input/CreateFactorModal.stories.tsx create mode 100644 .storybook/stories/ui/input/ManualEntryBase.stories.tsx create mode 100644 .storybook/stories/ui/input/ManualEntrySetupBase.stories.tsx create mode 100644 .storybook/stories/ui/input/MeasureColumnSelector.stories.tsx create mode 100644 .storybook/stories/ui/input/PasteScreenBase.stories.tsx create mode 100644 .storybook/stories/ui/input/Slider.stories.tsx create mode 100644 .storybook/stories/ui/input/SpecEditor.stories.tsx create mode 100644 .storybook/stories/ui/input/SpecsPopover.stories.tsx create mode 100644 .storybook/stories/ui/navigation/FilterBreadcrumb.stories.tsx create mode 100644 .storybook/stories/ui/navigation/FilterChipDropdown.stories.tsx create mode 100644 .storybook/stories/ui/navigation/FilterContextBar.stories.tsx create mode 100644 .storybook/stories/ui/navigation/SelectionPanel.stories.tsx create mode 100644 .storybook/stories/ui/simulation/WhatIfPageBase.stories.tsx create mode 100644 .storybook/stories/ui/simulation/WhatIfSimulator.stories.tsx create mode 100644 .storybook/stories/ui/utilities/ErrorBoundary.stories.tsx create mode 100644 .storybook/stories/ui/utilities/HelpTooltip.stories.tsx create mode 100644 .storybook/stories/ui/utilities/UpgradePrompt.stories.tsx create mode 100644 apps/docs/.astro/collections/docs.schema.json create mode 100644 apps/docs/.astro/content-assets.mjs create mode 100644 apps/docs/.astro/content-modules.mjs create mode 100644 apps/docs/.astro/content.d.ts create mode 100644 apps/docs/.astro/data-store.json create mode 100644 apps/docs/.astro/settings.json create mode 100644 apps/docs/.astro/types.d.ts create mode 100644 apps/docs/astro.config.mjs create mode 100644 apps/docs/package.json create mode 100644 apps/docs/src/content.config.ts create mode 120000 apps/docs/src/content/docs create mode 100644 apps/docs/src/styles/custom.css create mode 100644 apps/docs/tsconfig.json create mode 100644 docs/03-features/workflows/analysis-journey-map.md create mode 100644 docs/03-features/workflows/investigation-lifecycle-map.md create mode 100644 docs/05-technical/architecture/component-map.md create mode 100644 docs/05-technical/architecture/data-pipeline-map.md create mode 100644 docs/05-technical/architecture/generated/ChartsComponents.mmd create mode 100644 docs/05-technical/architecture/generated/Containers.mmd create mode 100644 docs/05-technical/architecture/generated/CoreComponents.mmd create mode 100644 docs/05-technical/architecture/generated/DataComponents.mmd create mode 100644 docs/05-technical/architecture/generated/HooksComponents.mmd create mode 100644 docs/05-technical/architecture/generated/SystemContext.mmd create mode 100644 docs/05-technical/architecture/generated/UIComponents.mmd create mode 100644 docs/05-technical/architecture/generated/index.mmd create mode 100644 docs/05-technical/architecture/system-map.md create mode 100644 docs/05-technical/documentation-methodology.md create mode 100644 docs/architecture/likec4/charts.c4 create mode 100644 docs/architecture/likec4/core.c4 create mode 100644 docs/architecture/likec4/hooks.c4 create mode 100644 docs/architecture/likec4/model.c4 create mode 100644 docs/architecture/likec4/ui.c4 create mode 100644 docs/architecture/likec4/views.c4 delete mode 100644 docs/stylesheets/extra.css delete mode 100644 mkdocs.yml create mode 100644 packages/core/typedoc.json diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 000000000..28d3ca28c --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,16 @@ +import type { StorybookConfig } from '@storybook/react-vite'; + +const config: StorybookConfig = { + stories: ['./stories/**/*.stories.@(ts|tsx)'], + addons: ['@storybook/addon-essentials', '@storybook/addon-a11y', '@storybook/addon-themes'], + framework: { + name: '@storybook/react-vite', + options: {}, + }, + viteFinal: async config => { + // Ensure Tailwind CSS is processed + return config; + }, +}; + +export default config; diff --git a/.storybook/manager.ts b/.storybook/manager.ts new file mode 100644 index 000000000..9ef875bd9 --- /dev/null +++ b/.storybook/manager.ts @@ -0,0 +1,10 @@ +import { addons } from '@storybook/manager-api'; +import { themes } from '@storybook/theming'; + +addons.setConfig({ + theme: { + ...themes.dark, + brandTitle: 'VariScout Components', + brandUrl: '/', + }, +}); diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 000000000..deb004d23 --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,50 @@ +import type { Preview } from '@storybook/react'; +import '../packages/ui/src/styles/theme.css'; +import '../packages/ui/src/styles/components.css'; + +const preview: Preview = { + globalTypes: { + theme: { + name: 'Theme', + description: 'Color theme', + defaultValue: 'dark', + toolbar: { + icon: 'circlehollow', + items: [ + { value: 'dark', icon: 'moon', title: 'Dark' }, + { value: 'light', icon: 'sun', title: 'Light' }, + ], + dynamicTitle: true, + }, + }, + chartMode: { + name: 'Chart Mode', + description: 'Chart color mode', + defaultValue: 'technical', + toolbar: { + icon: 'graphline', + items: [ + { value: 'technical', title: 'Technical' }, + { value: 'executive', title: 'Executive' }, + ], + dynamicTitle: true, + }, + }, + }, + decorators: [ + (Story, context) => { + document.documentElement.setAttribute('data-theme', context.globals.theme || 'dark'); + document.documentElement.setAttribute( + 'data-chart-mode', + context.globals.chartMode || 'technical' + ); + return ; + }, + ], + parameters: { + controls: { matchers: { color: /(background|color)$/i, date: /Date$/i } }, + layout: 'centered', + }, +}; + +export default preview; diff --git a/.storybook/stories/README.md b/.storybook/stories/README.md new file mode 100644 index 000000000..92c5a873a --- /dev/null +++ b/.storybook/stories/README.md @@ -0,0 +1,72 @@ +# VariScout Storybook Story Conventions + +## File Naming + +- `ComponentName.stories.tsx` +- One story file per component + +## Title Convention + +Stories are organized by category: + +| Category | Title prefix | Example | +| ---------------------- | ---------------- | -------------------------------- | +| Chart primitives | `Charts/` | `Charts/IChart` | +| UI Input components | `UI/Input/` | `UI/Input/ColumnMapping` | +| UI Data components | `UI/Data/` | `UI/Data/DataQualityBanner` | +| UI Analysis components | `UI/Analysis/` | `UI/Analysis/AnovaResults` | +| UI Chart wrappers | `UI/Charts/` | `UI/Charts/ChartCard` | +| UI Navigation | `UI/Navigation/` | `UI/Navigation/FilterBreadcrumb` | +| UI Findings | `UI/Findings/` | `UI/Findings/FindingCard` | +| UI Simulation | `UI/Simulation/` | `UI/Simulation/WhatIfSimulator` | +| UI Dashboard | `UI/Dashboard/` | `UI/Dashboard/DashboardGrid` | +| UI Utilities | `UI/Utilities/` | `UI/Utilities/HelpTooltip` | + +## Story Structure + +```tsx +import type { Meta, StoryObj } from '@storybook/react'; +import { ComponentName } from '../path/to/component'; + +const meta = { + title: 'Category/ComponentName', + component: ComponentName, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + /* default props */ + }, +}; +``` + +## Auto-Generated Docs + +Use `tags: ['autodocs']` on every story to enable automatic documentation pages. + +## Sample Data + +- Import sample datasets from `@variscout/data` (e.g., `SAMPLES`, `getSample`) +- Use `calculateStats` from `@variscout/core` for computed statistical data +- For simple demos, use inline mock data arrays + +## Theme Integration + +The Storybook toolbar provides: + +- **Theme** toggle: Sets `data-theme` attribute (`dark` / `light`) +- **Chart Mode** toggle: Sets `data-chart-mode` attribute (`technical` / `executive`) + +Components that read these attributes will respond automatically. + +## Color Schemes + +Many UI components accept a `colorScheme` prop. Use the exported `defaultScheme` for each component: + +```tsx +import { AnovaResults, anovaDefaultColorScheme } from '@variscout/ui'; +``` diff --git a/.storybook/stories/charts/Boxplot.stories.tsx b/.storybook/stories/charts/Boxplot.stories.tsx new file mode 100644 index 000000000..88da536cb --- /dev/null +++ b/.storybook/stories/charts/Boxplot.stories.tsx @@ -0,0 +1,93 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { BoxplotBase } from '../../../packages/charts/src/index'; +import type { BoxplotGroupData, SpecLimits } from '../../../packages/charts/src/index'; + +function makeGroup(key: string, center: number, spread: number): BoxplotGroupData { + const values: number[] = []; + for (let i = 0; i < 30; i++) { + values.push(center + (Math.random() - 0.5) * spread * 2); + } + values.sort((a, b) => a - b); + const q1 = values[7]; + const median = values[15]; + const q3 = values[22]; + const iqr = q3 - q1; + return { + key, + values, + min: Math.max(values[0], q1 - 1.5 * iqr), + max: Math.min(values[29], q3 + 1.5 * iqr), + q1, + median, + mean: values.reduce((a, b) => a + b, 0) / values.length, + q3, + outliers: values.filter(v => v < q1 - 1.5 * iqr || v > q3 + 1.5 * iqr), + stdDev: spread * 0.6, + }; +} + +const mockData: BoxplotGroupData[] = [ + makeGroup('Line A', 10.0, 0.5), + makeGroup('Line B', 10.3, 0.8), + makeGroup('Line C', 9.7, 0.4), + makeGroup('Line D', 10.1, 1.0), +]; + +const mockSpecs: SpecLimits = { usl: 11.0, lsl: 9.0, target: 10.0 }; + +const meta = { + title: 'Charts/Boxplot', + component: BoxplotBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + data: mockData, + specs: mockSpecs, + parentWidth: 800, + parentHeight: 500, + yAxisLabel: 'Weight (g)', + xAxisLabel: 'Production Line', + }, +}; + +export const WithViolin: Story = { + args: { + ...Default.args, + showViolin: true, + }, +}; + +export const WithContributions: Story = { + args: { + ...Default.args, + categoryContributions: new Map([ + ['Line A', 15], + ['Line B', 45], + ['Line C', 10], + ['Line D', 30], + ]), + showContributionLabels: true, + showContributionBars: true, + }, +}; + +export const WithHighlights: Story = { + args: { + ...Default.args, + highlightedCategories: { 'Line B': 'red', 'Line C': 'green' }, + }, +}; + +export const Compact: Story = { + args: { + ...Default.args, + parentWidth: 400, + parentHeight: 300, + }, +}; diff --git a/.storybook/stories/charts/BoxplotStatsTable.stories.tsx b/.storybook/stories/charts/BoxplotStatsTable.stories.tsx new file mode 100644 index 000000000..8cde004d1 --- /dev/null +++ b/.storybook/stories/charts/BoxplotStatsTable.stories.tsx @@ -0,0 +1,63 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import BoxplotStatsTable from '../../../packages/charts/src/BoxplotStatsTable'; +import type { BoxplotGroupData } from '../../../packages/charts/src/index'; + +function makeGroup(key: string, mean: number, stdDev: number): BoxplotGroupData { + const values = Array.from({ length: 25 }, () => mean + (Math.random() - 0.5) * stdDev * 4); + values.sort((a, b) => a - b); + return { + key, + values, + min: values[0], + max: values[values.length - 1], + q1: values[6], + median: values[12], + mean, + q3: values[18], + outliers: [], + stdDev, + }; +} + +const mockData: BoxplotGroupData[] = [ + makeGroup('Monday', 10.1, 0.3), + makeGroup('Tuesday', 10.3, 0.5), + makeGroup('Wednesday', 9.8, 0.2), + makeGroup('Thursday', 10.0, 0.9), + makeGroup('Friday', 10.2, 0.4), +]; + +const meta = { + title: 'Charts/BoxplotStatsTable', + component: BoxplotStatsTable, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + data: mockData, + }, +}; + +export const WithContributions: Story = { + args: { + data: mockData, + categoryContributions: new Map([ + ['Monday', 12], + ['Tuesday', 38], + ['Wednesday', 8], + ['Thursday', 32], + ['Friday', 10], + ]), + }, +}; + +export const Compact: Story = { + args: { + data: mockData, + compact: true, + }, +}; diff --git a/.storybook/stories/charts/CapabilityHistogram.stories.tsx b/.storybook/stories/charts/CapabilityHistogram.stories.tsx new file mode 100644 index 000000000..d29f53995 --- /dev/null +++ b/.storybook/stories/charts/CapabilityHistogram.stories.tsx @@ -0,0 +1,51 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { CapabilityHistogramBase } from '../../../packages/charts/src/index'; + +const mockValues = Array.from({ length: 100 }, () => 10.0 + (Math.random() - 0.5) * 2); + +const meta = { + title: 'Charts/CapabilityHistogram', + component: CapabilityHistogramBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + data: mockValues, + specs: { usl: 11.5, lsl: 8.5, target: 10.0 }, + mean: 10.0, + parentWidth: 600, + parentHeight: 400, + }, +}; + +export const OffCenter: Story = { + args: { + data: mockValues.map(v => v + 0.8), + specs: { usl: 11.5, lsl: 8.5, target: 10.0 }, + mean: 10.8, + parentWidth: 600, + parentHeight: 400, + }, +}; + +export const NoSpecs: Story = { + args: { + data: mockValues, + specs: {}, + mean: 10.0, + parentWidth: 600, + parentHeight: 400, + }, +}; + +export const WithBranding: Story = { + args: { + ...Default.args, + showBranding: true, + }, +}; diff --git a/.storybook/stories/charts/ChartLegend.stories.tsx b/.storybook/stories/charts/ChartLegend.stories.tsx new file mode 100644 index 000000000..daee91c67 --- /dev/null +++ b/.storybook/stories/charts/ChartLegend.stories.tsx @@ -0,0 +1,54 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import ChartLegend from '../../../packages/charts/src/ChartLegend'; + +const meta = { + title: 'Charts/ChartLegend', + component: ChartLegend, + tags: ['autodocs'], + decorators: [ + Story => ( + + + + ), + ], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Educational: Story = { + args: { + mode: 'educational', + width: 800, + top: 10, + show: true, + }, +}; + +export const Practical: Story = { + args: { + mode: 'practical', + width: 800, + top: 10, + show: true, + }, +}; + +export const Hidden: Story = { + args: { + mode: 'educational', + width: 800, + top: 10, + show: false, + }, +}; + +export const Narrow: Story = { + args: { + mode: 'educational', + width: 400, + top: 10, + show: true, + }, +}; diff --git a/.storybook/stories/charts/ChartSignature.stories.tsx b/.storybook/stories/charts/ChartSignature.stories.tsx new file mode 100644 index 000000000..07c95330b --- /dev/null +++ b/.storybook/stories/charts/ChartSignature.stories.tsx @@ -0,0 +1,25 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import ChartSignature from '../../../packages/charts/src/ChartSignature'; + +const meta = { + title: 'Charts/ChartSignature', + component: ChartSignature, + tags: ['autodocs'], + decorators: [ + Story => ( + + + + ), + ], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + x: 380, + y: 40, + }, +}; diff --git a/.storybook/stories/charts/ChartSourceBar.stories.tsx b/.storybook/stories/charts/ChartSourceBar.stories.tsx new file mode 100644 index 000000000..3fffa3d8f --- /dev/null +++ b/.storybook/stories/charts/ChartSourceBar.stories.tsx @@ -0,0 +1,47 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import ChartSourceBar from '../../../packages/charts/src/ChartSourceBar'; + +const meta = { + title: 'Charts/ChartSourceBar', + component: ChartSourceBar, + tags: ['autodocs'], + decorators: [ + Story => ( + + + + ), + ], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + width: 800, + top: 5, + n: 150, + forceShow: true, + }, +}; + +export const WithCustomText: Story = { + args: { + width: 800, + top: 5, + n: 42, + brandingText: 'VariScout Azure', + forceShow: true, + }, +}; + +export const CustomAccent: Story = { + args: { + width: 800, + top: 5, + n: 75, + accentColor: '#22c55e', + forceShow: true, + }, +}; diff --git a/.storybook/stories/charts/IChart.stories.tsx b/.storybook/stories/charts/IChart.stories.tsx new file mode 100644 index 000000000..98b9dc689 --- /dev/null +++ b/.storybook/stories/charts/IChart.stories.tsx @@ -0,0 +1,81 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { IChartBase } from '../../../packages/charts/src/index'; +import type { IChartDataPoint, StatsResult, SpecLimits } from '../../../packages/charts/src/index'; + +const mockValues = [ + 10.2, 9.8, 10.5, 10.1, 9.9, 10.3, 10.0, 9.7, 10.4, 10.2, 9.8, 10.1, 10.3, 9.9, 10.0, 10.2, 9.8, + 10.5, 10.1, 9.9, 10.6, 9.5, 10.3, 10.0, 9.8, 10.1, 10.4, 9.7, 10.2, 10.0, +]; + +const mockData: IChartDataPoint[] = mockValues.map((y, i) => ({ x: i, y })); + +const mockStats: StatsResult = { + mean: 10.08, + median: 10.05, + stdDev: 0.27, + sigmaWithin: 0.24, + mrBar: 0.27, + ucl: 10.8, + lcl: 9.36, + cp: 1.39, + cpk: 1.28, + outOfSpecPercentage: 0, +}; + +const mockSpecs: SpecLimits = { usl: 11.0, lsl: 9.0, target: 10.0 }; + +const meta = { + title: 'Charts/IChart', + component: IChartBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + data: mockData, + stats: mockStats, + specs: mockSpecs, + parentWidth: 800, + parentHeight: 400, + yAxisLabel: 'Weight (g)', + }, +}; + +export const WithoutSpecs: Story = { + args: { + data: mockData, + stats: mockStats, + specs: {}, + parentWidth: 800, + parentHeight: 400, + yAxisLabel: 'Weight (g)', + }, +}; + +export const WithBranding: Story = { + args: { + ...Default.args, + showBranding: true, + sampleSize: 30, + }, +}; + +export const WithLegend: Story = { + args: { + ...Default.args, + showLegend: true, + legendMode: 'educational', + }, +}; + +export const Compact: Story = { + args: { + ...Default.args, + parentWidth: 400, + parentHeight: 250, + }, +}; diff --git a/.storybook/stories/charts/ParetoChart.stories.tsx b/.storybook/stories/charts/ParetoChart.stories.tsx new file mode 100644 index 000000000..e345ca54b --- /dev/null +++ b/.storybook/stories/charts/ParetoChart.stories.tsx @@ -0,0 +1,66 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ParetoChartBase } from '../../../packages/charts/src/index'; +import type { ParetoDataPoint } from '../../../packages/charts/src/index'; + +const rawCounts = [ + { key: 'Seal defect', value: 42 }, + { key: 'Weight error', value: 28 }, + { key: 'Print smear', value: 15 }, + { key: 'Tear', value: 10 }, + { key: 'Misalign', value: 5 }, +]; + +const total = rawCounts.reduce((s, d) => s + d.value, 0); +let cumulative = 0; +const mockData: ParetoDataPoint[] = rawCounts.map(d => { + cumulative += d.value; + return { + key: d.key, + value: d.value, + cumulative, + cumulativePercentage: (cumulative / total) * 100, + }; +}); + +const meta = { + title: 'Charts/ParetoChart', + component: ParetoChartBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + data: mockData, + totalCount: total, + parentWidth: 800, + parentHeight: 450, + xAxisLabel: 'Defect Type', + yAxisLabel: 'Count', + }, +}; + +export const WithHighlights: Story = { + args: { + ...Default.args, + highlightedCategories: { 'Seal defect': 'red', 'Print smear': 'amber' }, + }, +}; + +export const WithBranding: Story = { + args: { + ...Default.args, + showBranding: true, + }, +}; + +export const Compact: Story = { + args: { + ...Default.args, + parentWidth: 400, + parentHeight: 300, + }, +}; diff --git a/.storybook/stories/charts/PerformanceBoxplot.stories.tsx b/.storybook/stories/charts/PerformanceBoxplot.stories.tsx new file mode 100644 index 000000000..6bf58fc2f --- /dev/null +++ b/.storybook/stories/charts/PerformanceBoxplot.stories.tsx @@ -0,0 +1,71 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { PerformanceBoxplotBase } from '../../../packages/charts/src/index'; +import type { ChannelResult } from '../../../packages/charts/src/index'; + +function makeChannel(id: string, mean: number, spread: number): ChannelResult { + const values = Array.from({ length: 30 }, () => mean + (Math.random() - 0.5) * spread * 2); + const cpk = 1.0 / (spread * 3); + return { + id, + label: id, + n: values.length, + mean, + stdDev: spread, + cp: cpk + 0.1, + cpk, + min: Math.min(...values), + max: Math.max(...values), + health: + cpk >= 1.67 ? 'excellent' : cpk >= 1.33 ? 'capable' : cpk >= 1.0 ? 'warning' : 'critical', + outOfSpecPercentage: 0, + values, + }; +} + +const mockChannels: ChannelResult[] = [ + makeChannel('Head 1', 100.2, 0.3), + makeChannel('Head 2', 99.8, 0.5), + makeChannel('Head 3', 100.5, 0.2), + makeChannel('Head 4', 100.0, 0.8), + makeChannel('Head 5', 99.5, 0.4), +]; + +const meta = { + title: 'Charts/PerformanceBoxplot', + component: PerformanceBoxplotBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + channels: mockChannels, + specs: { usl: 101.5, lsl: 98.5, target: 100.0 }, + parentWidth: 800, + parentHeight: 500, + }, +}; + +export const WithSelectedChannel: Story = { + args: { + ...Default.args, + selectedMeasure: 'Head 4', + }, +}; + +export const WithStatsTable: Story = { + args: { + ...Default.args, + showStatsTable: true, + }, +}; + +export const WithViolin: Story = { + args: { + ...Default.args, + showViolin: true, + }, +}; diff --git a/.storybook/stories/charts/PerformanceCapability.stories.tsx b/.storybook/stories/charts/PerformanceCapability.stories.tsx new file mode 100644 index 000000000..f187953e4 --- /dev/null +++ b/.storybook/stories/charts/PerformanceCapability.stories.tsx @@ -0,0 +1,70 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { PerformanceCapabilityBase } from '../../../packages/charts/src/index'; +import type { ChannelResult } from '../../../packages/charts/src/index'; + +const capableChannel: ChannelResult = { + id: 'Valve 1', + label: 'Valve 1', + n: 50, + mean: 100.0, + stdDev: 0.3, + cp: 1.67, + cpk: 1.55, + min: 98.8, + max: 101.2, + health: 'capable', + outOfSpecPercentage: 0, + values: Array.from({ length: 50 }, () => 100 + (Math.random() - 0.5) * 1.2), +}; + +const criticalChannel: ChannelResult = { + id: 'Valve 3', + label: 'Valve 3', + n: 50, + mean: 100.8, + stdDev: 0.6, + cp: 0.83, + cpk: 0.72, + min: 98.5, + max: 102.5, + health: 'critical', + outOfSpecPercentage: 4.5, + values: Array.from({ length: 50 }, () => 100.8 + (Math.random() - 0.5) * 3), +}; + +const meta = { + title: 'Charts/PerformanceCapability', + component: PerformanceCapabilityBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const CapableChannel: Story = { + args: { + channel: capableChannel, + specs: { usl: 101.5, lsl: 98.5, target: 100.0 }, + parentWidth: 600, + parentHeight: 400, + }, +}; + +export const CriticalChannel: Story = { + args: { + channel: criticalChannel, + specs: { usl: 101.5, lsl: 98.5, target: 100.0 }, + parentWidth: 600, + parentHeight: 400, + }, +}; + +export const NoChannel: Story = { + args: { + channel: null, + specs: { usl: 101.5, lsl: 98.5 }, + parentWidth: 600, + parentHeight: 400, + }, +}; diff --git a/.storybook/stories/charts/PerformanceIChart.stories.tsx b/.storybook/stories/charts/PerformanceIChart.stories.tsx new file mode 100644 index 000000000..4bb62608f --- /dev/null +++ b/.storybook/stories/charts/PerformanceIChart.stories.tsx @@ -0,0 +1,77 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { PerformanceIChartBase } from '../../../packages/charts/src/index'; +import type { ChannelResult } from '../../../packages/charts/src/index'; + +function makeChannel(id: string, cpk: number): ChannelResult { + const values = Array.from({ length: 30 }, () => 10 + (Math.random() - 0.5) * (2 / cpk)); + return { + id, + label: id, + n: values.length, + mean: values.reduce((a, b) => a + b, 0) / values.length, + stdDev: 1 / (3 * cpk), + cp: cpk + 0.1, + cpk, + min: Math.min(...values), + max: Math.max(...values), + health: + cpk >= 1.67 ? 'excellent' : cpk >= 1.33 ? 'capable' : cpk >= 1.0 ? 'warning' : 'critical', + outOfSpecPercentage: cpk >= 1.33 ? 0 : 2.5, + values, + }; +} + +const mockChannels: ChannelResult[] = [ + makeChannel('Valve 1', 1.85), + makeChannel('Valve 2', 1.45), + makeChannel('Valve 3', 0.92), + makeChannel('Valve 4', 1.67), + makeChannel('Valve 5', 1.12), + makeChannel('Valve 6', 2.01), +]; + +const meta = { + title: 'Charts/PerformanceIChart', + component: PerformanceIChartBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + channels: mockChannels, + parentWidth: 800, + parentHeight: 400, + }, +}; + +export const WithSelectedChannel: Story = { + args: { + ...Default.args, + selectedMeasure: 'Valve 3', + }, +}; + +export const CpMetric: Story = { + args: { + ...Default.args, + capabilityMetric: 'cp', + }, +}; + +export const BothMetrics: Story = { + args: { + ...Default.args, + capabilityMetric: 'both', + }, +}; + +export const CustomTarget: Story = { + args: { + ...Default.args, + cpkTarget: 1.67, + }, +}; diff --git a/.storybook/stories/charts/PerformancePareto.stories.tsx b/.storybook/stories/charts/PerformancePareto.stories.tsx new file mode 100644 index 000000000..aa09b9b76 --- /dev/null +++ b/.storybook/stories/charts/PerformancePareto.stories.tsx @@ -0,0 +1,65 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { PerformanceParetoBase } from '../../../packages/charts/src/index'; +import type { ChannelResult } from '../../../packages/charts/src/index'; + +function makeChannel(id: string, cpk: number): ChannelResult { + const values = Array.from({ length: 30 }, () => 10 + (Math.random() - 0.5) * 2); + return { + id, + label: id, + n: 30, + mean: 10, + stdDev: 0.3, + cp: cpk + 0.1, + cpk, + min: 9, + max: 11, + health: + cpk >= 1.67 ? 'excellent' : cpk >= 1.33 ? 'capable' : cpk >= 1.0 ? 'warning' : 'critical', + outOfSpecPercentage: 0, + values, + }; +} + +const mockChannels: ChannelResult[] = [ + makeChannel('Nozzle 1', 0.78), + makeChannel('Nozzle 2', 1.05), + makeChannel('Nozzle 3', 1.22), + makeChannel('Nozzle 4', 1.45), + makeChannel('Nozzle 5', 1.67), + makeChannel('Nozzle 6', 1.89), + makeChannel('Nozzle 7', 2.1), + makeChannel('Nozzle 8', 0.55), +]; + +const meta = { + title: 'Charts/PerformancePareto', + component: PerformanceParetoBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + channels: mockChannels, + parentWidth: 800, + parentHeight: 450, + }, +}; + +export const WithSelectedChannel: Story = { + args: { + ...Default.args, + selectedMeasure: 'Nozzle 8', + }, +}; + +export const CustomThresholds: Story = { + args: { + ...Default.args, + cpkThresholds: { critical: 1.0, warning: 1.33, capable: 1.67 }, + }, +}; diff --git a/.storybook/stories/charts/ProbabilityPlot.stories.tsx b/.storybook/stories/charts/ProbabilityPlot.stories.tsx new file mode 100644 index 000000000..8ffcbf034 --- /dev/null +++ b/.storybook/stories/charts/ProbabilityPlot.stories.tsx @@ -0,0 +1,46 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ProbabilityPlotBase } from '../../../packages/charts/src/index'; + +const mockValues = Array.from({ length: 50 }, () => 10.0 + (Math.random() - 0.5) * 2).sort( + (a, b) => a - b +); + +const meta = { + title: 'Charts/ProbabilityPlot', + component: ProbabilityPlotBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + data: mockValues, + mean: 10.0, + stdDev: 0.58, + parentWidth: 600, + parentHeight: 500, + }, +}; + +export const SkewedData: Story = { + args: { + data: Array.from({ length: 50 }, () => Math.exp(Math.random() * 0.5 + 2)).sort((a, b) => a - b), + mean: 8.2, + stdDev: 2.1, + parentWidth: 600, + parentHeight: 500, + }, +}; + +export const SmallSample: Story = { + args: { + data: [9.1, 9.5, 9.8, 10.0, 10.2, 10.5, 10.9], + mean: 10.0, + stdDev: 0.58, + parentWidth: 600, + parentHeight: 500, + }, +}; diff --git a/.storybook/stories/charts/ScatterPlot.stories.tsx b/.storybook/stories/charts/ScatterPlot.stories.tsx new file mode 100644 index 000000000..d78f6fd31 --- /dev/null +++ b/.storybook/stories/charts/ScatterPlot.stories.tsx @@ -0,0 +1,56 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +/** + * ScatterPlot is not a standalone export from @variscout/charts. + * Scatter-like visualization is handled via PerformanceIChart (Cpk scatter) + * or regression plots. This story serves as a placeholder for future + * standalone scatter plot extraction. + */ + +// Placeholder until ScatterPlot is extracted as a standalone component +const ScatterPlotPlaceholder = ({ + width = 600, + height = 400, +}: { + width?: number; + height?: number; +}) => ( +
+
+

ScatterPlot

+

+ Scatter visualization is provided by PerformanceIChart (Cpk scatter). +

+

See Charts/PerformanceIChart for the live component.

+
+
+); + +const meta = { + title: 'Charts/ScatterPlot', + component: ScatterPlotPlaceholder, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Placeholder: Story = { + args: { + width: 600, + height: 400, + }, +}; diff --git a/.storybook/stories/ui/analysis/AnovaResults.stories.tsx b/.storybook/stories/ui/analysis/AnovaResults.stories.tsx new file mode 100644 index 000000000..8b6bdda99 --- /dev/null +++ b/.storybook/stories/ui/analysis/AnovaResults.stories.tsx @@ -0,0 +1,65 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { AnovaResults, anovaDefaultColorScheme } from '../../../../packages/ui/src/index'; +import type { AnovaResult } from '../../../../packages/core/src/types'; + +const significantResult: AnovaResult = { + groups: [ + { name: 'Line A', n: 30, mean: 10.1, stdDev: 0.3 }, + { name: 'Line B', n: 30, mean: 10.5, stdDev: 0.4 }, + { name: 'Line C', n: 30, mean: 9.8, stdDev: 0.2 }, + ], + ssb: 7.35, + ssw: 8.12, + dfBetween: 2, + dfWithin: 87, + msb: 3.675, + msw: 0.093, + fStatistic: 39.5, + pValue: 0.0001, + isSignificant: true, + etaSquared: 0.475, + insight: 'Machine explains 47.5% of variation. Line B runs significantly higher than Line C.', +}; + +const nonSignificantResult: AnovaResult = { + groups: [ + { name: 'Shift 1', n: 25, mean: 10.02, stdDev: 0.31 }, + { name: 'Shift 2', n: 25, mean: 10.05, stdDev: 0.29 }, + ], + ssb: 0.01, + ssw: 4.52, + dfBetween: 1, + dfWithin: 48, + msb: 0.01, + msw: 0.094, + fStatistic: 0.11, + pValue: 0.74, + isSignificant: false, + etaSquared: 0.002, + insight: 'No significant difference between shifts. Shift explains only 0.2% of variation.', +}; + +const meta = { + title: 'UI/Analysis/AnovaResults', + component: AnovaResults, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Significant: Story = { + args: { + result: significantResult, + factorName: 'Machine', + colorScheme: anovaDefaultColorScheme, + }, +}; + +export const NotSignificant: Story = { + args: { + result: nonSignificantResult, + factorName: 'Shift', + colorScheme: anovaDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/analysis/AxisEditor.stories.tsx b/.storybook/stories/ui/analysis/AxisEditor.stories.tsx new file mode 100644 index 000000000..0518f390a --- /dev/null +++ b/.storybook/stories/ui/analysis/AxisEditor.stories.tsx @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { AxisEditor, axisEditorDefaultColorScheme } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Analysis/AxisEditor', + component: AxisEditor, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + axis: 'y', + currentLabel: 'Weight (g)', + onLabelChange: () => {}, + onClose: () => {}, + colorScheme: axisEditorDefaultColorScheme, + }, +}; + +export const XAxis: Story = { + args: { + isOpen: true, + axis: 'x', + currentLabel: 'Machine', + onLabelChange: () => {}, + onClose: () => {}, + colorScheme: axisEditorDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/analysis/BoxplotDisplayToggle.stories.tsx b/.storybook/stories/ui/analysis/BoxplotDisplayToggle.stories.tsx new file mode 100644 index 000000000..adfcaf689 --- /dev/null +++ b/.storybook/stories/ui/analysis/BoxplotDisplayToggle.stories.tsx @@ -0,0 +1,47 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { + BoxplotDisplayToggle, + boxplotDisplayToggleDefaultColorScheme, +} from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Analysis/BoxplotDisplayToggle', + component: BoxplotDisplayToggle, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + showViolin: false, + showContributions: false, + onViolinChange: () => {}, + onContributionsChange: () => {}, + colorScheme: boxplotDisplayToggleDefaultColorScheme, + }, +}; + +export const ViolinEnabled: Story = { + args: { + showViolin: true, + showContributions: false, + onViolinChange: () => {}, + onContributionsChange: () => {}, + colorScheme: boxplotDisplayToggleDefaultColorScheme, + }, +}; + +export const AllEnabled: Story = { + args: { + showViolin: true, + showContributions: true, + onViolinChange: () => {}, + onContributionsChange: () => {}, + sortBy: 'mean', + sortDirection: 'desc', + onSortChange: () => {}, + colorScheme: boxplotDisplayToggleDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/analysis/FactorSelector.stories.tsx b/.storybook/stories/ui/analysis/FactorSelector.stories.tsx new file mode 100644 index 000000000..1960e94ea --- /dev/null +++ b/.storybook/stories/ui/analysis/FactorSelector.stories.tsx @@ -0,0 +1,41 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { + FactorSelector, + factorSelectorDefaultColorScheme, +} from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Analysis/FactorSelector', + component: FactorSelector, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + factors: ['Machine', 'Operator', 'Shift'], + selectedFactor: 'Machine', + onFactorChange: () => {}, + colorScheme: factorSelectorDefaultColorScheme, + }, +}; + +export const SingleFactor: Story = { + args: { + factors: ['Machine'], + selectedFactor: 'Machine', + onFactorChange: () => {}, + colorScheme: factorSelectorDefaultColorScheme, + }, +}; + +export const NoSelection: Story = { + args: { + factors: ['Machine', 'Operator'], + selectedFactor: '', + onFactorChange: () => {}, + colorScheme: factorSelectorDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/analysis/InvestigationPrompt.stories.tsx b/.storybook/stories/ui/analysis/InvestigationPrompt.stories.tsx new file mode 100644 index 000000000..782955102 --- /dev/null +++ b/.storybook/stories/ui/analysis/InvestigationPrompt.stories.tsx @@ -0,0 +1,41 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { + InvestigationPrompt, + investigationPromptDefaultColorScheme, +} from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Analysis/InvestigationPrompt', + component: InvestigationPrompt, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + findingCount: 3, + analyzedCount: 1, + onOpenFindings: () => {}, + colorScheme: investigationPromptDefaultColorScheme, + }, +}; + +export const AllAnalyzed: Story = { + args: { + findingCount: 5, + analyzedCount: 5, + onOpenFindings: () => {}, + colorScheme: investigationPromptDefaultColorScheme, + }, +}; + +export const NoFindings: Story = { + args: { + findingCount: 0, + analyzedCount: 0, + onOpenFindings: () => {}, + colorScheme: investigationPromptDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/analysis/StatsPanelBase.stories.tsx b/.storybook/stories/ui/analysis/StatsPanelBase.stories.tsx new file mode 100644 index 000000000..4c611f298 --- /dev/null +++ b/.storybook/stories/ui/analysis/StatsPanelBase.stories.tsx @@ -0,0 +1,54 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { StatsPanelBase, statsPanelDefaultColorScheme } from '../../../../packages/ui/src/index'; +import type { StatsResult } from '../../../../packages/core/src/types'; + +const mockStats: StatsResult = { + mean: 10.08, + median: 10.05, + stdDev: 0.27, + sigmaWithin: 0.24, + mrBar: 0.27, + ucl: 10.8, + lcl: 9.36, + cp: 1.39, + cpk: 1.28, + outOfSpecPercentage: 0.5, +}; + +const meta = { + title: 'UI/Analysis/StatsPanelBase', + component: StatsPanelBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + stats: mockStats, + specs: { usl: 11.0, lsl: 9.0, target: 10.0 }, + sampleCount: 150, + colorScheme: statsPanelDefaultColorScheme, + }, +}; + +export const NoSpecs: Story = { + args: { + stats: { ...mockStats, cp: undefined, cpk: undefined, outOfSpecPercentage: 0 }, + specs: {}, + sampleCount: 150, + colorScheme: statsPanelDefaultColorScheme, + }, +}; + +export const WithEditSpecs: Story = { + args: { + stats: mockStats, + specs: { usl: 11.0, lsl: 9.0, target: 10.0 }, + sampleCount: 150, + colorScheme: statsPanelDefaultColorScheme, + onEditSpecs: () => {}, + }, +}; diff --git a/.storybook/stories/ui/analysis/VariationBar.stories.tsx b/.storybook/stories/ui/analysis/VariationBar.stories.tsx new file mode 100644 index 000000000..6f3a7ebb0 --- /dev/null +++ b/.storybook/stories/ui/analysis/VariationBar.stories.tsx @@ -0,0 +1,39 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { VariationBar, variationBarDefaultColorScheme } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Analysis/VariationBar', + component: VariationBar, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + scopeFraction: 0.65, + colorScheme: variationBarDefaultColorScheme, + }, +}; + +export const FullScope: Story = { + args: { + scopeFraction: 1.0, + colorScheme: variationBarDefaultColorScheme, + }, +}; + +export const MinimalScope: Story = { + args: { + scopeFraction: 0.08, + colorScheme: variationBarDefaultColorScheme, + }, +}; + +export const NoScope: Story = { + args: { + scopeFraction: 0, + colorScheme: variationBarDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/analysis/YAxisPopover.stories.tsx b/.storybook/stories/ui/analysis/YAxisPopover.stories.tsx new file mode 100644 index 000000000..b42df32bf --- /dev/null +++ b/.storybook/stories/ui/analysis/YAxisPopover.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { YAxisPopover, yAxisPopoverDefaultColorScheme } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Analysis/YAxisPopover', + component: YAxisPopover, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + currentMin: 8.0, + currentMax: 12.0, + onApply: () => {}, + onReset: () => {}, + onClose: () => {}, + colorScheme: yAxisPopoverDefaultColorScheme, + }, +}; + +export const Closed: Story = { + args: { + isOpen: false, + currentMin: 8.0, + currentMax: 12.0, + onApply: () => {}, + onReset: () => {}, + onClose: () => {}, + colorScheme: yAxisPopoverDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/charts/AnnotationContextMenu.stories.tsx b/.storybook/stories/ui/charts/AnnotationContextMenu.stories.tsx new file mode 100644 index 000000000..4753bcb63 --- /dev/null +++ b/.storybook/stories/ui/charts/AnnotationContextMenu.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { AnnotationContextMenu } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Charts/AnnotationContextMenu', + component: AnnotationContextMenu, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + x: 200, + y: 150, + category: 'Line B', + onHighlight: () => {}, + onAddObservation: () => {}, + onClose: () => {}, + }, +}; + +export const Closed: Story = { + args: { + isOpen: false, + x: 0, + y: 0, + category: '', + onHighlight: () => {}, + onAddObservation: () => {}, + onClose: () => {}, + }, +}; diff --git a/.storybook/stories/ui/charts/BoxplotWrapperBase.stories.tsx b/.storybook/stories/ui/charts/BoxplotWrapperBase.stories.tsx new file mode 100644 index 000000000..4336132c6 --- /dev/null +++ b/.storybook/stories/ui/charts/BoxplotWrapperBase.stories.tsx @@ -0,0 +1,48 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { BoxplotWrapperBase } from '../../../../packages/ui/src/index'; +import type { BoxplotGroupData } from '../../../../packages/charts/src/index'; + +function makeGroup(key: string, center: number, spread: number): BoxplotGroupData { + const values: number[] = []; + for (let i = 0; i < 25; i++) { + values.push(center + (Math.random() - 0.5) * spread * 2); + } + values.sort((a, b) => a - b); + const q1 = values[6]; + const q3 = values[18]; + const iqr = q3 - q1; + return { + key, + values, + min: Math.max(values[0], q1 - 1.5 * iqr), + max: Math.min(values[24], q3 + 1.5 * iqr), + q1, + median: values[12], + mean: values.reduce((a, b) => a + b, 0) / values.length, + q3, + outliers: values.filter(v => v < q1 - 1.5 * iqr || v > q3 + 1.5 * iqr), + stdDev: spread * 0.6, + }; +} + +const meta = { + title: 'UI/Charts/BoxplotWrapperBase', + component: BoxplotWrapperBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + data: [ + makeGroup('Line A', 10.0, 0.5), + makeGroup('Line B', 10.3, 0.8), + makeGroup('Line C', 9.7, 0.4), + ], + specs: { usl: 11.0, lsl: 9.0, target: 10.0 }, + factorName: 'Production Line', + }, +}; diff --git a/.storybook/stories/ui/charts/ChartAnnotationLayer.stories.tsx b/.storybook/stories/ui/charts/ChartAnnotationLayer.stories.tsx new file mode 100644 index 000000000..0e40efbb3 --- /dev/null +++ b/.storybook/stories/ui/charts/ChartAnnotationLayer.stories.tsx @@ -0,0 +1,48 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ChartAnnotationLayer } from '../../../../packages/ui/src/index'; +import type { Finding } from '../../../../packages/core/src/findings'; + +const mockFindings: Finding[] = [ + { + id: '1', + text: 'Line B shows elevated mean compared to others', + createdAt: Date.now() - 3600000, + context: { + activeFilters: {}, + cumulativeScope: null, + stats: { mean: 10.5, cpk: 0.92, samples: 30 }, + }, + status: 'observed', + comments: [], + statusChangedAt: Date.now() - 3600000, + source: { chart: 'boxplot', category: 'Line B' }, + }, +]; + +const meta = { + title: 'UI/Charts/ChartAnnotationLayer', + component: ChartAnnotationLayer, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + findings: mockFindings, + chartType: 'boxplot', + width: 600, + height: 400, + }, +}; + +export const Empty: Story = { + args: { + findings: [], + chartType: 'ichart', + width: 600, + height: 400, + }, +}; diff --git a/.storybook/stories/ui/charts/ChartCard.stories.tsx b/.storybook/stories/ui/charts/ChartCard.stories.tsx new file mode 100644 index 000000000..50a001a0e --- /dev/null +++ b/.storybook/stories/ui/charts/ChartCard.stories.tsx @@ -0,0 +1,53 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ChartCard } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Charts/ChartCard', + component: ChartCard, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + id: 'ichart', + title: 'I-Chart', + children: ( +
+ Chart content area +
+ ), + }, +}; + +export const WithActions: Story = { + args: { + id: 'boxplot', + title: 'Boxplot', + onFocus: () => {}, + children: ( +
+ Chart content area +
+ ), + }, +}; diff --git a/.storybook/stories/ui/charts/ChartDownloadMenu.stories.tsx b/.storybook/stories/ui/charts/ChartDownloadMenu.stories.tsx new file mode 100644 index 000000000..c742f7d37 --- /dev/null +++ b/.storybook/stories/ui/charts/ChartDownloadMenu.stories.tsx @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { + ChartDownloadMenu, + chartDownloadMenuDefaultColorScheme, +} from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Charts/ChartDownloadMenu', + component: ChartDownloadMenu, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + onDownloadPNG: () => {}, + onDownloadSVG: () => {}, + colorScheme: chartDownloadMenuDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/charts/EditableChartTitle.stories.tsx b/.storybook/stories/ui/charts/EditableChartTitle.stories.tsx new file mode 100644 index 000000000..7d20d873c --- /dev/null +++ b/.storybook/stories/ui/charts/EditableChartTitle.stories.tsx @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { EditableChartTitle } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Charts/EditableChartTitle', + component: EditableChartTitle, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + title: 'Fill Weight Analysis', + onTitleChange: () => {}, + }, +}; + +export const LongTitle: Story = { + args: { + title: 'Monthly Production Line B Fill Weight Distribution Analysis', + onTitleChange: () => {}, + }, +}; + +export const Empty: Story = { + args: { + title: '', + onTitleChange: () => {}, + placeholder: 'Enter chart title...', + }, +}; diff --git a/.storybook/stories/ui/charts/FocusedChartViewBase.stories.tsx b/.storybook/stories/ui/charts/FocusedChartViewBase.stories.tsx new file mode 100644 index 000000000..e28590b2c --- /dev/null +++ b/.storybook/stories/ui/charts/FocusedChartViewBase.stories.tsx @@ -0,0 +1,38 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FocusedChartViewBase } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Charts/FocusedChartViewBase', + component: FocusedChartViewBase, + tags: ['autodocs'], + parameters: { layout: 'fullscreen' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + activeChart: 'ichart', + navigation: { + onPrevious: () => {}, + onNext: () => {}, + hasPrevious: true, + hasNext: true, + }, + chartExport: { + onCopy: () => {}, + onDownloadPNG: () => {}, + onDownloadSVG: () => {}, + }, + ichartSection: { + chart:
, + }, + boxplotSection: { + chart:
, + }, + paretoSection: { + chart:
, + }, + }, +}; diff --git a/.storybook/stories/ui/charts/IChartWrapperBase.stories.tsx b/.storybook/stories/ui/charts/IChartWrapperBase.stories.tsx new file mode 100644 index 000000000..6b16ab7c7 --- /dev/null +++ b/.storybook/stories/ui/charts/IChartWrapperBase.stories.tsx @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { IChartWrapperBase } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Charts/IChartWrapperBase', + component: IChartWrapperBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + data: Array.from({ length: 25 }, (_, i) => ({ + x: i, + y: 10 + (Math.random() - 0.5) * 1.5, + })), + stats: { + mean: 10.0, + median: 10.0, + stdDev: 0.28, + sigmaWithin: 0.25, + mrBar: 0.28, + ucl: 10.75, + lcl: 9.25, + cp: 1.33, + cpk: 1.25, + outOfSpecPercentage: 0, + }, + specs: { usl: 11.0, lsl: 9.0, target: 10.0 }, + }, +}; diff --git a/.storybook/stories/ui/charts/ParetoChartWrapperBase.stories.tsx b/.storybook/stories/ui/charts/ParetoChartWrapperBase.stories.tsx new file mode 100644 index 000000000..2ff1bce09 --- /dev/null +++ b/.storybook/stories/ui/charts/ParetoChartWrapperBase.stories.tsx @@ -0,0 +1,39 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ParetoChartWrapperBase } from '../../../../packages/ui/src/index'; +import type { ParetoDataPoint } from '../../../../packages/charts/src/index'; + +const rawCounts = [ + { key: 'Seal defect', value: 42 }, + { key: 'Weight error', value: 28 }, + { key: 'Print smear', value: 15 }, + { key: 'Tear', value: 10 }, +]; +const total = rawCounts.reduce((s, d) => s + d.value, 0); +let cumulative = 0; +const mockData: ParetoDataPoint[] = rawCounts.map(d => { + cumulative += d.value; + return { + key: d.key, + value: d.value, + cumulative, + cumulativePercentage: (cumulative / total) * 100, + }; +}); + +const meta = { + title: 'UI/Charts/ParetoChartWrapperBase', + component: ParetoChartWrapperBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + data: mockData, + totalCount: total, + factorName: 'Defect Type', + }, +}; diff --git a/.storybook/stories/ui/dashboard/DashboardChartCard.stories.tsx b/.storybook/stories/ui/dashboard/DashboardChartCard.stories.tsx new file mode 100644 index 000000000..11fffd4aa --- /dev/null +++ b/.storybook/stories/ui/dashboard/DashboardChartCard.stories.tsx @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { DashboardChartCard } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Dashboard/DashboardChartCard', + component: DashboardChartCard, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + title: 'I-Chart', + chartId: 'ichart', + onFocus: () => {}, + children: ( +
+ Chart content +
+ ), + }, +}; diff --git a/.storybook/stories/ui/dashboard/DashboardGrid.stories.tsx b/.storybook/stories/ui/dashboard/DashboardGrid.stories.tsx new file mode 100644 index 000000000..851851e20 --- /dev/null +++ b/.storybook/stories/ui/dashboard/DashboardGrid.stories.tsx @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { DashboardGrid } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Dashboard/DashboardGrid', + component: DashboardGrid, + tags: ['autodocs'], + parameters: { layout: 'fullscreen' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + children: ( + <> +
+ I-Chart slot +
+
+ Boxplot slot +
+
+ Pareto slot +
+
+ Stats slot +
+ + ), + }, +}; diff --git a/.storybook/stories/ui/dashboard/FocusedChartCard.stories.tsx b/.storybook/stories/ui/dashboard/FocusedChartCard.stories.tsx new file mode 100644 index 000000000..dfaee7ab1 --- /dev/null +++ b/.storybook/stories/ui/dashboard/FocusedChartCard.stories.tsx @@ -0,0 +1,32 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FocusedChartCard } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Dashboard/FocusedChartCard', + component: FocusedChartCard, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + title: 'Boxplot - Machine', + onClose: () => {}, + children: ( +
+ Focused chart content +
+ ), + }, +}; diff --git a/.storybook/stories/ui/dashboard/FocusedViewOverlay.stories.tsx b/.storybook/stories/ui/dashboard/FocusedViewOverlay.stories.tsx new file mode 100644 index 000000000..ca09f2a67 --- /dev/null +++ b/.storybook/stories/ui/dashboard/FocusedViewOverlay.stories.tsx @@ -0,0 +1,41 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FocusedViewOverlay } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Dashboard/FocusedViewOverlay', + component: FocusedViewOverlay, + tags: ['autodocs'], + parameters: { layout: 'fullscreen' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + onClose: () => {}, + children: ( +
+ Focused chart view content +
+ ), + }, +}; + +export const Closed: Story = { + args: { + isOpen: false, + onClose: () => {}, + children:
Hidden content
, + }, +}; diff --git a/.storybook/stories/ui/dashboard/PerformanceSetupPanelBase.stories.tsx b/.storybook/stories/ui/dashboard/PerformanceSetupPanelBase.stories.tsx new file mode 100644 index 000000000..63e845658 --- /dev/null +++ b/.storybook/stories/ui/dashboard/PerformanceSetupPanelBase.stories.tsx @@ -0,0 +1,50 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { + PerformanceSetupPanelBase, + performanceSetupPanelDefaultColorScheme, +} from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Dashboard/PerformanceSetupPanelBase', + component: PerformanceSetupPanelBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + channels: [ + { + id: 'Valve 1', + label: 'Valve 1', + n: 30, + preview: { min: 9.2, max: 10.8, mean: 10.0 }, + matchedPattern: true, + }, + { + id: 'Valve 2', + label: 'Valve 2', + n: 30, + preview: { min: 9.5, max: 10.5, mean: 10.0 }, + matchedPattern: true, + }, + { + id: 'Valve 3', + label: 'Valve 3', + n: 30, + preview: { min: 9.0, max: 11.0, mean: 10.1 }, + matchedPattern: true, + }, + ], + selectedChannels: ['Valve 1', 'Valve 2', 'Valve 3'], + specs: { usl: 11.0, lsl: 9.0, target: 10.0 }, + onChannelToggle: () => {}, + onSpecsChange: () => {}, + onConfirm: () => {}, + colorScheme: performanceSetupPanelDefaultColorScheme, + tier: { maxChannels: 5, isPaidTier: false }, + }, +}; diff --git a/.storybook/stories/ui/dashboard/SettingsPanelBase.stories.tsx b/.storybook/stories/ui/dashboard/SettingsPanelBase.stories.tsx new file mode 100644 index 000000000..19cd295c1 --- /dev/null +++ b/.storybook/stories/ui/dashboard/SettingsPanelBase.stories.tsx @@ -0,0 +1,42 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { SettingsPanelBase } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Dashboard/SettingsPanelBase', + component: SettingsPanelBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + onClose: () => {}, + settings: { + yAxisLocked: false, + showSpecs: true, + cpkTarget: 1.33, + showFilterContext: true, + textSize: 'medium', + }, + onSettingsChange: () => {}, + }, +}; + +export const Closed: Story = { + args: { + isOpen: false, + onClose: () => {}, + settings: { + yAxisLocked: false, + showSpecs: true, + cpkTarget: 1.33, + showFilterContext: true, + textSize: 'medium', + }, + onSettingsChange: () => {}, + }, +}; diff --git a/.storybook/stories/ui/data/DataQualityBanner.stories.tsx b/.storybook/stories/ui/data/DataQualityBanner.stories.tsx new file mode 100644 index 000000000..501444a70 --- /dev/null +++ b/.storybook/stories/ui/data/DataQualityBanner.stories.tsx @@ -0,0 +1,43 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { DataQualityBanner } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Data/DataQualityBanner', + component: DataQualityBanner, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + totalRows: 150, + validRows: 142, + invalidRows: 8, + warnings: ['8 rows had non-numeric values in the Weight column'], + }, +}; + +export const AllValid: Story = { + args: { + totalRows: 100, + validRows: 100, + invalidRows: 0, + warnings: [], + }, +}; + +export const MultipleWarnings: Story = { + args: { + totalRows: 200, + validRows: 175, + invalidRows: 25, + warnings: [ + '15 rows had non-numeric values in the Weight column', + '10 rows had empty Machine values', + '3 duplicate timestamps detected', + ], + }, +}; diff --git a/.storybook/stories/ui/data/DataTableBase.stories.tsx b/.storybook/stories/ui/data/DataTableBase.stories.tsx new file mode 100644 index 000000000..4b4317880 --- /dev/null +++ b/.storybook/stories/ui/data/DataTableBase.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { DataTableBase } from '../../../../packages/ui/src/index'; + +const mockRows = Array.from({ length: 20 }, (_, i) => ({ + Date: `2026-03-${String(i + 1).padStart(2, '0')}`, + Weight: (10 + (Math.random() - 0.5) * 2).toFixed(2), + Machine: ['A', 'B', 'C'][i % 3], + Operator: ['Alice', 'Bob'][i % 2], +})); + +const meta = { + title: 'UI/Data/DataTableBase', + component: DataTableBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + data: mockRows, + columns: ['Date', 'Weight', 'Machine', 'Operator'], + measureColumn: 'Weight', + }, +}; + +export const EmptyData: Story = { + args: { + data: [], + columns: ['Date', 'Weight', 'Machine'], + measureColumn: 'Weight', + }, +}; diff --git a/.storybook/stories/ui/data/MobileCategorySheet.stories.tsx b/.storybook/stories/ui/data/MobileCategorySheet.stories.tsx new file mode 100644 index 000000000..d1e00be69 --- /dev/null +++ b/.storybook/stories/ui/data/MobileCategorySheet.stories.tsx @@ -0,0 +1,36 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { MobileCategorySheet } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Data/MobileCategorySheet', + component: MobileCategorySheet, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + data: { + category: 'Machine A', + stats: { n: 45, mean: 10.2, median: 10.1, stdDev: 0.35 }, + }, + onClose: () => {}, + onDrillDown: () => {}, + onHighlight: () => {}, + onPinAsFinding: () => {}, + }, +}; + +export const Closed: Story = { + args: { + isOpen: false, + data: null, + onClose: () => {}, + onDrillDown: () => {}, + onHighlight: () => {}, + onPinAsFinding: () => {}, + }, +}; diff --git a/.storybook/stories/ui/data/PerformanceDetectedModal.stories.tsx b/.storybook/stories/ui/data/PerformanceDetectedModal.stories.tsx new file mode 100644 index 000000000..a21b7a104 --- /dev/null +++ b/.storybook/stories/ui/data/PerformanceDetectedModal.stories.tsx @@ -0,0 +1,31 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { PerformanceDetectedModal } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Data/PerformanceDetectedModal', + component: PerformanceDetectedModal, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + channelCount: 12, + sampleColumns: ['Valve 1', 'Valve 2', 'Valve 3', 'Valve 4'], + onAccept: () => {}, + onDecline: () => {}, + }, +}; + +export const FewChannels: Story = { + args: { + isOpen: true, + channelCount: 3, + sampleColumns: ['Head A', 'Head B', 'Head C'], + onAccept: () => {}, + onDecline: () => {}, + }, +}; diff --git a/.storybook/stories/ui/findings/FindingBoardView.stories.tsx b/.storybook/stories/ui/findings/FindingBoardView.stories.tsx new file mode 100644 index 000000000..4533d5af9 --- /dev/null +++ b/.storybook/stories/ui/findings/FindingBoardView.stories.tsx @@ -0,0 +1,73 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FindingBoardView } from '../../../../packages/ui/src/index'; +import type { Finding } from '../../../../packages/core/src/findings'; + +const now = Date.now(); + +const mockFindings: Finding[] = [ + { + id: '1', + text: 'Line B runs above target', + createdAt: now - 7200000, + context: { activeFilters: {}, cumulativeScope: null }, + status: 'observed', + comments: [], + statusChangedAt: now - 7200000, + }, + { + id: '2', + text: 'Night shift variability is higher', + createdAt: now - 5000000, + context: { activeFilters: { Shift: ['Night'] }, cumulativeScope: 0.35 }, + status: 'observed', + comments: [], + statusChangedAt: now - 5000000, + }, + { + id: '3', + text: 'Investigating temperature correlation', + createdAt: now - 3600000, + context: { activeFilters: {}, cumulativeScope: null }, + status: 'investigating', + comments: [{ id: 'c1', text: 'Running regression', createdAt: now - 1800000 }], + statusChangedAt: now - 3000000, + }, + { + id: '4', + text: 'Confirmed: temperature is the key driver', + createdAt: now - 1200000, + context: { activeFilters: {}, cumulativeScope: null }, + status: 'analyzed', + tag: 'key-driver', + comments: [], + statusChangedAt: now - 600000, + }, +]; + +const meta = { + title: 'UI/Findings/FindingBoardView', + component: FindingBoardView, + tags: ['autodocs'], + parameters: { layout: 'fullscreen' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + findings: mockFindings, + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + }, +}; + +export const Empty: Story = { + args: { + findings: [], + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + }, +}; diff --git a/.storybook/stories/ui/findings/FindingCard.stories.tsx b/.storybook/stories/ui/findings/FindingCard.stories.tsx new file mode 100644 index 000000000..144749ab1 --- /dev/null +++ b/.storybook/stories/ui/findings/FindingCard.stories.tsx @@ -0,0 +1,77 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FindingCard } from '../../../../packages/ui/src/index'; +import type { Finding } from '../../../../packages/core/src/findings'; + +const now = Date.now(); + +const observedFinding: Finding = { + id: '1', + text: 'Line B consistently runs 0.3g above target', + createdAt: now - 7200000, + context: { + activeFilters: { Machine: ['Line B'] }, + cumulativeScope: 0.45, + stats: { mean: 10.3, cpk: 0.92, samples: 30 }, + }, + status: 'observed', + comments: [], + statusChangedAt: now - 7200000, + source: { chart: 'boxplot', category: 'Line B' }, +}; + +const investigatingFinding: Finding = { + id: '2', + text: 'Night shift variability exceeds day shift by 40%', + createdAt: now - 3600000, + context: { activeFilters: { Shift: ['Night'] }, cumulativeScope: 0.35 }, + status: 'investigating', + comments: [{ id: 'c1', text: 'Reviewing training records', createdAt: now - 1800000 }], + statusChangedAt: now - 3000000, +}; + +const analyzedFinding: Finding = { + id: '3', + text: 'Temperature is the primary driver of variation', + createdAt: now - 600000, + context: { activeFilters: {}, cumulativeScope: null }, + status: 'analyzed', + tag: 'key-driver', + comments: [], + statusChangedAt: now - 300000, +}; + +const meta = { + title: 'UI/Findings/FindingCard', + component: FindingCard, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Observed: Story = { + args: { + finding: observedFinding, + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + }, +}; + +export const Investigating: Story = { + args: { + finding: investigatingFinding, + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + }, +}; + +export const Analyzed: Story = { + args: { + finding: analyzedFinding, + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + }, +}; diff --git a/.storybook/stories/ui/findings/FindingComments.stories.tsx b/.storybook/stories/ui/findings/FindingComments.stories.tsx new file mode 100644 index 000000000..57a40d3f4 --- /dev/null +++ b/.storybook/stories/ui/findings/FindingComments.stories.tsx @@ -0,0 +1,49 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FindingComments } from '../../../../packages/ui/src/index'; +import type { FindingComment } from '../../../../packages/core/src/findings'; + +const now = Date.now(); + +const mockComments: FindingComment[] = [ + { + id: 'c1', + text: 'Checked calibration logs - last calibration was 3 weeks ago', + createdAt: now - 7200000, + }, + { + id: 'c2', + text: 'Operator reports nozzle pressure variance during morning startup', + createdAt: now - 3600000, + }, + { id: 'c3', text: 'Maintenance scheduled for next Tuesday', createdAt: now - 1200000 }, +]; + +const meta = { + title: 'UI/Findings/FindingComments', + component: FindingComments, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + comments: mockComments, + onAddComment: () => {}, + }, +}; + +export const Empty: Story = { + args: { + comments: [], + onAddComment: () => {}, + }, +}; + +export const SingleComment: Story = { + args: { + comments: [mockComments[0]], + onAddComment: () => {}, + }, +}; diff --git a/.storybook/stories/ui/findings/FindingEditor.stories.tsx b/.storybook/stories/ui/findings/FindingEditor.stories.tsx new file mode 100644 index 000000000..9ce72e601 --- /dev/null +++ b/.storybook/stories/ui/findings/FindingEditor.stories.tsx @@ -0,0 +1,40 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FindingEditor } from '../../../../packages/ui/src/index'; +import type { Finding } from '../../../../packages/core/src/findings'; + +const now = Date.now(); + +const mockFinding: Finding = { + id: '1', + text: 'Line B consistently runs 0.3g above target', + createdAt: now - 7200000, + context: { + activeFilters: { Machine: ['Line B'] }, + cumulativeScope: 0.45, + stats: { mean: 10.3, cpk: 0.92, samples: 30 }, + }, + status: 'investigating', + comments: [ + { id: 'c1', text: 'Checked calibration logs', createdAt: now - 3600000 }, + { id: 'c2', text: 'Operator reports nozzle pressure variance', createdAt: now - 1800000 }, + ], + statusChangedAt: now - 5000000, +}; + +const meta = { + title: 'UI/Findings/FindingEditor', + component: FindingEditor, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + finding: mockFinding, + onUpdate: () => {}, + onClose: () => {}, + }, +}; diff --git a/.storybook/stories/ui/findings/FindingStatusBadge.stories.tsx b/.storybook/stories/ui/findings/FindingStatusBadge.stories.tsx new file mode 100644 index 000000000..1ce80bca7 --- /dev/null +++ b/.storybook/stories/ui/findings/FindingStatusBadge.stories.tsx @@ -0,0 +1,29 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FindingStatusBadge } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Findings/FindingStatusBadge', + component: FindingStatusBadge, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Observed: Story = { + args: { + status: 'observed', + }, +}; + +export const Investigating: Story = { + args: { + status: 'investigating', + }, +}; + +export const Analyzed: Story = { + args: { + status: 'analyzed', + }, +}; diff --git a/.storybook/stories/ui/findings/FindingsLog.stories.tsx b/.storybook/stories/ui/findings/FindingsLog.stories.tsx new file mode 100644 index 000000000..71f3b2cbb --- /dev/null +++ b/.storybook/stories/ui/findings/FindingsLog.stories.tsx @@ -0,0 +1,72 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FindingsLog } from '../../../../packages/ui/src/index'; +import type { Finding } from '../../../../packages/core/src/findings'; + +const now = Date.now(); + +const mockFindings: Finding[] = [ + { + id: '1', + text: 'Line B consistently runs 0.3g above target', + createdAt: now - 7200000, + context: { + activeFilters: {}, + cumulativeScope: null, + stats: { mean: 10.3, cpk: 0.92, samples: 30 }, + }, + status: 'observed', + comments: [], + statusChangedAt: now - 7200000, + }, + { + id: '2', + text: 'Night shift shows higher variability than day shift', + createdAt: now - 3600000, + context: { + activeFilters: { Shift: ['Night'] }, + cumulativeScope: 0.35, + stats: { mean: 10.0, cpk: 1.1, samples: 45 }, + }, + status: 'investigating', + comments: [{ id: 'c1', text: 'Checking operator training records', createdAt: now - 1800000 }], + statusChangedAt: now - 3000000, + }, + { + id: '3', + text: 'Temperature correlation confirmed with R-squared 0.78', + createdAt: now - 1200000, + context: { activeFilters: {}, cumulativeScope: null }, + status: 'analyzed', + tag: 'key-driver', + comments: [], + statusChangedAt: now - 600000, + }, +]; + +const meta = { + title: 'UI/Findings/FindingsLog', + component: FindingsLog, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + findings: mockFindings, + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + }, +}; + +export const Empty: Story = { + args: { + findings: [], + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + }, +}; diff --git a/.storybook/stories/ui/findings/FindingsPanel.stories.tsx b/.storybook/stories/ui/findings/FindingsPanel.stories.tsx new file mode 100644 index 000000000..d5ff5ba34 --- /dev/null +++ b/.storybook/stories/ui/findings/FindingsPanel.stories.tsx @@ -0,0 +1,72 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FindingsPanelBase } from '../../../../packages/ui/src/index'; +import type { Finding } from '../../../../packages/core/src/findings'; + +const now = Date.now(); + +const mockFindings: Finding[] = [ + { + id: '1', + text: 'Line B shows elevated mean', + createdAt: now - 7200000, + context: { activeFilters: {}, cumulativeScope: null }, + status: 'observed', + comments: [], + statusChangedAt: now - 7200000, + }, + { + id: '2', + text: 'Night shift variability is higher', + createdAt: now - 3600000, + context: { activeFilters: { Shift: ['Night'] }, cumulativeScope: 0.35 }, + status: 'investigating', + comments: [], + statusChangedAt: now - 3000000, + }, +]; + +const meta = { + title: 'UI/Findings/FindingsPanel', + component: FindingsPanelBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + findings: mockFindings, + onClose: () => {}, + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + onAddFinding: () => {}, + }, +}; + +export const Closed: Story = { + args: { + isOpen: false, + findings: mockFindings, + onClose: () => {}, + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + onAddFinding: () => {}, + }, +}; + +export const Empty: Story = { + args: { + isOpen: true, + findings: [], + onClose: () => {}, + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + onAddFinding: () => {}, + }, +}; diff --git a/.storybook/stories/ui/findings/FindingsWindow.stories.tsx b/.storybook/stories/ui/findings/FindingsWindow.stories.tsx new file mode 100644 index 000000000..f45d4ad8c --- /dev/null +++ b/.storybook/stories/ui/findings/FindingsWindow.stories.tsx @@ -0,0 +1,55 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { FindingsWindow } from '../../../../packages/ui/src/index'; +import type { Finding } from '../../../../packages/core/src/findings'; + +const now = Date.now(); + +const mockFindings: Finding[] = [ + { + id: '1', + text: 'Line B runs above target', + createdAt: now - 7200000, + context: { activeFilters: {}, cumulativeScope: null }, + status: 'observed', + comments: [], + statusChangedAt: now - 7200000, + }, + { + id: '2', + text: 'Temperature is the key driver', + createdAt: now - 3600000, + context: { activeFilters: {}, cumulativeScope: null }, + status: 'analyzed', + tag: 'key-driver', + comments: [], + statusChangedAt: now - 1800000, + }, +]; + +const meta = { + title: 'UI/Findings/FindingsWindow', + component: FindingsWindow, + tags: ['autodocs'], + parameters: { layout: 'fullscreen' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + findings: mockFindings, + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + }, +}; + +export const Empty: Story = { + args: { + findings: [], + onStatusChange: () => {}, + onDelete: () => {}, + onNavigateToContext: () => {}, + }, +}; diff --git a/.storybook/stories/ui/input/CharacteristicTypeSelector.stories.tsx b/.storybook/stories/ui/input/CharacteristicTypeSelector.stories.tsx new file mode 100644 index 000000000..6e6b1e8bd --- /dev/null +++ b/.storybook/stories/ui/input/CharacteristicTypeSelector.stories.tsx @@ -0,0 +1,32 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import CharacteristicTypeSelector from '../../../../packages/ui/src/components/CharacteristicTypeSelector'; + +const meta = { + title: 'UI/Input/CharacteristicTypeSelector', + component: CharacteristicTypeSelector, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Nominal: Story = { + args: { + value: 'nominal', + onChange: () => {}, + }, +}; + +export const SmallerIsBetter: Story = { + args: { + value: 'smaller', + onChange: () => {}, + }, +}; + +export const LargerIsBetter: Story = { + args: { + value: 'larger', + onChange: () => {}, + }, +}; diff --git a/.storybook/stories/ui/input/ColumnMapping.stories.tsx b/.storybook/stories/ui/input/ColumnMapping.stories.tsx new file mode 100644 index 000000000..c298c5c0a --- /dev/null +++ b/.storybook/stories/ui/input/ColumnMapping.stories.tsx @@ -0,0 +1,50 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ColumnMapping } from '../../../../packages/ui/src/index'; + +const mockColumns = ['Date', 'Weight', 'Machine', 'Operator', 'Shift']; + +const meta = { + title: 'UI/Input/ColumnMapping', + component: ColumnMapping, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + columns: mockColumns, + measureColumn: 'Weight', + factorColumns: ['Machine'], + specs: { usl: 11.0, lsl: 9.0 }, + onMeasureChange: () => {}, + onFactorChange: () => {}, + onSpecsChange: () => {}, + onConfirm: () => {}, + maxFactors: 3, + }, +}; + +export const NoSelection: Story = { + args: { + columns: mockColumns, + measureColumn: '', + factorColumns: [], + specs: {}, + onMeasureChange: () => {}, + onFactorChange: () => {}, + onSpecsChange: () => {}, + onConfirm: () => {}, + maxFactors: 3, + }, +}; + +export const AzureMode: Story = { + args: { + ...Default.args, + maxFactors: 6, + showBrief: true, + }, +}; diff --git a/.storybook/stories/ui/input/CreateFactorModal.stories.tsx b/.storybook/stories/ui/input/CreateFactorModal.stories.tsx new file mode 100644 index 000000000..646d29df9 --- /dev/null +++ b/.storybook/stories/ui/input/CreateFactorModal.stories.tsx @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { CreateFactorModal } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Input/CreateFactorModal', + component: CreateFactorModal, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + columns: ['Date', 'Weight', 'Machine', 'Operator'], + measureColumn: 'Weight', + existingFactors: ['Machine'], + onConfirm: () => {}, + onCancel: () => {}, + }, +}; + +export const MaxFactorsReached: Story = { + args: { + isOpen: true, + columns: ['Date', 'Weight', 'Machine', 'Operator', 'Shift'], + measureColumn: 'Weight', + existingFactors: ['Machine', 'Operator', 'Shift'], + onConfirm: () => {}, + onCancel: () => {}, + }, +}; diff --git a/.storybook/stories/ui/input/ManualEntryBase.stories.tsx b/.storybook/stories/ui/input/ManualEntryBase.stories.tsx new file mode 100644 index 000000000..4ccf77e5b --- /dev/null +++ b/.storybook/stories/ui/input/ManualEntryBase.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ManualEntryBase } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Input/ManualEntryBase', + component: ManualEntryBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + config: { + measureLabel: 'Weight (g)', + factors: [{ name: 'Machine', values: ['A', 'B', 'C'] }], + }, + onDataSubmit: () => {}, + }, +}; + +export const MultipleFactor: Story = { + args: { + config: { + measureLabel: 'Temperature (C)', + factors: [ + { name: 'Oven', values: ['Oven 1', 'Oven 2'] }, + { name: 'Zone', values: ['Top', 'Middle', 'Bottom'] }, + ], + }, + onDataSubmit: () => {}, + }, +}; diff --git a/.storybook/stories/ui/input/ManualEntrySetupBase.stories.tsx b/.storybook/stories/ui/input/ManualEntrySetupBase.stories.tsx new file mode 100644 index 000000000..0caf03a9e --- /dev/null +++ b/.storybook/stories/ui/input/ManualEntrySetupBase.stories.tsx @@ -0,0 +1,26 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ManualEntrySetupBase } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Input/ManualEntrySetupBase', + component: ManualEntrySetupBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + onConfigConfirm: () => {}, + maxFactors: 3, + }, +}; + +export const AzureMaxFactors: Story = { + args: { + onConfigConfirm: () => {}, + maxFactors: 6, + }, +}; diff --git a/.storybook/stories/ui/input/MeasureColumnSelector.stories.tsx b/.storybook/stories/ui/input/MeasureColumnSelector.stories.tsx new file mode 100644 index 000000000..81b3899b2 --- /dev/null +++ b/.storybook/stories/ui/input/MeasureColumnSelector.stories.tsx @@ -0,0 +1,27 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { MeasureColumnSelector } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Input/MeasureColumnSelector', + component: MeasureColumnSelector, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + columns: ['Weight', 'Height', 'Diameter', 'Temperature'], + selectedColumn: 'Weight', + onColumnSelect: () => {}, + }, +}; + +export const NoSelection: Story = { + args: { + columns: ['Weight', 'Height', 'Diameter'], + selectedColumn: '', + onColumnSelect: () => {}, + }, +}; diff --git a/.storybook/stories/ui/input/PasteScreenBase.stories.tsx b/.storybook/stories/ui/input/PasteScreenBase.stories.tsx new file mode 100644 index 000000000..184b192f6 --- /dev/null +++ b/.storybook/stories/ui/input/PasteScreenBase.stories.tsx @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import PasteScreenBase, { + pasteScreenDefaultColorScheme, +} from '../../../../packages/ui/src/components/PasteScreen'; + +const meta = { + title: 'UI/Input/PasteScreenBase', + component: PasteScreenBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + onPaste: () => {}, + onFileSelect: () => {}, + colorScheme: pasteScreenDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/input/Slider.stories.tsx b/.storybook/stories/ui/input/Slider.stories.tsx new file mode 100644 index 000000000..5c005e6d7 --- /dev/null +++ b/.storybook/stories/ui/input/Slider.stories.tsx @@ -0,0 +1,43 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Slider, sliderDefaultColorScheme } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Input/Slider', + component: Slider, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + value: 50, + min: 0, + max: 100, + onChange: () => {}, + colorScheme: sliderDefaultColorScheme, + }, +}; + +export const WithStep: Story = { + args: { + value: 25, + min: 0, + max: 100, + step: 5, + onChange: () => {}, + colorScheme: sliderDefaultColorScheme, + }, +}; + +export const SmallRange: Story = { + args: { + value: 1.33, + min: 0, + max: 3, + step: 0.01, + onChange: () => {}, + colorScheme: sliderDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/input/SpecEditor.stories.tsx b/.storybook/stories/ui/input/SpecEditor.stories.tsx new file mode 100644 index 000000000..5f36b272f --- /dev/null +++ b/.storybook/stories/ui/input/SpecEditor.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { SpecEditor, specEditorDefaultColorScheme } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Input/SpecEditor', + component: SpecEditor, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + specs: { usl: 11.0, lsl: 9.0, target: 10.0 }, + onSpecsChange: () => {}, + colorScheme: specEditorDefaultColorScheme, + }, +}; + +export const Empty: Story = { + args: { + specs: {}, + onSpecsChange: () => {}, + colorScheme: specEditorDefaultColorScheme, + }, +}; + +export const OneSided: Story = { + args: { + specs: { usl: 5.0 }, + onSpecsChange: () => {}, + colorScheme: specEditorDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/input/SpecsPopover.stories.tsx b/.storybook/stories/ui/input/SpecsPopover.stories.tsx new file mode 100644 index 000000000..67d1bda50 --- /dev/null +++ b/.storybook/stories/ui/input/SpecsPopover.stories.tsx @@ -0,0 +1,31 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { SpecsPopover, specsPopoverDefaultColorScheme } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Input/SpecsPopover', + component: SpecsPopover, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + specs: { usl: 11.0, lsl: 9.0, target: 10.0 }, + onSpecsChange: () => {}, + onClose: () => {}, + colorScheme: specsPopoverDefaultColorScheme, + }, +}; + +export const Closed: Story = { + args: { + isOpen: false, + specs: { usl: 11.0, lsl: 9.0 }, + onSpecsChange: () => {}, + onClose: () => {}, + colorScheme: specsPopoverDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/navigation/FilterBreadcrumb.stories.tsx b/.storybook/stories/ui/navigation/FilterBreadcrumb.stories.tsx new file mode 100644 index 000000000..fcb7443d6 --- /dev/null +++ b/.storybook/stories/ui/navigation/FilterBreadcrumb.stories.tsx @@ -0,0 +1,45 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { + FilterBreadcrumb, + filterBreadcrumbDefaultColorScheme, +} from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Navigation/FilterBreadcrumb', + component: FilterBreadcrumb, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + filters: [ + { factor: 'Machine', values: ['Line A'], contribution: 35 }, + { factor: 'Operator', values: ['Alice'], contribution: 12 }, + ], + onRemoveFilter: () => {}, + onFilterClick: () => {}, + colorScheme: filterBreadcrumbDefaultColorScheme, + }, +}; + +export const SingleFilter: Story = { + args: { + filters: [{ factor: 'Machine', values: ['Line B'], contribution: 45 }], + onRemoveFilter: () => {}, + onFilterClick: () => {}, + colorScheme: filterBreadcrumbDefaultColorScheme, + }, +}; + +export const NoFilters: Story = { + args: { + filters: [], + onRemoveFilter: () => {}, + onFilterClick: () => {}, + colorScheme: filterBreadcrumbDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/navigation/FilterChipDropdown.stories.tsx b/.storybook/stories/ui/navigation/FilterChipDropdown.stories.tsx new file mode 100644 index 000000000..d4a2689d2 --- /dev/null +++ b/.storybook/stories/ui/navigation/FilterChipDropdown.stories.tsx @@ -0,0 +1,44 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { + FilterChipDropdown, + filterChipDropdownDefaultColorScheme, +} from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Navigation/FilterChipDropdown', + component: FilterChipDropdown, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + factorName: 'Machine', + values: ['Line A', 'Line B', 'Line C', 'Line D'], + selectedValues: ['Line A'], + onSelectionChange: () => {}, + colorScheme: filterChipDropdownDefaultColorScheme, + }, +}; + +export const MultipleSelected: Story = { + args: { + factorName: 'Operator', + values: ['Alice', 'Bob', 'Carol'], + selectedValues: ['Alice', 'Bob'], + onSelectionChange: () => {}, + colorScheme: filterChipDropdownDefaultColorScheme, + }, +}; + +export const NoneSelected: Story = { + args: { + factorName: 'Shift', + values: ['Morning', 'Afternoon', 'Night'], + selectedValues: [], + onSelectionChange: () => {}, + colorScheme: filterChipDropdownDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/navigation/FilterContextBar.stories.tsx b/.storybook/stories/ui/navigation/FilterContextBar.stories.tsx new file mode 100644 index 000000000..a1db95294 --- /dev/null +++ b/.storybook/stories/ui/navigation/FilterContextBar.stories.tsx @@ -0,0 +1,43 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { + FilterContextBar, + filterContextBarDefaultColorScheme, +} from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Navigation/FilterContextBar', + component: FilterContextBar, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + filters: [ + { factor: 'Machine', values: ['Line A'] }, + { factor: 'Operator', values: ['Alice'] }, + ], + colorScheme: filterContextBarDefaultColorScheme, + }, +}; + +export const NoFilters: Story = { + args: { + filters: [], + colorScheme: filterContextBarDefaultColorScheme, + }, +}; + +export const ManyFilters: Story = { + args: { + filters: [ + { factor: 'Machine', values: ['Line A'] }, + { factor: 'Operator', values: ['Alice', 'Bob'] }, + { factor: 'Shift', values: ['Morning'] }, + ], + colorScheme: filterContextBarDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/navigation/SelectionPanel.stories.tsx b/.storybook/stories/ui/navigation/SelectionPanel.stories.tsx new file mode 100644 index 000000000..ea22ab7d4 --- /dev/null +++ b/.storybook/stories/ui/navigation/SelectionPanel.stories.tsx @@ -0,0 +1,32 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { SelectionPanel } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Navigation/SelectionPanel', + component: SelectionPanel, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + measureColumn: 'Weight', + factorColumns: ['Machine', 'Operator'], + specs: { usl: 11.0, lsl: 9.0, target: 10.0 }, + sampleCount: 150, + onEditMapping: () => {}, + }, +}; + +export const NoSpecs: Story = { + args: { + measureColumn: 'Temperature', + factorColumns: ['Zone'], + specs: {}, + sampleCount: 80, + onEditMapping: () => {}, + }, +}; diff --git a/.storybook/stories/ui/simulation/WhatIfPageBase.stories.tsx b/.storybook/stories/ui/simulation/WhatIfPageBase.stories.tsx new file mode 100644 index 000000000..2715b8c44 --- /dev/null +++ b/.storybook/stories/ui/simulation/WhatIfPageBase.stories.tsx @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { WhatIfPageBase, whatIfPageDefaultColorScheme } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Simulation/WhatIfPageBase', + component: WhatIfPageBase, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + factors: [{ name: 'Machine', currentValue: 'Line A', levels: ['Line A', 'Line B', 'Line C'] }], + baselineStats: { mean: 10.0, stdDev: 0.3, cpk: 1.28 }, + onSimulate: () => {}, + onClose: () => {}, + colorScheme: whatIfPageDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/simulation/WhatIfSimulator.stories.tsx b/.storybook/stories/ui/simulation/WhatIfSimulator.stories.tsx new file mode 100644 index 000000000..dfd3833aa --- /dev/null +++ b/.storybook/stories/ui/simulation/WhatIfSimulator.stories.tsx @@ -0,0 +1,27 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { + WhatIfSimulator, + whatIfSimulatorDefaultColorScheme, +} from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Simulation/WhatIfSimulator', + component: WhatIfSimulator, + tags: ['autodocs'], + parameters: { layout: 'padded' }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + factors: [ + { name: 'Machine', currentValue: 'Line B', levels: ['Line A', 'Line B', 'Line C'] }, + { name: 'Temperature', currentValue: 185, min: 170, max: 200 }, + ], + baselineStats: { mean: 10.3, stdDev: 0.4, cpk: 0.92 }, + onSimulate: () => {}, + colorScheme: whatIfSimulatorDefaultColorScheme, + }, +}; diff --git a/.storybook/stories/ui/utilities/ErrorBoundary.stories.tsx b/.storybook/stories/ui/utilities/ErrorBoundary.stories.tsx new file mode 100644 index 000000000..e8bd140bf --- /dev/null +++ b/.storybook/stories/ui/utilities/ErrorBoundary.stories.tsx @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ErrorBoundary, errorBoundaryDefaultColorScheme } from '../../../../packages/ui/src/index'; + +const ThrowError = () => { + throw new Error('Example error for Storybook'); +}; + +const meta = { + title: 'UI/Utilities/ErrorBoundary', + component: ErrorBoundary, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const WithError: Story = { + args: { + colorScheme: errorBoundaryDefaultColorScheme, + children: , + }, +}; + +export const NoError: Story = { + args: { + colorScheme: errorBoundaryDefaultColorScheme, + children: ( +
+ This content renders normally when no error occurs. +
+ ), + }, +}; diff --git a/.storybook/stories/ui/utilities/HelpTooltip.stories.tsx b/.storybook/stories/ui/utilities/HelpTooltip.stories.tsx new file mode 100644 index 000000000..25aee5458 --- /dev/null +++ b/.storybook/stories/ui/utilities/HelpTooltip.stories.tsx @@ -0,0 +1,36 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { HelpTooltip } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Utilities/HelpTooltip', + component: HelpTooltip, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + term: 'Cpk', + content: + 'Process Capability Index (Cpk) measures how well a process meets specification limits, accounting for both spread and centering.', + }, +}; + +export const WithLearnMore: Story = { + args: { + term: 'Control Limits', + content: + 'Control limits (UCL/LCL) are calculated from the data as mean plus/minus 3 sigma. They represent the natural voice of the process.', + learnMoreUrl: '#', + }, +}; + +export const LongContent: Story = { + args: { + term: 'ANOVA', + content: + 'Analysis of Variance (ANOVA) tests whether the means of different groups are statistically different. A significant result (p < 0.05) indicates that at least one group mean differs. The eta-squared value shows what percentage of total variation is explained by the factor.', + }, +}; diff --git a/.storybook/stories/ui/utilities/UpgradePrompt.stories.tsx b/.storybook/stories/ui/utilities/UpgradePrompt.stories.tsx new file mode 100644 index 000000000..bba7afcd6 --- /dev/null +++ b/.storybook/stories/ui/utilities/UpgradePrompt.stories.tsx @@ -0,0 +1,29 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { UpgradePrompt } from '../../../../packages/ui/src/index'; + +const meta = { + title: 'UI/Utilities/UpgradePrompt', + component: UpgradePrompt, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + feature: 'Performance Mode', + description: + 'Analyze up to 1,500 measurement channels simultaneously with the Azure Standard plan.', + }, +}; + +export const ChannelLimit: Story = { + args: { + feature: 'More Channels', + description: + 'The free tier supports up to 5 channels. Upgrade to Azure for up to 1,500 channels.', + currentCount: 5, + maxCount: 5, + }, +}; diff --git a/CLAUDE.md b/CLAUDE.md index 8c836905d..874e6c063 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,6 +16,14 @@ pnpm --filter @variscout/azure-app test # Azure app tests only claude --chrome # Enable Chrome browser for E2E testing +pnpm storybook # Component catalog (localhost:6006) +pnpm build-storybook # Build static Storybook + +pnpm docs:dev # Starlight doc site (localhost:4321) +pnpm docs:build # Build static doc site +pnpm docs:c4 # Export LikeC4 → Mermaid +pnpm docs:c4:serve # Interactive C4 browser + npx ruflo@latest security scan --depth full # OWASP security scan npx ruflo@latest security cve --check # CVE check @@ -56,7 +64,8 @@ docs/ │ │ # performance-mode, nelson-rules, staged-analysis, │ │ # probability-plot, variation-decomposition │ ├── workflows/ # four-lenses, drill-down, performance-mode, quick-check, -│ │ # deep-dive, decision-trees, investigation-to-action, process-maps +│ │ # deep-dive, decision-trees, investigation-to-action, process-maps, +│ │ # analysis-journey-map, investigation-lifecycle-map │ ├── data/ # data-input, storage, validation │ ├── navigation/ # drill-down, breadcrumbs, linked-filtering │ └── learning/ # case-based-learning, glossary, help-tooltips @@ -71,7 +80,8 @@ docs/ ├── 05-technical/ # Technical architecture │ ├── index.md │ ├── architecture.md -│ ├── architecture/ # offline-first, monorepo, shared-packages, data-flow, component-patterns +│ ├── architecture/ # offline-first, monorepo, shared-packages, data-flow, component-patterns, +│ │ # system-map, data-pipeline-map, component-map │ ├── implementation/ # data-input, deployment, testing, system-limits, security-scanning, ruflo │ └── integrations/ # shared-ui, embed-messaging ├── 06-design-system/ # Design tokens and components @@ -95,6 +105,8 @@ docs/ │ ├── pwa/ # index (demo tool), storage │ ├── website/ # index, design-philosophy, content-architecture │ └── powerbi/ +├── architecture/ # LikeC4 model (C4 L1-L3 source of truth) +│ └── likec4/ # model.c4, core.c4, charts.c4, hooks.c4, ui.c4, views.c4 └── archive/ # HISTORICAL ONLY — removed features, do not reference for current work sales/ # Sales leads and company contacts (not software docs) @@ -102,55 +114,64 @@ sales/ # Sales leads and company contacts (not software docs) ## Task-to-Documentation Mapping -| Task Type | Read First | -| ------------------------ | ------------------------------------------------------------------------------------------------------- | -| Statistics/Cpk changes | docs/03-features/analysis/capability.md, packages/core/src/stats.ts | -| Chart modifications | docs/06-design-system/charts/, .claude/rules/charts.md | -| Azure app changes | docs/08-products/azure/, packages/hooks/src/useDataState.ts | -| Adding new feature | docs/07-decisions/ (check ADRs), docs/05-technical/ | -| Parser/data input | docs/03-features/data/data-input.md, packages/core/src/parser.ts | -| Design system | docs/06-design-system/foundations/, packages/ui/src/colors.ts | -| User personas | docs/02-journeys/personas/, docs/01-vision/philosophy.md | -| Use cases / SEO | docs/02-journeys/use-cases/ | -| Performance Mode | docs/03-features/analysis/performance-mode.md | -| Testing (E2E/Chrome) | docs/05-technical/implementation/testing.md Feature Verification Protocols | -| Testing (Unit/Component) | docs/05-technical/implementation/testing.md, .claude/rules/testing.md | -| Licensing/Tiers | docs/07-decisions/adr-007-azure-marketplace-distribution.md | -| Deployment | docs/05-technical/implementation/deployment.md | -| Website changes | docs/08-products/website/, apps/website/README.md, .claude/rules/charts.md | -| Website design | docs/08-products/website/design-philosophy.md | -| Website content arch | docs/08-products/website/content-architecture.md, adr-008 | -| Use case pages | docs/08-products/website/content-architecture.md, apps/website/src/data/useCaseData.ts | -| Nelson Rules/Runs | docs/03-features/analysis/nelson-rules.md | -| Staged Analysis | docs/03-features/analysis/staged-analysis.md | -| Probability Plots | docs/03-features/analysis/probability-plot.md | -| Data Flow/Architecture | docs/05-technical/architecture/data-flow.md | -| Hook Integration | docs/05-technical/architecture/component-patterns.md | -| Platform Comparison | docs/08-products/feature-parity.md | -| Analysis Workflows | docs/03-features/workflows/ (four-lenses, drill-down, decision-trees) | -| Quick Analysis | docs/03-features/workflows/quick-check.md, deep-dive.md | -| Drill-down workflow | docs/03-features/workflows/drill-down-workflow.md | -| Four Lenses workflow | docs/03-features/workflows/four-lenses-workflow.md | -| Decision trees | docs/03-features/workflows/decision-trees.md | -| Glossary/terminology | packages/core/src/glossary/terms.ts, docs/03-features/learning/glossary.md | -| Azure deployment/ARM | docs/08-products/azure/marketplace.md, docs/08-products/azure/arm-template.md | -| Azure auth (EasyAuth) | docs/08-products/azure/authentication.md | -| OneDrive sync | docs/08-products/azure/onedrive-sync.md | -| UI components (modals) | docs/06-design-system/components/ | -| Color/typography | docs/06-design-system/foundations/ | -| Case studies | docs/04-cases/index.md | -| Product specs/tagline | docs/03-features/specifications.md | -| Ruflo / AI tooling | docs/07-decisions/adr-011-ai-development-tooling.md, docs/05-technical/implementation/ruflo.md | -| Statistics reference | docs/05-technical/statistics-reference.md | -| Investigation workflow | docs/03-features/workflows/investigation-to-action.md | -| Investigation tracking | docs/07-decisions/adr-015-investigation-board.md, docs/03-features/workflows/investigation-to-action.md | -| Characteristic types | docs/03-features/analysis/characteristic-types.md, packages/core/src/types.ts | -| Variation metrics/SS | docs/03-features/analysis/variation-decomposition.md, packages/core/src/variation/contributions.ts | -| What-If/simulation | docs/06-design-system/components/what-if-simulator.md, packages/core/src/variation/simulation.ts | -| Azure CI/CD pipeline | `.github/workflows/deploy-azure-staging.yml`, `docs/05-technical/implementation/deployment.md` | -| Teams integration | docs/07-decisions/adr-016-teams-integration.md, docs/08-products/azure/authentication.md | -| Teams SSO / OBO auth | apps/azure/src/auth/graphToken.ts, docs/08-products/azure/authentication.md | -| EXIF / photo security | packages/core/src/utils/exifStrip.ts, docs/07-decisions/adr-016-security-evaluation.md | +| Task Type | Read First | +| ------------------------- | ------------------------------------------------------------------------------------------------------- | +| Statistics/Cpk changes | docs/03-features/analysis/capability.md, packages/core/src/stats.ts | +| Chart modifications | docs/06-design-system/charts/, .claude/rules/charts.md | +| Azure app changes | docs/08-products/azure/, packages/hooks/src/useDataState.ts | +| Adding new feature | docs/07-decisions/ (check ADRs), docs/05-technical/ | +| Parser/data input | docs/03-features/data/data-input.md, packages/core/src/parser.ts | +| Design system | docs/06-design-system/foundations/, packages/ui/src/colors.ts | +| User personas | docs/02-journeys/personas/, docs/01-vision/philosophy.md | +| Use cases / SEO | docs/02-journeys/use-cases/ | +| Performance Mode | docs/03-features/analysis/performance-mode.md | +| Testing (E2E/Chrome) | docs/05-technical/implementation/testing.md Feature Verification Protocols | +| Testing (Unit/Component) | docs/05-technical/implementation/testing.md, .claude/rules/testing.md | +| Licensing/Tiers | docs/07-decisions/adr-007-azure-marketplace-distribution.md | +| Deployment | docs/05-technical/implementation/deployment.md | +| Website changes | docs/08-products/website/, apps/website/README.md, .claude/rules/charts.md | +| Website design | docs/08-products/website/design-philosophy.md | +| Website content arch | docs/08-products/website/content-architecture.md, adr-008 | +| Use case pages | docs/08-products/website/content-architecture.md, apps/website/src/data/useCaseData.ts | +| Nelson Rules/Runs | docs/03-features/analysis/nelson-rules.md | +| Staged Analysis | docs/03-features/analysis/staged-analysis.md | +| Probability Plots | docs/03-features/analysis/probability-plot.md | +| Data Flow/Architecture | docs/05-technical/architecture/data-flow.md | +| Hook Integration | docs/05-technical/architecture/component-patterns.md | +| Platform Comparison | docs/08-products/feature-parity.md | +| Analysis Workflows | docs/03-features/workflows/ (four-lenses, drill-down, decision-trees) | +| Quick Analysis | docs/03-features/workflows/quick-check.md, deep-dive.md | +| Drill-down workflow | docs/03-features/workflows/drill-down-workflow.md | +| Four Lenses workflow | docs/03-features/workflows/four-lenses-workflow.md | +| Decision trees | docs/03-features/workflows/decision-trees.md | +| Glossary/terminology | packages/core/src/glossary/terms.ts, docs/03-features/learning/glossary.md | +| Azure deployment/ARM | docs/08-products/azure/marketplace.md, docs/08-products/azure/arm-template.md | +| Azure auth (EasyAuth) | docs/08-products/azure/authentication.md | +| OneDrive sync | docs/08-products/azure/onedrive-sync.md | +| UI components (modals) | docs/06-design-system/components/ | +| Color/typography | docs/06-design-system/foundations/ | +| Case studies | docs/04-cases/index.md | +| Product specs/tagline | docs/03-features/specifications.md | +| Ruflo / AI tooling | docs/07-decisions/adr-011-ai-development-tooling.md, docs/05-technical/implementation/ruflo.md | +| Statistics reference | docs/05-technical/statistics-reference.md | +| Documentation methodology | docs/05-technical/documentation-methodology.md | +| Storybook / components | `.storybook/stories/`, `.storybook/stories/README.md` | +| Investigation workflow | docs/03-features/workflows/investigation-to-action.md | +| Investigation tracking | docs/07-decisions/adr-015-investigation-board.md, docs/03-features/workflows/investigation-to-action.md | +| Characteristic types | docs/03-features/analysis/characteristic-types.md, packages/core/src/types.ts | +| Variation metrics/SS | docs/03-features/analysis/variation-decomposition.md, packages/core/src/variation/contributions.ts | +| What-If/simulation | docs/06-design-system/components/what-if-simulator.md, packages/core/src/variation/simulation.ts | +| Azure CI/CD pipeline | `.github/workflows/deploy-azure-staging.yml`, `docs/05-technical/implementation/deployment.md` | +| Teams integration | docs/07-decisions/adr-016-teams-integration.md, docs/08-products/azure/authentication.md | +| Teams SSO / OBO auth | apps/azure/src/auth/graphToken.ts, docs/08-products/azure/authentication.md | +| EXIF / photo security | packages/core/src/utils/exifStrip.ts, docs/07-decisions/adr-016-security-evaluation.md | +| System topology | docs/05-technical/architecture/system-map.md | +| Component decomposition | docs/05-technical/architecture/component-map.md, docs/architecture/likec4/ | +| C4 architecture model | docs/architecture/likec4/ | +| Analysis journey | docs/03-features/workflows/analysis-journey-map.md | +| Data pipeline | docs/05-technical/architecture/data-pipeline-map.md | +| Investigation lifecycle | docs/03-features/workflows/investigation-lifecycle-map.md | +| Core API reference | `pnpm --filter @variscout/core docs`, docs/05-technical/api/core/ | ## Repository Structure @@ -169,7 +190,8 @@ variscout-lite/ ├── apps/ │ ├── pwa/ # PWA website (React + Vite) │ ├── azure/ # Azure Team App (EasyAuth + OneDrive sync) -│ └── website/ # Marketing website (Astro + React Islands) +│ ├── website/ # Marketing website (Astro + React Islands) +│ └── docs/ # Documentation site (Astro + Starlight) ├── infra/ # ARM template (mainTemplate.json + createUiDefinition.json) └── docs/ # Documentation (see index above) ``` diff --git a/apps/docs/.astro/collections/docs.schema.json b/apps/docs/.astro/collections/docs.schema.json new file mode 100644 index 000000000..a663eb8f9 --- /dev/null +++ b/apps/docs/.astro/collections/docs.schema.json @@ -0,0 +1,595 @@ +{ + "$ref": "#/definitions/docs", + "definitions": { + "docs": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "editUrl": { + "anyOf": [ + { + "type": "string", + "format": "uri" + }, + { + "type": "boolean" + } + ], + "default": true + }, + "head": { + "type": "array", + "items": { + "type": "object", + "properties": { + "tag": { + "type": "string", + "enum": ["title", "base", "link", "style", "meta", "script", "noscript", "template"] + }, + "attrs": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "boolean" + }, + { + "not": {} + } + ] + } + }, + "content": { + "type": "string" + } + }, + "required": ["tag"], + "additionalProperties": false + }, + "default": [] + }, + "tableOfContents": { + "anyOf": [ + { + "type": "object", + "properties": { + "minHeadingLevel": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "default": 2 + }, + "maxHeadingLevel": { + "type": "integer", + "minimum": 1, + "maximum": 6, + "default": 3 + } + }, + "additionalProperties": false + }, + { + "type": "boolean" + } + ], + "default": { + "minHeadingLevel": 2, + "maxHeadingLevel": 3 + } + }, + "template": { + "type": "string", + "enum": ["doc", "splash"], + "default": "doc" + }, + "hero": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "tagline": { + "type": "string" + }, + "image": { + "anyOf": [ + { + "type": "object", + "properties": { + "alt": { + "type": "string", + "default": "" + }, + "file": { + "type": "string" + } + }, + "required": ["file"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "alt": { + "type": "string", + "default": "" + }, + "dark": { + "type": "string" + }, + "light": { + "type": "string" + } + }, + "required": ["dark", "light"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "html": { + "type": "string" + } + }, + "required": ["html"], + "additionalProperties": false + } + ] + }, + "actions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "link": { + "type": "string" + }, + "variant": { + "type": "string", + "enum": ["primary", "secondary", "minimal"], + "default": "primary" + }, + "icon": { + "anyOf": [ + { + "type": "string", + "enum": [ + "up-caret", + "down-caret", + "right-caret", + "left-caret", + "up-arrow", + "down-arrow", + "right-arrow", + "left-arrow", + "bars", + "translate", + "pencil", + "pen", + "document", + "add-document", + "setting", + "external", + "download", + "cloud-download", + "moon", + "sun", + "laptop", + "open-book", + "information", + "magnifier", + "forward-slash", + "close", + "error", + "warning", + "approve-check-circle", + "approve-check", + "rocket", + "star", + "puzzle", + "list-format", + "random", + "comment", + "comment-alt", + "heart", + "github", + "gitlab", + "bitbucket", + "codePen", + "farcaster", + "discord", + "gitter", + "twitter", + "x.com", + "mastodon", + "codeberg", + "youtube", + "threads", + "linkedin", + "twitch", + "azureDevOps", + "microsoftTeams", + "instagram", + "stackOverflow", + "telegram", + "rss", + "facebook", + "email", + "phone", + "reddit", + "patreon", + "signal", + "slack", + "matrix", + "hackerOne", + "openCollective", + "blueSky", + "discourse", + "zulip", + "pinterest", + "tiktok", + "astro", + "alpine", + "pnpm", + "biome", + "bun", + "mdx", + "apple", + "linux", + "homebrew", + "nix", + "starlight", + "pkl", + "node", + "cloudflare", + "vercel", + "netlify", + "deno", + "jsr", + "nostr", + "backstage", + "confluence", + "jira", + "storybook", + "vscode", + "jetbrains", + "zed", + "vim", + "figma", + "sketch", + "npm", + "sourcehut", + "substack", + "seti:folder", + "seti:bsl", + "seti:mdo", + "seti:salesforce", + "seti:asm", + "seti:bicep", + "seti:bazel", + "seti:c", + "seti:c-sharp", + "seti:html", + "seti:cpp", + "seti:clojure", + "seti:coldfusion", + "seti:config", + "seti:crystal", + "seti:crystal_embedded", + "seti:json", + "seti:css", + "seti:csv", + "seti:xls", + "seti:cu", + "seti:cake", + "seti:cake_php", + "seti:d", + "seti:word", + "seti:elixir", + "seti:elixir_script", + "seti:hex", + "seti:elm", + "seti:favicon", + "seti:f-sharp", + "seti:git", + "seti:go", + "seti:godot", + "seti:gradle", + "seti:grails", + "seti:graphql", + "seti:hacklang", + "seti:haml", + "seti:mustache", + "seti:haskell", + "seti:haxe", + "seti:jade", + "seti:java", + "seti:javascript", + "seti:jinja", + "seti:julia", + "seti:karma", + "seti:kotlin", + "seti:dart", + "seti:liquid", + "seti:livescript", + "seti:lua", + "seti:markdown", + "seti:argdown", + "seti:info", + "seti:clock", + "seti:maven", + "seti:nim", + "seti:github", + "seti:notebook", + "seti:nunjucks", + "seti:npm", + "seti:ocaml", + "seti:odata", + "seti:perl", + "seti:php", + "seti:pipeline", + "seti:pddl", + "seti:plan", + "seti:happenings", + "seti:powershell", + "seti:prisma", + "seti:pug", + "seti:puppet", + "seti:purescript", + "seti:python", + "seti:react", + "seti:rescript", + "seti:R", + "seti:ruby", + "seti:rust", + "seti:sass", + "seti:spring", + "seti:slim", + "seti:smarty", + "seti:sbt", + "seti:scala", + "seti:ethereum", + "seti:stylus", + "seti:svelte", + "seti:swift", + "seti:db", + "seti:terraform", + "seti:tex", + "seti:default", + "seti:twig", + "seti:typescript", + "seti:tsconfig", + "seti:vala", + "seti:vite", + "seti:vue", + "seti:wasm", + "seti:wat", + "seti:xml", + "seti:yml", + "seti:prolog", + "seti:zig", + "seti:zip", + "seti:wgt", + "seti:illustrator", + "seti:photoshop", + "seti:pdf", + "seti:font", + "seti:image", + "seti:svg", + "seti:sublime", + "seti:code-search", + "seti:shell", + "seti:video", + "seti:audio", + "seti:windows", + "seti:jenkins", + "seti:babel", + "seti:bower", + "seti:docker", + "seti:code-climate", + "seti:eslint", + "seti:firebase", + "seti:firefox", + "seti:gitlab", + "seti:grunt", + "seti:gulp", + "seti:ionic", + "seti:platformio", + "seti:rollup", + "seti:stylelint", + "seti:yarn", + "seti:webpack", + "seti:lock", + "seti:license", + "seti:makefile", + "seti:heroku", + "seti:todo", + "seti:ignored" + ] + }, + { + "type": "string", + "pattern": "^\\; + components: import('astro').MDXInstance<{}>['components']; + }>; + } +} + +declare module 'astro:content' { + export interface RenderResult { + Content: import('astro/runtime/server/index.js').AstroComponentFactory; + headings: import('astro').MarkdownHeading[]; + remarkPluginFrontmatter: Record; + } + interface Render { + '.md': Promise; + } + + export interface RenderedContent { + html: string; + metadata?: { + imagePaths: Array; + [key: string]: unknown; + }; + } +} + +declare module 'astro:content' { + type Flatten = T extends { [K: string]: infer U } ? U : never; + + export type CollectionKey = keyof AnyEntryMap; + export type CollectionEntry = Flatten; + + export type ContentCollectionKey = keyof ContentEntryMap; + export type DataCollectionKey = keyof DataEntryMap; + + type AllValuesOf = T extends any ? T[keyof T] : never; + type ValidContentEntrySlug = AllValuesOf< + ContentEntryMap[C] + >['slug']; + + export type ReferenceDataEntry< + C extends CollectionKey, + E extends keyof DataEntryMap[C] = string, + > = { + collection: C; + id: E; + }; + export type ReferenceContentEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}) = string, + > = { + collection: C; + slug: E; + }; + export type ReferenceLiveEntry = { + collection: C; + id: string; + }; + + /** @deprecated Use `getEntry` instead. */ + export function getEntryBySlug< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >( + collection: C, + // Note that this has to accept a regular string too, for SSR + entrySlug: E + ): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + + /** @deprecated Use `getEntry` instead. */ + export function getDataEntryById( + collection: C, + entryId: E + ): Promise>; + + export function getCollection>( + collection: C, + filter?: (entry: CollectionEntry) => entry is E + ): Promise; + export function getCollection( + collection: C, + filter?: (entry: CollectionEntry) => unknown + ): Promise[]>; + + export function getLiveCollection( + collection: C, + filter?: LiveLoaderCollectionFilterType + ): Promise< + import('astro').LiveDataCollectionResult, LiveLoaderErrorType> + >; + + export function getEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >( + entry: ReferenceContentEntry + ): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + entry: ReferenceDataEntry + ): E extends keyof DataEntryMap[C] + ? Promise + : Promise | undefined>; + export function getEntry< + C extends keyof ContentEntryMap, + E extends ValidContentEntrySlug | (string & {}), + >( + collection: C, + slug: E + ): E extends ValidContentEntrySlug + ? Promise> + : Promise | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + collection: C, + id: E + ): E extends keyof DataEntryMap[C] + ? string extends keyof DataEntryMap[C] + ? Promise | undefined + : Promise + : Promise | undefined>; + export function getLiveEntry( + collection: C, + filter: string | LiveLoaderEntryFilterType + ): Promise, LiveLoaderErrorType>>; + + /** Resolve an array of entry references from the same collection */ + export function getEntries( + entries: ReferenceContentEntry>[] + ): Promise[]>; + export function getEntries( + entries: ReferenceDataEntry[] + ): Promise[]>; + + export function render( + entry: AnyEntryMap[C][string] + ): Promise; + + export function reference( + collection: C + ): import('astro/zod').ZodEffects< + import('astro/zod').ZodString, + C extends keyof ContentEntryMap + ? ReferenceContentEntry> + : ReferenceDataEntry + >; + // Allow generic `string` to avoid excessive type errors in the config + // if `dev` is not running to update as you edit. + // Invalid collection names will be caught at build time. + export function reference( + collection: C + ): import('astro/zod').ZodEffects; + + type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; + type InferEntrySchema = import('astro/zod').infer< + ReturnTypeOrOriginal['schema']> + >; + + type ContentEntryMap = {}; + + type DataEntryMap = { + docs: Record< + string, + { + id: string; + body?: string; + collection: 'docs'; + data: InferEntrySchema<'docs'>; + rendered?: RenderedContent; + filePath?: string; + } + >; + }; + + type AnyEntryMap = ContentEntryMap & DataEntryMap; + + type ExtractLoaderTypes = T extends import('astro/loaders').LiveLoader< + infer TData, + infer TEntryFilter, + infer TCollectionFilter, + infer TError + > + ? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError } + : { data: never; entryFilter: never; collectionFilter: never; error: never }; + type ExtractDataType = ExtractLoaderTypes['data']; + type ExtractEntryFilterType = ExtractLoaderTypes['entryFilter']; + type ExtractCollectionFilterType = ExtractLoaderTypes['collectionFilter']; + type ExtractErrorType = ExtractLoaderTypes['error']; + + type LiveLoaderDataType = + LiveContentConfig['collections'][C]['schema'] extends undefined + ? ExtractDataType + : import('astro/zod').infer< + Exclude + >; + type LiveLoaderEntryFilterType = + ExtractEntryFilterType; + type LiveLoaderCollectionFilterType = + ExtractCollectionFilterType; + type LiveLoaderErrorType = ExtractErrorType< + LiveContentConfig['collections'][C]['loader'] + >; + + export type ContentConfig = typeof import('../src/content.config.js'); + export type LiveContentConfig = never; +} diff --git a/apps/docs/.astro/data-store.json b/apps/docs/.astro/data-store.json new file mode 100644 index 000000000..3a3e16e25 --- /dev/null +++ b/apps/docs/.astro/data-store.json @@ -0,0 +1,17703 @@ +[ + ["Map", 1, 2, 9, 10], + "meta::meta", + ["Map", 3, 4, 5, 6, 7, 8], + "astro-version", + "5.18.0", + "content-config-digest", + "3e93567dcc77d5f1", + "astro-config-digest", + "{\"root\":{},\"srcDir\":{},\"publicDir\":{},\"outDir\":{},\"cacheDir\":{},\"compressHTML\":true,\"base\":\"/\",\"trailingSlash\":\"ignore\",\"output\":\"static\",\"scopedStyleStrategy\":\"where\",\"build\":{\"format\":\"directory\",\"client\":{},\"server\":{},\"assets\":\"_astro\",\"serverEntry\":\"entry.mjs\",\"redirects\":true,\"inlineStylesheets\":\"auto\",\"concurrency\":1},\"server\":{\"open\":false,\"host\":false,\"port\":4321,\"streaming\":true,\"allowedHosts\":[]},\"redirects\":{},\"image\":{\"endpoint\":{\"route\":\"/_image\"},\"service\":{\"entrypoint\":\"astro/assets/services/sharp\",\"config\":{}},\"domains\":[],\"remotePatterns\":[],\"responsiveStyles\":false},\"devToolbar\":{\"enabled\":true},\"markdown\":{\"syntaxHighlight\":false,\"shikiConfig\":{\"langs\":[],\"langAlias\":{},\"theme\":\"github-dark\",\"themes\":{},\"wrap\":false,\"transformers\":[]},\"remarkPlugins\":[null,null,null],\"rehypePlugins\":[[null,{\"strategy\":\"pre-mermaid\"}],null,[null,{\"experimentalHeadingIdCompat\":false}],null,[null,{\"themes\":[{\"name\":\"Night Owl No Italics\",\"type\":\"dark\",\"colors\":{\"focusBorder\":\"#122d42\",\"foreground\":\"#d6deeb\",\"disabledForeground\":\"#cccccc80\",\"descriptionForeground\":\"#d6deebb3\",\"errorForeground\":\"#ef5350\",\"icon.foreground\":\"#c5c5c5\",\"contrastActiveBorder\":null,\"contrastBorder\":\"#122d42\",\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#4f4f4f\",\"textLink.activeForeground\":\"#3794ff\",\"textLink.foreground\":\"#3794ff\",\"textPreformat.foreground\":\"#d7ba7d\",\"textSeparator.foreground\":\"#ffffff2e\",\"editor.background\":\"#23262f\",\"editor.foreground\":\"#d6deeb\",\"editorLineNumber.foreground\":\"#4b6479\",\"editorLineNumber.activeForeground\":\"#c5e4fd\",\"editorActiveLineNumber.foreground\":\"#c6c6c6\",\"editor.selectionBackground\":\"#1d3b53\",\"editor.inactiveSelectionBackground\":\"#7e57c25a\",\"editor.selectionHighlightBackground\":\"#5f7e9779\",\"editorError.foreground\":\"#ef5350\",\"editorWarning.foreground\":\"#b39554\",\"editorInfo.foreground\":\"#3794ff\",\"editorHint.foreground\":\"#eeeeeeb2\",\"problemsErrorIcon.foreground\":\"#ef5350\",\"problemsWarningIcon.foreground\":\"#b39554\",\"problemsInfoIcon.foreground\":\"#3794ff\",\"editor.findMatchBackground\":\"#5f7e9779\",\"editor.findMatchHighlightBackground\":\"#1085bb5d\",\"editor.findRangeHighlightBackground\":\"#3a3d4166\",\"editorLink.activeForeground\":\"#4e94ce\",\"editorLightBulb.foreground\":\"#ffcc00\",\"editorLightBulbAutoFix.foreground\":\"#75beff\",\"diffEditor.insertedTextBackground\":\"#99b76d23\",\"diffEditor.insertedTextBorder\":\"#c5e47833\",\"diffEditor.removedTextBackground\":\"#ef535033\",\"diffEditor.removedTextBorder\":\"#ef53504d\",\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#011627\",\"editorStickyScrollHover.background\":\"#2a2d2e\",\"editorInlayHint.background\":\"#5f7e97cc\",\"editorInlayHint.foreground\":\"#ffffff\",\"editorInlayHint.typeBackground\":\"#5f7e97cc\",\"editorInlayHint.typeForeground\":\"#ffffff\",\"editorInlayHint.parameterBackground\":\"#5f7e97cc\",\"editorInlayHint.parameterForeground\":\"#ffffff\",\"editorPane.background\":\"#011627\",\"editorGroup.emptyBackground\":\"#011627\",\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-black)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#011627\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#011627\",\"editorGroup.dropBackground\":\"#7e57c273\",\"editorGroup.dropIntoPromptForeground\":\"#d6deeb\",\"editorGroup.dropIntoPromptBackground\":\"#021320\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#011627\",\"sideBySideEditor.verticalBorder\":\"#011627\",\"scrollbar.shadow\":\"#010b14\",\"scrollbarSlider.background\":\"#ffffff17\",\"scrollbarSlider.hoverBackground\":\"#ffffff40\",\"scrollbarSlider.activeBackground\":\"#084d8180\",\"panel.background\":\"#011627\",\"panel.border\":\"#5f7e97\",\"panelTitle.activeBorder\":\"#5f7e97\",\"panelTitle.activeForeground\":\"#ffffffcc\",\"panelTitle.inactiveForeground\":\"#d6deeb80\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#011627\",\"widget.shadow\":\"#011627\",\"editorWidget.background\":\"#021320\",\"editorWidget.foreground\":\"#d6deeb\",\"editorWidget.border\":\"#5f7e97\",\"quickInput.background\":\"#021320\",\"quickInput.foreground\":\"#d6deeb\",\"quickInputTitle.background\":\"#ffffff1a\",\"pickerGroup.foreground\":\"#d1aaff\",\"pickerGroup.border\":\"#011627\",\"editor.hoverHighlightBackground\":\"#7e57c25a\",\"editorHoverWidget.background\":\"#011627\",\"editorHoverWidget.foreground\":\"#d6deeb\",\"editorHoverWidget.border\":\"#5f7e97\",\"editorHoverWidget.statusBarBackground\":\"#011a2f\",\"titleBar.activeBackground\":\"var(--sl-color-black)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#010e1a\",\"titleBar.inactiveForeground\":\"#eeefff99\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#5a5d5e50\",\"toolbar.activeBackground\":\"#63666750\",\"tab.activeBackground\":\"#0b2942\",\"tab.unfocusedActiveBackground\":\"#0b2942\",\"tab.inactiveBackground\":\"#01111d\",\"tab.unfocusedInactiveBackground\":\"#01111d\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#5f7e97\",\"tab.unfocusedActiveForeground\":\"#5f7e97\",\"tab.unfocusedInactiveForeground\":\"#5f7e97\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#272b3b\",\"tab.lastPinnedBorder\":\"#585858\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":\"#262a39\",\"tab.activeBorderTop\":\"var(--sl-color-accent-high)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#3399cc\",\"tab.inactiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedActiveModifiedBorder\":\"#3399cc80\",\"tab.unfocusedInactiveModifiedBorder\":\"#3399cc40\",\"badge.background\":\"#5f7e97\",\"badge.foreground\":\"#ffffff\",\"button.background\":\"#7e57c2cc\",\"button.foreground\":\"#ffffffcc\",\"button.border\":\"#122d42\",\"button.separator\":\"#ffffff52\",\"button.hoverBackground\":\"#7e57c2\",\"button.secondaryBackground\":\"#3a3d41\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#46494e\",\"dropdown.background\":\"#011627\",\"dropdown.foreground\":\"#ffffffcc\",\"dropdown.border\":\"#5f7e97\",\"list.activeSelectionBackground\":\"#234d708c\",\"list.activeSelectionForeground\":\"#ffffff\",\"tree.indentGuidesStroke\":\"#585858\",\"input.background\":\"#0b253a\",\"input.foreground\":\"#ffffffcc\",\"input.placeholderForeground\":\"#5f7e97\",\"inputOption.activeBorder\":\"#ffffffcc\",\"inputOption.hoverBackground\":\"#5a5d5e80\",\"inputOption.activeBackground\":\"#122d4266\",\"inputOption.activeForeground\":\"#ffffff\",\"inputValidation.infoBackground\":\"#00589ef2\",\"inputValidation.infoBorder\":\"#64b5f6\",\"inputValidation.warningBackground\":\"#675700f2\",\"inputValidation.warningBorder\":\"#ffca28\",\"inputValidation.errorBackground\":\"#ab0300f2\",\"inputValidation.errorBorder\":\"#ef5350\",\"keybindingLabel.background\":\"#8080802b\",\"keybindingLabel.foreground\":\"#cccccc\",\"keybindingLabel.border\":\"#33333399\",\"keybindingLabel.bottomBorder\":\"#44444499\",\"menu.foreground\":\"#ffffffcc\",\"menu.background\":\"#011627\",\"menu.selectionForeground\":\"#ffffff\",\"menu.selectionBackground\":\"#234d708c\",\"menu.separatorBackground\":\"#606060\",\"editor.snippetTabstopHighlightBackground\":\"#7c7c74c\",\"editor.snippetFinalTabstopHighlightBorder\":\"#525252\",\"terminal.ansiBlack\":\"#011627\",\"terminal.ansiRed\":\"#ef5350\",\"terminal.ansiGreen\":\"#22da6e\",\"terminal.ansiYellow\":\"#c5e478\",\"terminal.ansiBlue\":\"#82aaff\",\"terminal.ansiMagenta\":\"#c792ea\",\"terminal.ansiCyan\":\"#21c7a8\",\"terminal.ansiWhite\":\"#ffffff\",\"terminal.ansiBrightBlack\":\"#575656\",\"terminal.ansiBrightRed\":\"#ef5350\",\"terminal.ansiBrightGreen\":\"#22da6e\",\"terminal.ansiBrightYellow\":\"#ffeb95\",\"terminal.ansiBrightBlue\":\"#82aaff\",\"terminal.ansiBrightMagenta\":\"#c792ea\",\"terminal.ansiBrightCyan\":\"#7fdbca\",\"terminal.ansiBrightWhite\":\"#ffffff\",\"selection.background\":\"#4373c2\",\"input.border\":\"#5f7e97\",\"punctuation.definition.generic.begin.html\":\"#ef5350f2\",\"progress.background\":\"#7e57c2\",\"breadcrumb.foreground\":\"#a599e9\",\"breadcrumb.focusForeground\":\"#ffffff\",\"breadcrumb.activeSelectionForeground\":\"#ffffff\",\"breadcrumbPicker.background\":\"#001122\",\"list.invalidItemForeground\":\"#975f94\",\"list.dropBackground\":\"#011627\",\"list.focusBackground\":\"#010d18\",\"list.focusForeground\":\"#ffffff\",\"list.highlightForeground\":\"#ffffff\",\"list.hoverBackground\":\"#011627\",\"list.hoverForeground\":\"#ffffff\",\"list.inactiveSelectionBackground\":\"#0e293f\",\"list.inactiveSelectionForeground\":\"#5f7e97\",\"activityBar.background\":\"#011627\",\"activityBar.dropBackground\":\"#5f7e97\",\"activityBar.foreground\":\"#5f7e97\",\"activityBar.border\":\"#011627\",\"activityBarBadge.background\":\"#44596b\",\"activityBarBadge.foreground\":\"#ffffff\",\"sideBar.background\":\"#011627\",\"sideBar.foreground\":\"#89a4bb\",\"sideBar.border\":\"#011627\",\"sideBarTitle.foreground\":\"#5f7e97\",\"sideBarSectionHeader.background\":\"#011627\",\"sideBarSectionHeader.foreground\":\"#5f7e97\",\"editorCursor.foreground\":\"#80a4c2\",\"editor.wordHighlightBackground\":\"#f6bbe533\",\"editor.wordHighlightStrongBackground\":\"#e2a2f433\",\"editor.lineHighlightBackground\":\"#0003\",\"editor.rangeHighlightBackground\":\"#7e57c25a\",\"editorIndentGuide.background\":\"#5e81ce52\",\"editorIndentGuide.activeBackground\":\"#7e97ac\",\"editorRuler.foreground\":\"#5e81ce52\",\"editorCodeLens.foreground\":\"#5e82ceb4\",\"editorBracketMatch.background\":\"#5f7e974d\",\"editorOverviewRuler.currentContentForeground\":\"#7e57c2\",\"editorOverviewRuler.incomingContentForeground\":\"#7e57c2\",\"editorOverviewRuler.commonContentForeground\":\"#7e57c2\",\"editorGutter.background\":\"#011627\",\"editorGutter.modifiedBackground\":\"#e2b93d\",\"editorGutter.addedBackground\":\"#9ccc65\",\"editorGutter.deletedBackground\":\"#ef5350\",\"editorSuggestWidget.background\":\"#2c3043\",\"editorSuggestWidget.border\":\"#2b2f40\",\"editorSuggestWidget.foreground\":\"#d6deeb\",\"editorSuggestWidget.highlightForeground\":\"#ffffff\",\"editorSuggestWidget.selectedBackground\":\"#5f7e97\",\"debugExceptionWidget.background\":\"#011627\",\"debugExceptionWidget.border\":\"#5f7e97\",\"editorMarkerNavigation.background\":\"#0b2942\",\"editorMarkerNavigationError.background\":\"#ef5350\",\"editorMarkerNavigationWarning.background\":\"#ffca28\",\"peekView.border\":\"#5f7e97\",\"peekViewEditor.background\":\"#011627\",\"peekViewEditor.matchHighlightBackground\":\"#7e57c25a\",\"peekViewResult.background\":\"#011627\",\"peekViewResult.fileForeground\":\"#5f7e97\",\"peekViewResult.lineForeground\":\"#5f7e97\",\"peekViewResult.matchHighlightBackground\":\"#ffffffcc\",\"peekViewResult.selectionBackground\":\"#2e3250\",\"peekViewResult.selectionForeground\":\"#5f7e97\",\"peekViewTitle.background\":\"#011627\",\"peekViewTitleDescription.foreground\":\"#697098\",\"peekViewTitleLabel.foreground\":\"#5f7e97\",\"merge.currentHeaderBackground\":\"#5f7e97\",\"merge.incomingHeaderBackground\":\"#7e57c25a\",\"statusBar.background\":\"#011627\",\"statusBar.foreground\":\"#5f7e97\",\"statusBar.border\":\"#262a39\",\"statusBar.debuggingBackground\":\"#202431\",\"statusBar.debuggingBorder\":\"#1f2330\",\"statusBar.noFolderBackground\":\"#011627\",\"statusBar.noFolderBorder\":\"#25293a\",\"statusBarItem.activeBackground\":\"#202431\",\"statusBarItem.hoverBackground\":\"#202431\",\"statusBarItem.prominentBackground\":\"#202431\",\"statusBarItem.prominentHoverBackground\":\"#202431\",\"notifications.background\":\"#01111d\",\"notifications.border\":\"#262a39\",\"notificationCenter.border\":\"#262a39\",\"notificationToast.border\":\"#262a39\",\"notifications.foreground\":\"#ffffffcc\",\"notificationLink.foreground\":\"#80cbc4\",\"extensionButton.prominentForeground\":\"#ffffffcc\",\"extensionButton.prominentBackground\":\"#7e57c2cc\",\"extensionButton.prominentHoverBackground\":\"#7e57c2\",\"terminal.selectionBackground\":\"#1b90dd4d\",\"terminalCursor.background\":\"#234d70\",\"debugToolBar.background\":\"#011627\",\"welcomePage.buttonBackground\":\"#011627\",\"welcomePage.buttonHoverBackground\":\"#011627\",\"walkThrough.embeddedEditorBackground\":\"#011627\",\"gitDecoration.modifiedResourceForeground\":\"#a2bffc\",\"gitDecoration.deletedResourceForeground\":\"#ef535090\",\"gitDecoration.untrackedResourceForeground\":\"#c5e478ff\",\"gitDecoration.ignoredResourceForeground\":\"#395a75\",\"gitDecoration.conflictingResourceForeground\":\"#ffeb95cc\",\"source.elm\":\"#5f7e97\",\"string.quoted.single.js\":\"#ffffff\",\"meta.objectliteral.js\":\"#82aaff\"},\"fg\":\"#d6deeb\",\"bg\":\"#23262f\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#a2bffc\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#f27775fe\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#d6deeb\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#919f9f\",\"fontStyle\":\"\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#5ca7e4\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#caece6\",\"fontStyle\":\"\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"fontStyle\":\"\",\"foreground\":\"#c5e478\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"background\":\"#ff2c83\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#d3423e\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#919f9f\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#cdebf7\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#ffffff\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#7fdbca\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#80cbc4\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#57eaf1\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#fad430\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#faf39f\",\"fontStyle\":\"\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#82aaff\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Comparison, returns, imports, and Keyword Operator Ruby\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#989da0\",\"background\":\"#F78C6C\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"background\":\"#8BD649\",\"foreground\":\"#ffffff\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#ffffff\",\"background\":\"#ec5f67\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#ef787f\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#d9f5dd\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#e2817f\"}},{\"name\":\"Backtics(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"CoffeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#31e1eb\"}},{\"name\":\"CoffeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Unquoted String Zone\",\"scope\":[\"string.unquoted.preprocessor.message.cs\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C# Region\",\"scope\":[\"punctuation.separator.hash.cs\",\"keyword.preprocessor.region.cs\",\"keyword.preprocessor.endregion.cs\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"bold\"}},{\"name\":\"C# Other Variables\",\"scope\":[\"variable.other.object.cs\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"C# Enum\",\"scope\":[\"entity.name.type.enum.cs\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Dart String\",\"scope\":[\"string.interpolated.single.dart\",\"string.interpolated.double.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Dart Class\",\"scope\":[\"support.class.dart\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#ff6d6d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#dddddd\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#e0dec6\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#6ae9f0\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#78ccf0\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#8b96ea\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#ffcb8b\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#c789d6\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#ecc48d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#c792ea\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#c5e478\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#969bb7\",\"fontStyle\":\"\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#80cbc4\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#ff869a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#d6deeb\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#82b1ff\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#ff6a83\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#b2ccd6\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#8eace3\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#c5e478\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#bec5d4\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#f78c6c\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#ffeb95\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#889fb2\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#7fdbca\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#d7dbe0\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#f78c6c\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#d6deeb\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#ffcb8b\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#c792ea\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#82aaff\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definintion.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-6)\",\"terminalBackground\":\"var(--sl-color-gray-6)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-6)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#ffffff17\",\"markBorderColor\":\"#ffffff40\"}}},{\"name\":\"Night Owl Light\",\"type\":\"light\",\"colors\":{\"focusBorder\":\"#93a1a1\",\"foreground\":\"#403f53\",\"disabledForeground\":\"#61616180\",\"descriptionForeground\":\"#403f53\",\"errorForeground\":\"#403f53\",\"icon.foreground\":\"#424242\",\"contrastActiveBorder\":null,\"contrastBorder\":null,\"textBlockQuote.background\":\"#7f7f7f1a\",\"textBlockQuote.border\":\"#007acc80\",\"textCodeBlock.background\":\"#dcdcdc66\",\"textLink.activeForeground\":\"#006ab1\",\"textLink.foreground\":\"#006ab1\",\"textPreformat.foreground\":\"#a31515\",\"textSeparator.foreground\":\"#0000002e\",\"editor.background\":\"#f6f7f9\",\"editor.foreground\":\"#403f53\",\"editorLineNumber.foreground\":\"#90a7b2\",\"editorLineNumber.activeForeground\":\"#403f53\",\"editorActiveLineNumber.foreground\":\"#0b216f\",\"editor.selectionBackground\":\"#e0e0e0\",\"editor.inactiveSelectionBackground\":\"#e0e0e080\",\"editor.selectionHighlightBackground\":\"#339cec33\",\"editorError.foreground\":\"#e64d49\",\"editorWarning.foreground\":\"#daaa01\",\"editorInfo.foreground\":\"#1a85ff\",\"editorHint.foreground\":\"#6c6c6c\",\"problemsErrorIcon.foreground\":\"#e64d49\",\"problemsWarningIcon.foreground\":\"#daaa01\",\"problemsInfoIcon.foreground\":\"#1a85ff\",\"editor.findMatchBackground\":\"#93a1a16c\",\"editor.findMatchHighlightBackground\":\"#93a1a16c\",\"editor.findRangeHighlightBackground\":\"#7497a633\",\"editorLink.activeForeground\":\"#0000ff\",\"editorLightBulb.foreground\":\"#ddb100\",\"editorLightBulbAutoFix.foreground\":\"#007acc\",\"diffEditor.insertedTextBackground\":\"#9ccc2c40\",\"diffEditor.insertedTextBorder\":null,\"diffEditor.removedTextBackground\":\"#ff000033\",\"diffEditor.removedTextBorder\":null,\"diffEditor.insertedLineBackground\":\"#9bb95533\",\"diffEditor.removedLineBackground\":\"#ff000033\",\"editorStickyScroll.background\":\"#fbfbfb\",\"editorStickyScrollHover.background\":\"#f0f0f0\",\"editorInlayHint.background\":\"#2aa29899\",\"editorInlayHint.foreground\":\"#f0f0f0\",\"editorInlayHint.typeBackground\":\"#2aa29899\",\"editorInlayHint.typeForeground\":\"#f0f0f0\",\"editorInlayHint.parameterBackground\":\"#2aa29899\",\"editorInlayHint.parameterForeground\":\"#f0f0f0\",\"editorPane.background\":\"#fbfbfb\",\"editorGroup.emptyBackground\":null,\"editorGroup.focusedEmptyBorder\":null,\"editorGroupHeader.tabsBackground\":\"var(--sl-color-gray-6)\",\"editorGroupHeader.tabsBorder\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"editorGroupHeader.noTabsBackground\":\"#f0f0f0\",\"editorGroupHeader.border\":null,\"editorGroup.border\":\"#f0f0f0\",\"editorGroup.dropBackground\":\"#2677cb2d\",\"editorGroup.dropIntoPromptForeground\":\"#403f53\",\"editorGroup.dropIntoPromptBackground\":\"#f0f0f0\",\"editorGroup.dropIntoPromptBorder\":null,\"sideBySideEditor.horizontalBorder\":\"#f0f0f0\",\"sideBySideEditor.verticalBorder\":\"#f0f0f0\",\"scrollbar.shadow\":\"#cccccc\",\"scrollbarSlider.background\":\"#0000001a\",\"scrollbarSlider.hoverBackground\":\"#00000055\",\"scrollbarSlider.activeBackground\":\"#00000099\",\"panel.background\":\"#f0f0f0\",\"panel.border\":\"#d9d9d9\",\"panelTitle.activeBorder\":\"#424242\",\"panelTitle.activeForeground\":\"#424242\",\"panelTitle.inactiveForeground\":\"#424242bf\",\"panelSectionHeader.background\":\"#80808051\",\"terminal.background\":\"#f6f6f6\",\"widget.shadow\":\"#d9d9d9\",\"editorWidget.background\":\"#f0f0f0\",\"editorWidget.foreground\":\"#403f53\",\"editorWidget.border\":\"#d9d9d9\",\"quickInput.background\":\"#f0f0f0\",\"quickInput.foreground\":\"#403f53\",\"quickInputTitle.background\":\"#0000000f\",\"pickerGroup.foreground\":\"#403f53\",\"pickerGroup.border\":\"#d9d9d9\",\"editor.hoverHighlightBackground\":\"#339cec33\",\"editorHoverWidget.background\":\"#f0f0f0\",\"editorHoverWidget.foreground\":\"#403f53\",\"editorHoverWidget.border\":\"#d9d9d9\",\"editorHoverWidget.statusBarBackground\":\"#e4e4e4\",\"titleBar.activeBackground\":\"var(--sl-color-gray-6)\",\"titleBar.activeForeground\":\"var(--sl-color-text)\",\"titleBar.inactiveBackground\":\"#f0f0f099\",\"titleBar.inactiveForeground\":\"#33333399\",\"titleBar.border\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"toolbar.hoverBackground\":\"#b8b8b850\",\"toolbar.activeBackground\":\"#a6a6a650\",\"tab.activeBackground\":\"#f6f6f6\",\"tab.unfocusedActiveBackground\":\"#f6f6f6\",\"tab.inactiveBackground\":\"#f0f0f0\",\"tab.unfocusedInactiveBackground\":\"#f0f0f0\",\"tab.activeForeground\":\"var(--sl-color-text)\",\"tab.inactiveForeground\":\"#403f53\",\"tab.unfocusedActiveForeground\":\"#403f53b3\",\"tab.unfocusedInactiveForeground\":\"#403f5380\",\"tab.hoverBackground\":null,\"tab.unfocusedHoverBackground\":null,\"tab.hoverForeground\":null,\"tab.unfocusedHoverForeground\":null,\"tab.border\":\"#f0f0f0\",\"tab.lastPinnedBorder\":\"#a9a9a9\",\"tab.activeBorder\":\"transparent\",\"tab.unfocusedActiveBorder\":null,\"tab.activeBorderTop\":\"var(--sl-color-accent)\",\"tab.unfocusedActiveBorderTop\":null,\"tab.hoverBorder\":null,\"tab.unfocusedHoverBorder\":null,\"tab.activeModifiedBorder\":\"#2aa298\",\"tab.inactiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedActiveModifiedBorder\":\"#93a1a1\",\"tab.unfocusedInactiveModifiedBorder\":\"#93a1a1\",\"badge.background\":\"#2aa298\",\"badge.foreground\":\"#f0f0f0\",\"button.background\":\"#2aa298\",\"button.foreground\":\"#f0f0f0\",\"button.border\":null,\"button.separator\":\"#f0f0f066\",\"button.hoverBackground\":\"#22827a\",\"button.secondaryBackground\":\"#5f6a79\",\"button.secondaryForeground\":\"#ffffff\",\"button.secondaryHoverBackground\":\"#4c5561\",\"dropdown.background\":\"#f0f0f0\",\"dropdown.foreground\":\"#403f53\",\"dropdown.border\":\"#d9d9d9\",\"list.activeSelectionBackground\":\"#d3e8f8\",\"list.activeSelectionForeground\":\"#403f53\",\"tree.indentGuidesStroke\":\"#a9a9a9\",\"input.background\":\"#f0f0f0\",\"input.foreground\":\"#403f53\",\"input.placeholderForeground\":\"#93a1a1\",\"inputOption.activeBorder\":\"#2aa298\",\"inputOption.hoverBackground\":\"#b8b8b850\",\"inputOption.activeBackground\":\"#93a1a133\",\"inputOption.activeForeground\":\"#000000\",\"inputValidation.infoBackground\":\"#f0f0f0\",\"inputValidation.infoBorder\":\"#d0d0d0\",\"inputValidation.warningBackground\":\"#daaa01\",\"inputValidation.warningBorder\":\"#e0af02\",\"inputValidation.errorBackground\":\"#f76e6e\",\"inputValidation.errorBorder\":\"#de3d3b\",\"keybindingLabel.background\":\"#dddddd66\",\"keybindingLabel.foreground\":\"#555555\",\"keybindingLabel.border\":\"#cccccc66\",\"keybindingLabel.bottomBorder\":\"#bbbbbb66\",\"menu.foreground\":\"#403f53\",\"menu.background\":\"#f0f0f0\",\"menu.selectionForeground\":\"#403f53\",\"menu.selectionBackground\":\"#d3e8f8\",\"menu.separatorBackground\":\"#d4d4d4\",\"editor.snippetTabstopHighlightBackground\":\"#0a326433\",\"editor.snippetFinalTabstopHighlightBorder\":\"#0a326480\",\"terminal.ansiBlack\":\"#403f53\",\"terminal.ansiRed\":\"#de3d3b\",\"terminal.ansiGreen\":\"#08916a\",\"terminal.ansiYellow\":\"#e0af02\",\"terminal.ansiBlue\":\"#288ed7\",\"terminal.ansiMagenta\":\"#d6438a\",\"terminal.ansiCyan\":\"#2aa298\",\"terminal.ansiWhite\":\"#f0f0f0\",\"terminal.ansiBrightBlack\":\"#403f53\",\"terminal.ansiBrightRed\":\"#de3d3b\",\"terminal.ansiBrightGreen\":\"#08916a\",\"terminal.ansiBrightYellow\":\"#daaa01\",\"terminal.ansiBrightBlue\":\"#288ed7\",\"terminal.ansiBrightMagenta\":\"#d6438a\",\"terminal.ansiBrightCyan\":\"#2aa298\",\"terminal.ansiBrightWhite\":\"#f0f0f0\",\"selection.background\":\"#7a8181ad\",\"notifications.background\":\"#f0f0f0\",\"notifications.foreground\":\"#403f53\",\"notificationLink.foreground\":\"#994cc3\",\"notifications.border\":\"#cccccc\",\"notificationCenter.border\":\"#cccccc\",\"notificationToast.border\":\"#cccccc\",\"notificationCenterHeader.foreground\":\"#403f53\",\"notificationCenterHeader.background\":\"#f0f0f0\",\"input.border\":\"#d9d9d9\",\"progressBar.background\":\"#2aa298\",\"list.inactiveSelectionBackground\":\"#e0e7ea\",\"list.inactiveSelectionForeground\":\"#403f53\",\"list.focusBackground\":\"#d3e8f8\",\"list.hoverBackground\":\"#d3e8f8\",\"list.focusForeground\":\"#403f53\",\"list.hoverForeground\":\"#403f53\",\"list.highlightForeground\":\"#403f53\",\"list.errorForeground\":\"#e64d49\",\"list.warningForeground\":\"#daaa01\",\"activityBar.background\":\"#f0f0f0\",\"activityBar.foreground\":\"#403f53\",\"activityBar.dropBackground\":\"#d0d0d0\",\"activityBarBadge.background\":\"#403f53\",\"activityBarBadge.foreground\":\"#f0f0f0\",\"activityBar.border\":\"#f0f0f0\",\"sideBar.background\":\"#f0f0f0\",\"sideBar.foreground\":\"#403f53\",\"sideBarTitle.foreground\":\"#403f53\",\"sideBar.border\":\"#f0f0f0\",\"editorGroup.background\":\"#f6f6f6\",\"editorCursor.foreground\":\"#90a7b2\",\"editor.wordHighlightBackground\":\"#339cec33\",\"editor.wordHighlightStrongBackground\":\"#007dd659\",\"editor.lineHighlightBackground\":\"#f0f0f0\",\"editor.rangeHighlightBackground\":\"#7497a633\",\"editorWhitespace.foreground\":\"#d9d9d9\",\"editorIndentGuide.background\":\"#d9d9d9\",\"editorCodeLens.foreground\":\"#403f53\",\"editorBracketMatch.background\":\"#d3e8f8\",\"editorBracketMatch.border\":\"#2aa298\",\"editorError.border\":\"#fbfbfb\",\"editorWarning.border\":\"#daaa01\",\"editorGutter.addedBackground\":\"#49d0c5\",\"editorGutter.modifiedBackground\":\"#6fbef6\",\"editorGutter.deletedBackground\":\"#f76e6e\",\"editorRuler.foreground\":\"#d9d9d9\",\"editorOverviewRuler.errorForeground\":\"#e64d49\",\"editorOverviewRuler.warningForeground\":\"#daaa01\",\"editorSuggestWidget.background\":\"#f0f0f0\",\"editorSuggestWidget.foreground\":\"#403f53\",\"editorSuggestWidget.highlightForeground\":\"#403f53\",\"editorSuggestWidget.selectedBackground\":\"#d3e8f8\",\"editorSuggestWidget.border\":\"#d9d9d9\",\"debugExceptionWidget.background\":\"#f0f0f0\",\"debugExceptionWidget.border\":\"#d9d9d9\",\"editorMarkerNavigation.background\":\"#d0d0d0\",\"editorMarkerNavigationError.background\":\"#f76e6e\",\"editorMarkerNavigationWarning.background\":\"#daaa01\",\"debugToolBar.background\":\"#f0f0f0\",\"extensionButton.prominentBackground\":\"#2aa298\",\"extensionButton.prominentForeground\":\"#f0f0f0\",\"statusBar.background\":\"#f0f0f0\",\"statusBar.border\":\"#f0f0f0\",\"statusBar.debuggingBackground\":\"#f0f0f0\",\"statusBar.debuggingForeground\":\"#403f53\",\"statusBar.foreground\":\"#403f53\",\"statusBar.noFolderBackground\":\"#f0f0f0\",\"statusBar.noFolderForeground\":\"#403f53\",\"peekView.border\":\"#d9d9d9\",\"peekViewEditor.background\":\"#f6f6f6\",\"peekViewEditorGutter.background\":\"#f6f6f6\",\"peekViewEditor.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.background\":\"#f0f0f0\",\"peekViewResult.fileForeground\":\"#403f53\",\"peekViewResult.lineForeground\":\"#403f53\",\"peekViewResult.matchHighlightBackground\":\"#49d0c5\",\"peekViewResult.selectionBackground\":\"#e0e7ea\",\"peekViewResult.selectionForeground\":\"#403f53\",\"peekViewTitle.background\":\"#f0f0f0\",\"peekViewTitleLabel.foreground\":\"#403f53\",\"peekViewTitleDescription.foreground\":\"#403f53\",\"terminal.foreground\":\"#403f53\"},\"fg\":\"#403f53\",\"bg\":\"#f6f7f9\",\"semanticHighlighting\":false,\"settings\":[{\"name\":\"Changed\",\"scope\":[\"markup.changed\",\"meta.diff.header.git\",\"meta.diff.header.from-file\",\"meta.diff.header.to-file\"],\"settings\":{\"foreground\":\"#556484\"}},{\"name\":\"Deleted\",\"scope\":[\"markup.deleted.diff\"],\"settings\":{\"foreground\":\"#ae3c3afd\"}},{\"name\":\"Inserted\",\"scope\":[\"markup.inserted.diff\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Global settings\",\"settings\":{\"background\":\"#011627\",\"foreground\":\"#403f53\"}},{\"name\":\"Comment\",\"scope\":[\"comment\"],\"settings\":{\"foreground\":\"#5f636f\"}},{\"name\":\"String\",\"scope\":[\"string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"String Quoted\",\"scope\":[\"string.quoted\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Support Constant Math\",\"scope\":[\"support.constant.math\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Number\",\"scope\":[\"constant.numeric\",\"constant.character.numeric\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Built-in constant\",\"scope\":[\"constant.language\",\"punctuation.definition.constant\",\"variable.other.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"User-defined constant\",\"scope\":[\"constant.character\",\"constant.other\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Constant Character Escape\",\"scope\":[\"constant.character.escape\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"RegExp String\",\"scope\":[\"string.regexp\",\"string.regexp keyword.other\"],\"settings\":{\"foreground\":\"#3a688f\"}},{\"name\":\"Comma in functions\",\"scope\":[\"meta.function punctuation.separator.comma\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Variable\",\"scope\":[\"variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword\",\"scope\":[\"punctuation.accessor\",\"keyword\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage\",\"scope\":[\"storage\",\"meta.var.expr\",\"meta.class meta.method.declaration meta.var.expr storage.type.js\",\"storage.type.property.js\",\"storage.type.property.ts\",\"storage.type.property.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Storage type\",\"scope\":[\"storage.type.function.arrow.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Class name\",\"scope\":[\"entity.name.class\",\"meta.class entity.name.type.class\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Inherited class\",\"scope\":[\"entity.other.inherited-class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Function name\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Meta Tag\",\"scope\":[\"punctuation.definition.tag\",\"meta.tag\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Tag names\",\"scope\":[\"entity.name.tag\",\"meta.tag.other.html\",\"meta.tag.other.js\",\"meta.tag.other.tsx\",\"entity.name.tag.tsx\",\"entity.name.tag.js\",\"entity.name.tag\",\"meta.tag.js\",\"meta.tag.tsx\",\"meta.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Tag attribute\",\"scope\":[\"entity.other.attribute-name\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Entity Name Tag Custom\",\"scope\":[\"entity.name.tag.custom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Library (function & constant)\",\"scope\":[\"support.function\",\"support.constant\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Constant Property Value meta\",\"scope\":[\"support.constant.meta.property-value\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Library class/type\",\"scope\":[\"support.type\",\"support.class\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Support Variable DOM\",\"scope\":[\"support.variable.dom\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid\",\"scope\":[\"invalid\"],\"settings\":{\"foreground\":\"#bb2060\"}},{\"name\":\"Invalid deprecated\",\"scope\":[\"invalid.deprecated\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Keyword Operator\",\"scope\":[\"keyword.operator\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Keyword Operator Relational\",\"scope\":[\"keyword.operator.relational\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Assignment\",\"scope\":[\"keyword.operator.assignment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Arithmetic\",\"scope\":[\"keyword.operator.arithmetic\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Bitwise\",\"scope\":[\"keyword.operator.bitwise\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Increment\",\"scope\":[\"keyword.operator.increment\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Operator Ternary\",\"scope\":[\"keyword.operator.ternary\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Double-Slashed Comment\",\"scope\":[\"comment.line.double-slash\"],\"settings\":{\"foreground\":\"#5d6376\"}},{\"name\":\"Object\",\"scope\":[\"object\"],\"settings\":{\"foreground\":\"#58656a\"}},{\"name\":\"Null\",\"scope\":[\"constant.language.null\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Meta Brace\",\"scope\":[\"meta.brace\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Meta Delimiter Period\",\"scope\":[\"meta.delimiter.period\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition String\",\"scope\":[\"punctuation.definition.string\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuation Definition String Markdown\",\"scope\":[\"punctuation.definition.string.begin.markdown\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Boolean\",\"scope\":[\"constant.language.boolean\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Object Comma\",\"scope\":[\"object.comma\"],\"settings\":{\"foreground\":\"#646464\"}},{\"name\":\"Variable Parameter Function\",\"scope\":[\"variable.parameter.function\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Support Type Property Name & entity name tags\",\"scope\":[\"support.type.vendor.property-name\",\"support.constant.vendor.property-value\",\"support.type.property-name\",\"meta.property-list entity.name.tag\"],\"settings\":{\"foreground\":\"#096e72\",\"fontStyle\":\"\"}},{\"name\":\"Entity Name tag reference in stylesheets\",\"scope\":[\"meta.property-list entity.name.tag.reference\"],\"settings\":{\"foreground\":\"#286d70\"}},{\"name\":\"Constant Other Color RGB Value Punctuation Definition Constant\",\"scope\":[\"constant.other.color.rgb-value punctuation.definition.constant\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Constant Other Color\",\"scope\":[\"constant.other.color\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Keyword Other Unit\",\"scope\":[\"keyword.other.unit\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Selector\",\"scope\":[\"meta.selector\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Entity Other Attribute Name Id\",\"scope\":[\"entity.other.attribute-name.id\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Meta Property Name\",\"scope\":[\"meta.property-name\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Doctypes\",\"scope\":[\"entity.name.tag.doctype\",\"meta.tag.sgml.doctype\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Punctuation Definition Parameters\",\"scope\":[\"punctuation.definition.parameters\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Keyword Control Operator\",\"scope\":[\"keyword.control.operator\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Keyword Operator Logical\",\"scope\":[\"keyword.operator.logical\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Variable Instances\",\"scope\":[\"variable.instance\",\"variable.other.instance\",\"variable.readwrite.instance\",\"variable.other.readwrite.instance\",\"variable.other.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Property Other object property\",\"scope\":[\"variable.other.object.property\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Variable Property Other object\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"fontStyle\":\"\"}},{\"name\":\"Entity Name Function\",\"scope\":[\"entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Keyword Operator Comparison, imports, returns and Keyword Operator Ruby\",\"scope\":[\"keyword.operator.comparison\",\"keyword.control.flow.js\",\"keyword.control.flow.ts\",\"keyword.control.flow.tsx\",\"keyword.control.ruby\",\"keyword.control.module.ruby\",\"keyword.control.class.ruby\",\"keyword.control.def.ruby\",\"keyword.control.loop.js\",\"keyword.control.loop.ts\",\"keyword.control.import.js\",\"keyword.control.import.ts\",\"keyword.control.import.tsx\",\"keyword.control.from.js\",\"keyword.control.from.ts\",\"keyword.control.from.tsx\",\"keyword.operator.instanceof.js\",\"keyword.operator.expression.instanceof.ts\",\"keyword.operator.expression.instanceof.tsx\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Keyword Control Conditional\",\"scope\":[\"keyword.control.conditional.js\",\"keyword.control.conditional.ts\",\"keyword.control.switch.js\",\"keyword.control.switch.ts\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"\"}},{\"name\":\"Support Constant, `new` keyword, Special Method Keyword, `debugger`, other keywords\",\"scope\":[\"support.constant\",\"keyword.other.special-method\",\"keyword.other.new\",\"keyword.other.debugger\",\"keyword.control\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Function\",\"scope\":[\"support.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Invalid Broken\",\"scope\":[\"invalid.broken\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Invalid Unimplemented\",\"scope\":[\"invalid.unimplemented\"],\"settings\":{\"foreground\":\"#486e26\"}},{\"name\":\"Invalid Illegal\",\"scope\":[\"invalid.illegal\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Language Variable\",\"scope\":[\"variable.language\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Support Variable Property\",\"scope\":[\"support.variable.property\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Variable Function\",\"scope\":[\"variable.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variable Interpolation\",\"scope\":[\"variable.interpolation\"],\"settings\":{\"foreground\":\"#a64348\"}},{\"name\":\"Meta Function Call\",\"scope\":[\"meta.function-call\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Punctuation Section Embedded\",\"scope\":[\"punctuation.section.embedded\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Punctuation Tweaks\",\"scope\":[\"punctuation.terminator.expression\",\"punctuation.definition.arguments\",\"punctuation.definition.array\",\"punctuation.section.array\",\"meta.array\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"More Punctuation Tweaks\",\"scope\":[\"punctuation.definition.list.begin\",\"punctuation.definition.list.end\",\"punctuation.separator.arguments\",\"punctuation.definition.list\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Template Strings\",\"scope\":[\"string.template meta.template.expression\"],\"settings\":{\"foreground\":\"#b23834\"}},{\"name\":\"Backtics(``) in Template Strings\",\"scope\":[\"string.template punctuation.definition.string\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Italics\",\"scope\":[\"italic\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Bold\",\"scope\":[\"bold\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Quote\",\"scope\":[\"quote\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Raw Code\",\"scope\":[\"raw\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CoffeScript Variable Assignment\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#186e73\"}},{\"name\":\"CoffeScript Parameter Function\",\"scope\":[\"variable.parameter.function.coffee\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"CoffeeScript Assignments\",\"scope\":[\"variable.assignment.coffee\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C# Readwrite Variables\",\"scope\":[\"variable.other.readwrite.cs\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C# Classes & Storage types\",\"scope\":[\"entity.name.type.class.cs\",\"storage.type.cs\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"C# Namespaces\",\"scope\":[\"entity.name.type.namespace.cs\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Tag names in Stylesheets\",\"scope\":[\"entity.name.tag.css\",\"entity.name.tag.less\",\"entity.name.tag.custom.css\",\"support.constant.property-value.css\"],\"settings\":{\"foreground\":\"#984e4d\",\"fontStyle\":\"\"}},{\"name\":\"Wildcard(*) selector in Stylesheets\",\"scope\":[\"entity.name.tag.wildcard.css\",\"entity.name.tag.wildcard.less\",\"entity.name.tag.wildcard.scss\",\"entity.name.tag.wildcard.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"CSS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Attribute Name for CSS\",\"scope\":[\"meta.attribute-selector.css entity.other.attribute-name.attribute\",\"variable.other.readwrite.js\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Elixir Classes\",\"scope\":[\"source.elixir support.type.elixir\",\"source.elixir meta.module.elixir entity.name.class.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Functions\",\"scope\":[\"source.elixir entity.name.function\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Constants\",\"scope\":[\"source.elixir constant.other.symbol.elixir\",\"source.elixir constant.other.keywords.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir String Punctuations\",\"scope\":[\"source.elixir punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir\",\"scope\":[\"source.elixir variable.other.readwrite.module.elixir\",\"source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Elixir Binary Punctuations\",\"scope\":[\"source.elixir .punctuation.binary.elixir\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Closure Constant Keyword\",\"scope\":[\"constant.keyword.clojure\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Function Calls\",\"scope\":[\"source.go meta.function-call.go\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Go Keywords\",\"scope\":[\"source.go keyword.package.go\",\"source.go keyword.import.go\",\"source.go keyword.function.go\",\"source.go keyword.type.go\",\"source.go keyword.struct.go\",\"source.go keyword.interface.go\",\"source.go keyword.const.go\",\"source.go keyword.var.go\",\"source.go keyword.map.go\",\"source.go keyword.channel.go\",\"source.go keyword.control.go\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"Go Constants e.g. nil, string format (%s, %d, etc.)\",\"scope\":[\"source.go constant.language.go\",\"source.go constant.other.placeholder.go\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Functions\",\"scope\":[\"entity.name.function.preprocessor.cpp\",\"entity.scope.name.cpp\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"C++ Meta Namespace\",\"scope\":[\"meta.namespace-block.cpp\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"C++ Language Primitive Storage\",\"scope\":[\"storage.type.language.primitive.cpp\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"C++ Preprocessor Macro\",\"scope\":[\"meta.preprocessor.macro.cpp\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"C++ Variable Parameter\",\"scope\":[\"variable.parameter\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Powershell Variables\",\"scope\":[\"variable.other.readwrite.powershell\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Powershell Function\",\"scope\":[\"support.function.powershell\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"ID Attribute Name in HTML\",\"scope\":[\"entity.other.attribute-name.id.html\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"HTML Punctuation Definition Tag\",\"scope\":[\"punctuation.definition.tag.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"HTML Doctype\",\"scope\":[\"meta.tag.sgml.doctype.html\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"JavaScript Classes\",\"scope\":[\"meta.class entity.name.type.class.js\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.js\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JavaScript Terminator\",\"scope\":[\"terminator.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Meta Punctuation Definition\",\"scope\":[\"meta.js punctuation.definition.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Entity Names in Code Documentations\",\"scope\":[\"entity.name.type.instance.jsdoc\",\"entity.name.type.instance.phpdoc\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"Other Variables in Code Documentations\",\"scope\":[\"variable.other.jsdoc\",\"variable.other.phpdoc\"],\"settings\":{\"foreground\":\"#3e697c\"}},{\"name\":\"JavaScript module imports and exports\",\"scope\":[\"variable.other.meta.import.js\",\"meta.import.js variable.other\",\"variable.other.meta.export.js\",\"meta.export.js variable.other\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variable Parameter Function\",\"scope\":[\"variable.parameter.function.js\"],\"settings\":{\"foreground\":\"#555ea2\"}},{\"name\":\"JavaScript[React] Variable Other Object\",\"scope\":[\"variable.other.object.js\",\"variable.other.object.jsx\",\"variable.object.property.js\",\"variable.object.property.jsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Variables\",\"scope\":[\"variable.js\",\"variable.other.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JavaScript Entity Name Type\",\"scope\":[\"entity.name.type.js\",\"entity.name.type.module.js\"],\"settings\":{\"foreground\":\"#111111\",\"fontStyle\":\"\"}},{\"name\":\"JavaScript Support Classes\",\"scope\":[\"support.class.js\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"JSON Property Names\",\"scope\":[\"support.type.property-name.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"JSON Support Constants\",\"scope\":[\"support.constant.json\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"JSON Property values (string)\",\"scope\":[\"meta.structure.dictionary.value.json string.quoted.double\"],\"settings\":{\"foreground\":\"#7c5686\"}},{\"name\":\"Strings in JSON values\",\"scope\":[\"string.quoted.double.json punctuation.definition.string.json\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Specific JSON Property values like null\",\"scope\":[\"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"JavaScript Other Variable\",\"scope\":[\"variable.other.object.js\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Variables\",\"scope\":[\"variable.other.ruby\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Ruby Class\",\"scope\":[\"entity.name.type.class.ruby\"],\"settings\":{\"foreground\":\"#984e4d\"}},{\"name\":\"Ruby Hashkeys\",\"scope\":[\"constant.language.symbol.hashkey.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Ruby Symbols\",\"scope\":[\"constant.language.symbol.ruby\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"LESS Tag names\",\"scope\":[\"entity.name.tag.less\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"LESS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.css\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Attribute Name for LESS\",\"scope\":[\"meta.attribute-selector.less entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Markdown Headings\",\"scope\":[\"markup.heading.markdown\",\"markup.heading.setext.1.markdown\",\"markup.heading.setext.2.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Italics\",\"scope\":[\"markup.italic.markdown\"],\"settings\":{\"foreground\":\"#8844ae\",\"fontStyle\":\"italic\"}},{\"name\":\"Markdown Bold\",\"scope\":[\"markup.bold.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\",\"fontStyle\":\"bold\"}},{\"name\":\"Markdown Quote + others\",\"scope\":[\"markup.quote.markdown\"],\"settings\":{\"foreground\":\"#5c6285\"}},{\"name\":\"Markdown Raw Code + others\",\"scope\":[\"markup.inline.raw.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown Links\",\"scope\":[\"markup.underline.link.markdown\",\"markup.underline.link.image.markdown\"],\"settings\":{\"foreground\":\"#954f5a\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Link Title and Description\",\"scope\":[\"string.other.link.title.markdown\",\"string.other.link.description.markdown\"],\"settings\":{\"foreground\":\"#403f53\",\"fontStyle\":\"underline\"}},{\"name\":\"Markdown Punctuation\",\"scope\":[\"punctuation.definition.string.markdown\",\"punctuation.definition.string.begin.markdown\",\"punctuation.definition.string.end.markdown\",\"meta.link.inline.markdown punctuation.definition.string\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown MetaData Punctuation\",\"scope\":[\"punctuation.definition.metadata.markdown\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Markdown List Punctuation\",\"scope\":[\"beginning.punctuation.definition.list.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Markdown Inline Raw String\",\"scope\":[\"markup.inline.raw.string.markdown\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"PHP Variables\",\"scope\":[\"variable.other.php\",\"variable.other.property.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Support Classes in PHP\",\"scope\":[\"support.class.php\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Punctuations in PHP function calls\",\"scope\":[\"meta.function-call.php punctuation\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"PHP Global Variables\",\"scope\":[\"variable.other.global.php\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Declaration Punctuation in PHP Global Variables\",\"scope\":[\"variable.other.global.php punctuation.definition.variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Language Constants in Python\",\"scope\":[\"constant.language.python\"],\"settings\":{\"foreground\":\"#a24848\"}},{\"name\":\"Python Function Parameter and Arguments\",\"scope\":[\"variable.parameter.function.python\",\"meta.function-call.arguments.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Function Call\",\"scope\":[\"meta.function-call.python\",\"meta.function-call.generic.python\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"Punctuations in Python\",\"scope\":[\"punctuation.python\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Decorator Functions in Python\",\"scope\":[\"entity.name.function.decorator.python\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Python Language Variable\",\"scope\":[\"source.python variable.language.special\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Python import control keyword\",\"scope\":[\"keyword.control\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"SCSS Variable\",\"scope\":[\"variable.scss\",\"variable.sass\",\"variable.parameter.url.scss\",\"variable.parameter.url.sass\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"Variables in SASS At-Rules\",\"scope\":[\"source.css.scss meta.at-rule variable\",\"source.css.sass meta.at-rule variable\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"Attribute Name for SASS\",\"scope\":[\"meta.attribute-selector.scss entity.other.attribute-name.attribute\",\"meta.attribute-selector.sass entity.other.attribute-name.attribute\"],\"settings\":{\"foreground\":\"#aa0982\"}},{\"name\":\"Tag names in SASS\",\"scope\":[\"entity.name.tag.scss\",\"entity.name.tag.sass\"],\"settings\":{\"foreground\":\"#096e72\"}},{\"name\":\"SASS Keyword Other Unit\",\"scope\":[\"keyword.other.unit.scss\",\"keyword.other.unit.sass\"],\"settings\":{\"foreground\":\"#8844ae\"}},{\"name\":\"TypeScript[React] Variables and Object Properties\",\"scope\":[\"variable.other.readwrite.alias.ts\",\"variable.other.readwrite.alias.tsx\",\"variable.other.readwrite.ts\",\"variable.other.readwrite.tsx\",\"variable.other.object.ts\",\"variable.other.object.tsx\",\"variable.object.property.ts\",\"variable.object.property.tsx\",\"variable.other.ts\",\"variable.other.tsx\",\"variable.tsx\",\"variable.ts\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Entity Name Types\",\"scope\":[\"entity.name.type.ts\",\"entity.name.type.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript[React] Node Classes\",\"scope\":[\"support.class.node.ts\",\"support.class.node.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Entity Name Types as Parameters\",\"scope\":[\"meta.type.parameters.ts entity.name.type\",\"meta.type.parameters.tsx entity.name.type\"],\"settings\":{\"foreground\":\"#4d667b\"}},{\"name\":\"TypeScript[React] Import/Export Punctuations\",\"scope\":[\"meta.import.ts punctuation.definition.block\",\"meta.import.tsx punctuation.definition.block\",\"meta.export.ts punctuation.definition.block\",\"meta.export.tsx punctuation.definition.block\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.decorator punctuation.decorator.ts\",\"meta.decorator punctuation.decorator.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"TypeScript[React] Punctuation Decorators\",\"scope\":[\"meta.tag.js meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"YAML Entity Name Tags\",\"scope\":[\"entity.name.tag.yaml\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"JavaScript Variable Other ReadWrite\",\"scope\":[\"variable.other.readwrite.js\",\"variable.parameter\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"Support Class Component\",\"scope\":[\"support.class.component.js\",\"support.class.component.tsx\"],\"settings\":{\"foreground\":\"#aa0982\",\"fontStyle\":\"\"}},{\"name\":\"Text nested in React tags\",\"scope\":[\"meta.jsx.children\",\"meta.jsx.children.js\",\"meta.jsx.children.tsx\"],\"settings\":{\"foreground\":\"#403f53\"}},{\"name\":\"TypeScript Classes\",\"scope\":[\"meta.class entity.name.type.class.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Entity Name Type\",\"scope\":[\"entity.name.type.tsx\",\"entity.name.type.module.tsx\"],\"settings\":{\"foreground\":\"#111111\"}},{\"name\":\"TypeScript Class Variable Keyword\",\"scope\":[\"meta.class.ts meta.var.expr.ts storage.type.ts\",\"meta.class.tsx meta.var.expr.tsx storage.type.tsx\"],\"settings\":{\"foreground\":\"#76578b\"}},{\"name\":\"TypeScript Method Declaration e.g. `constructor`\",\"scope\":[\"meta.method.declaration storage.type.ts\",\"meta.method.declaration storage.type.tsx\"],\"settings\":{\"foreground\":\"#3b61b0\"}},{\"name\":\"normalize font style of certain components\",\"scope\":[\"meta.property-list.css meta.property-value.css variable.other.less\",\"meta.property-list.scss variable.scss\",\"meta.property-list.sass variable.sass\",\"meta.brace\",\"keyword.operator.operator\",\"keyword.operator.or.regexp\",\"keyword.operator.expression.in\",\"keyword.operator.relational\",\"keyword.operator.assignment\",\"keyword.operator.comparison\",\"keyword.operator.type\",\"keyword.operator\",\"keyword\",\"punctuation.definintion.string\",\"punctuation\",\"variable.other.readwrite.js\",\"storage.type\",\"source.css\",\"string.quoted\"],\"settings\":{\"fontStyle\":\"\"}}],\"styleOverrides\":{\"frames\":{\"editorBackground\":\"var(--sl-color-gray-7)\",\"terminalBackground\":\"var(--sl-color-gray-7)\",\"editorActiveTabBackground\":\"var(--sl-color-gray-7)\",\"terminalTitlebarDotsForeground\":\"color-mix(in srgb, var(--sl-color-gray-5), transparent 25%)\",\"terminalTitlebarDotsOpacity\":\"0.75\",\"inlineButtonForeground\":\"var(--sl-color-text)\",\"frameBoxShadowCssValue\":\"none\"},\"textMarkers\":{\"markBackground\":\"#0000001a\",\"markBorderColor\":\"#00000055\"}}}],\"defaultLocale\":\"en\",\"cascadeLayer\":\"starlight.components\",\"styleOverrides\":{\"borderRadius\":\"0px\",\"borderWidth\":\"1px\",\"codePaddingBlock\":\"0.75rem\",\"codePaddingInline\":\"1rem\",\"codeFontFamily\":\"var(--__sl-font-mono)\",\"codeFontSize\":\"var(--sl-text-code)\",\"codeLineHeight\":\"var(--sl-line-height)\",\"uiFontFamily\":\"var(--__sl-font)\",\"textMarkers\":{\"lineDiffIndicatorMarginLeft\":\"0.25rem\",\"defaultChroma\":\"45\",\"backgroundOpacity\":\"60%\"}},\"plugins\":[{\"name\":\"Starlight Plugin\",\"hooks\":{}},{\"name\":\"astro-expressive-code\",\"hooks\":{}}]}]],\"remarkRehype\":{},\"gfm\":true,\"smartypants\":true},\"security\":{\"checkOrigin\":true,\"allowedDomains\":[],\"actionBodySizeLimit\":1048576},\"env\":{\"schema\":{},\"validateSecrets\":false},\"experimental\":{\"clientPrerender\":false,\"contentIntellisense\":false,\"headingIdCompat\":false,\"preserveScriptOrder\":false,\"liveContentCollections\":false,\"csp\":false,\"staticImportMetaEnv\":false,\"chromeDevtoolsWorkspace\":false,\"failOnPrerenderConflict\":false,\"svgo\":false},\"legacy\":{\"collections\":false},\"prefetch\":{\"prefetchAll\":true},\"i18n\":{\"defaultLocale\":\"en\",\"locales\":[\"en\"],\"routing\":{\"prefixDefaultLocale\":false,\"redirectToDefaultLocale\":false,\"fallbackType\":\"redirect\"}}}", + "docs", + [ + "Map", + 11, + 12, + 55, + 56, + 157, + 158, + 233, + 234, + 283, + 284, + 324, + 325, + 429, + 430, + 473, + 474, + 586, + 587, + 731, + 732, + 771, + 772, + 831, + 832, + 884, + 885, + 948, + 949, + 1022, + 1023, + 1067, + 1068, + 1111, + 1112, + 1284, + 1285, + 1456, + 1457, + 1610, + 1611, + 1861, + 1862, + 1903, + 1904, + 1971, + 1972, + 2020, + 2021, + 2089, + 2090, + 2132, + 2133, + 2166, + 2167, + 2192, + 2193, + 2218, + 2219, + 2244, + 2245, + 2270, + 2271, + 2321, + 2322, + 2410, + 2411, + 2462, + 2463, + 2490, + 2491, + 2546, + 2547, + 2576, + 2577, + 2619, + 2620, + 2655, + 2656, + 2691, + 2692, + 2746, + 2747, + 2887, + 2888, + 2951, + 2952, + 2986, + 2987, + 3035, + 3036, + 3125, + 3126, + 3155, + 3156, + 3239, + 3240, + 3342, + 3343, + 3479, + 3480, + 3581, + 3582, + 3654, + 3655, + 3745, + 3746, + 3894, + 3895, + 3963, + 3964, + 4052, + 4053, + 4110, + 4111, + 4172, + 4173, + 4230, + 4231, + 4287, + 4288, + 4348, + 4349, + 4417, + 4418, + 4507, + 4508, + 4555, + 4556, + 4624, + 4625, + 4661, + 4662, + 4704, + 4705, + 4743, + 4744, + 4782, + 4783, + 4815, + 4816, + 4855, + 4856, + 4901, + 4902, + 4942, + 4943, + 4969, + 4970, + 4996, + 4997, + 5023, + 5024, + 5059, + 5060, + 5086, + 5087, + 5143, + 5144, + 5170, + 5171, + 5197, + 5198, + 5224, + 5225, + 5251, + 5252, + 5278, + 5279, + 5305, + 5306, + 5332, + 5333, + 5383, + 5384, + 5470, + 5471, + 5643, + 5644, + 5690, + 5691, + 5730, + 5731, + 5775, + 5776, + 5879, + 5880, + 5915, + 5916, + 5954, + 5955, + 6003, + 6004, + 6052, + 6053, + 6094, + 6095, + 6133, + 6134, + 6199, + 6200, + 6228, + 6229, + 6257, + 6258, + 6295, + 6296, + 6324, + 6325, + 6366, + 6367, + 6416, + 6417, + 6479, + 6480, + 6520, + 6521, + 6567, + 6568, + 6603, + 6604, + 6631, + 6632, + 6696, + 6697, + 6755, + 6756, + 6848, + 6849, + 6910, + 6911, + 6975, + 6976, + 7006, + 7007, + 7040, + 7041, + 7069, + 7070, + 7101, + 7102, + 7143, + 7144, + 7190, + 7191, + 7222, + 7223, + 7276, + 7277, + 7376, + 7377, + 7496, + 7497, + 7589, + 7590, + 7646, + 7647, + 7716, + 7717, + 7827, + 7828, + 7909, + 7910, + 7974, + 7975, + 8103, + 8104, + 8174, + 8175, + 8211, + 8212, + 8254, + 8255, + 8302, + 8303, + 8393, + 8394, + 8508, + 8509, + 8638, + 8639, + 8686, + 8687, + 8739, + 8740, + 8802, + 8803, + 8884, + 8885, + 8920, + 8921, + 8979, + 8980, + 9131, + 9132, + 9185, + 9186, + 9250, + 9251, + 9291, + 9292, + 9377, + 9378, + 9433, + 9434, + 9517, + 9518, + 9569, + 9570, + 9716, + 9717, + 9849, + 9850, + 9922, + 9923, + 9997, + 9998, + 10053, + 10054, + 10171, + 10172, + 10259, + 10260, + 10337, + 10338, + 10429, + 10430, + 10494, + 10495, + 10577, + 10578, + 10629, + 10630, + 10717, + 10718, + 10787, + 10788, + 10836, + 10837, + 10908, + 10909, + 10952, + 10953, + 11000, + 11001, + 11043, + 11044, + 11156, + 11157, + 11236, + 11237, + 11284, + 11285, + 11341, + 11342, + 11449, + 11450, + 11520, + 11521, + 11580, + 11581, + 11649, + 11650, + 11707, + 11708, + 11803, + 11804, + 11862, + 11863, + 11942, + 11943, + 11991, + 11992, + 12040, + 12041, + 12124, + 12125, + 12171, + 12172, + 12242, + 12243, + 12276, + 12277, + 12334, + 12335, + 12366, + 12367, + 12419, + 12420, + 12446, + 12447, + 12525, + 12526, + 12589, + 12590, + 12636, + 12637, + 12673, + 12674, + 12700, + 12701, + 12727, + 12728, + 12754, + 12755, + 12792, + 12793, + 12825, + 12826, + 12852, + 12853, + 12879, + 12880, + 12906, + 12907, + 12939, + 12940, + 12964, + 12965, + 12989, + 12990, + 13014, + 13015, + 13038, + 13039, + 13063, + 13064, + 13192, + 13193, + 13254, + 13255, + 13304, + 13305, + 13345, + 13346, + 13395, + 13396 + ], + "index", + { "id": 11, "data": 13, "body": 22, "filePath": 23, "digest": 24, "rendered": 25 }, + { + "title": 14, + "description": 15, + "editUrl": 16, + "head": 17, + "template": 18, + "sidebar": 19, + "pagefind": 16, + "draft": 20 + }, + "VariScout Documentation", + "Lightweight, offline-first variation analysis for quality professionals", + true, + [], + "doc", + { "hidden": 20, "attrs": 21 }, + false, + {}, + "# VariScout Documentation\n\n**Lightweight, offline-first variation analysis for quality professionals.**\n\nVariScout helps quality engineers, operations managers, and Lean Six Sigma practitioners find and fix the sources of process variation. No backend required - all analysis happens in your browser.\n\n---\n\n## Quick Start\n\n```bash\n# PWA development\npnpm dev\n\n# Azure Team App development\npnpm --filter @variscout/azure-app dev\n```\n\n---\n\n## Core Concepts\n\n- **[Four Lenses](01-vision/four-lenses/index.md)** — Watson's Four Lenses of Process Knowledge: Change, Flow, Failure, Value\n- **[Two Voices](01-vision/two-voices/index.md)** — Understanding control limits (process voice) vs specification limits (customer voice)\n- **[Drill-Down Analysis](03-features/navigation/drill-down.md)** — Progressive stratification to find where variation hides\n- **[Case Studies](04-cases/index.md)** — Real-world examples with data files for learning\n\n---\n\n## The Promise\n\n> **46% of your variation may be hiding in one place. Find it. Fix it. Check it. Continue.**\n\nVariScout is EDA (Exploratory Data Analysis) for process improvement - not statistical verification. The goal is finding WHERE to focus, then applying Lean thinking to understand WHY.\n\n| Academic Statistician | Process Improvement Practitioner |\n| -------------------------------- | -------------------------------- |\n| \"Is this significant at p\u003C0.05?\" | \"Where should I focus?\" |\n| Hypothesis testing | Pattern finding |\n| Statistical correctness | Directional guidance |\n| Analysis as end goal | Analysis as starting point |\n\n---\n\n## Products & Pricing\n\n| Product | Distribution | Pricing | Status |\n| -------------------------------------------- | ----------------- | -------------------------------------------------- | ----------- |\n| [Azure Standard](08-products/azure/index.md) | Azure Marketplace | €99/month (full analysis, local files) | **PRIMARY** |\n| [Azure Team](08-products/azure/index.md) | Azure Marketplace | €299/month (+ Teams, OneDrive, SharePoint, mobile) | **PRIMARY** |\n| [PWA](08-products/pwa/index.md) | Public URL | FREE (forever, training & education) | Production |\n\n---\n\n## Architecture & Design System\n\nVariScout uses a monorepo structure with shared packages:\n\n```\npackages/\n├── core/ # Statistics, parser, types (no React)\n├── charts/ # Visx chart components\n├── hooks/ # Shared React hooks\n├── ui/ # Shared UI components\n└── data/ # Sample datasets\n\napps/\n├── pwa/ # React + Vite PWA\n├── azure/ # Azure Team App\n└── website/ # Astro marketing site\n```\n\nA unified design system covers both PWA and Azure App: theme-aware (dark/light), data-focused colors, consistent semantics across platforms, and WCAG AA accessible.\n\n[Technical documentation](05-technical/index.md) | [Design system](06-design-system/index.md)\n\n---\n\n## Contributing\n\nThis is a private repository. For contribution guidelines, contact the maintainers.\n\n---\n\n_Documentation built with [Starlight](https://starlight.astro.build/)_", + "src/content/docs/index.md", + "1acdf7f07f7b29a5", + { "html": 26, "metadata": 27 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"variscout-documentation\">VariScout Documentation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Lightweight, offline-first variation analysis for quality professionals.\u003C/strong>\u003C/p>\n\u003Cp>VariScout helps quality engineers, operations managers, and Lean Six Sigma practitioners find and fix the sources of process variation. No backend required - all analysis happens in your browser.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"quick-start\">Quick Start\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#quick-start\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Start”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># PWA development\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Azure Team App development\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm devpnpm --filter @variscout/azure-app dev\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-concepts\">Core Concepts\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-concepts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Concepts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>\u003Ca href=\"01-vision/four-lenses/index.md\">Four Lenses\u003C/a>\u003C/strong> — Watson’s Four Lenses of Process Knowledge: Change, Flow, Failure, Value\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ca href=\"01-vision/two-voices/index.md\">Two Voices\u003C/a>\u003C/strong> — Understanding control limits (process voice) vs specification limits (customer voice)\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ca href=\"03-features/navigation/drill-down.md\">Drill-Down Analysis\u003C/a>\u003C/strong> — Progressive stratification to find where variation hides\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ca href=\"04-cases/index.md\">Case Studies\u003C/a>\u003C/strong> — Real-world examples with data files for learning\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-promise\">The Promise\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-promise\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Promise”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>46% of your variation may be hiding in one place. Find it. Fix it. Check it. Continue.\u003C/strong>\u003C/p>\n\u003C/blockquote>\n\u003Cp>VariScout is EDA (Exploratory Data Analysis) for process improvement - not statistical verification. The goal is finding WHERE to focus, then applying Lean thinking to understand WHY.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Academic Statistician\u003C/th>\u003Cth>Process Improvement Practitioner\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Is this significant at p<0.05?\"\u003C/td>\u003Ctd>\"Where should I focus?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hypothesis testing\u003C/td>\u003Ctd>Pattern finding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Statistical correctness\u003C/td>\u003Ctd>Directional guidance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analysis as end goal\u003C/td>\u003Ctd>Analysis as starting point\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"products--pricing\">Products & Pricing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#products--pricing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Products & Pricing”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth>Distribution\u003C/th>\u003Cth>Pricing\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"08-products/azure/index.md\">Azure Standard\u003C/a>\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>€99/month (full analysis, local files)\u003C/td>\u003Ctd>\u003Cstrong>PRIMARY\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"08-products/azure/index.md\">Azure Team\u003C/a>\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>€299/month (+ Teams, OneDrive, SharePoint, mobile)\u003C/td>\u003Ctd>\u003Cstrong>PRIMARY\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"08-products/pwa/index.md\">PWA\u003C/a>\u003C/td>\u003Ctd>Public URL\u003C/td>\u003Ctd>FREE (forever, training & education)\u003C/td>\u003Ctd>Production\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"architecture--design-system\">Architecture & Design System\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#architecture--design-system\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture & Design System”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses a monorepo structure with shared packages:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">packages/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── core/ # Statistics, parser, types (no React)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── charts/ # Visx chart components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── hooks/ # Shared React hooks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── ui/ # Shared UI components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── data/ # Sample datasets\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">apps/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── pwa/ # React + Vite PWA\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── azure/ # Azure Team App\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── website/ # Astro marketing site\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"packages/├── core/ # Statistics, parser, types (no React)├── charts/ # Visx chart components├── hooks/ # Shared React hooks├── ui/ # Shared UI components└── data/ # Sample datasetsapps/├── pwa/ # React + Vite PWA├── azure/ # Azure Team App└── website/ # Astro marketing site\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>A unified design system covers both PWA and Azure App: theme-aware (dark/light), data-focused colors, consistent semantics across platforms, and WCAG AA accessible.\u003C/p>\n\u003Cp>\u003Ca href=\"05-technical/index.md\">Technical documentation\u003C/a> | \u003Ca href=\"06-design-system/index.md\">Design system\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"contributing\">Contributing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#contributing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Contributing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This is a private repository. For contribution guidelines, contact the maintainers.\u003C/p>\n\u003Chr>\n\u003Cp>\u003Cem>Documentation built with \u003Ca href=\"https://starlight.astro.build/\">Starlight\u003C/a>\u003C/em>\u003C/p>", + { + "headings": 28, + "localImagePaths": 51, + "remoteImagePaths": 52, + "frontmatter": 53, + "imagePaths": 54 + }, + [29, 32, 36, 39, 42, 45, 48], + { "depth": 30, "slug": 31, "text": 14 }, + 1, + "variscout-documentation", + { "depth": 33, "slug": 34, "text": 35 }, + 2, + "quick-start", + "Quick Start", + { "depth": 33, "slug": 37, "text": 38 }, + "core-concepts", + "Core Concepts", + { "depth": 33, "slug": 40, "text": 41 }, + "the-promise", + "The Promise", + { "depth": 33, "slug": 43, "text": 44 }, + "products--pricing", + "Products & Pricing", + { "depth": 33, "slug": 46, "text": 47 }, + "architecture--design-system", + "Architecture & Design System", + { "depth": 33, "slug": 49, "text": 50 }, + "contributing", + "Contributing", + [], + [], + { "title": 14, "description": 15 }, + [], + "05-technical/documentation-methodology", + { "id": 55, "data": 57, "body": 63, "filePath": 64, "digest": 65, "rendered": 66 }, + { + "title": 58, + "description": 59, + "editUrl": 16, + "head": 60, + "template": 18, + "sidebar": 61, + "pagefind": 16, + "draft": 20 + }, + "Documentation Methodology", + "How VariScout's 100+ docs are organized — grounded in Diataxis, C4, Docs-as-Code, and the 4-phase analysis journey", + [], + { "hidden": 20, "attrs": 62 }, + {}, + "# Documentation Methodology\n\n```mermaid\nflowchart TB\n subgraph L1[\"Layer 1 — AI Agent Routing\"]\n CLAUDE[\"CLAUDE.md\\ntask-to-doc table\"]\n end\n\n subgraph L2[\"Layer 2 — Visual Maps\"]\n SM[\"system-map.md\"]\n JM[\"analysis-journey-map.md\"]\n PM[\"data-pipeline-map.md\"]\n LM[\"investigation-lifecycle-map.md\"]\n end\n\n subgraph L3[\"Layer 3 — Workflow Docs\"]\n FL[\"Four Lenses\"]\n DD[\"Drill-Down\"]\n QC[\"Quick Check\"]\n DV[\"Deep Dive\"]\n IA[\"Investigation to Action\"]\n end\n\n subgraph L4[\"Layer 4 — Feature Docs\"]\n CH[\"Charts\"]\n DA[\"Data\"]\n NV[\"Navigation\"]\n LN[\"Learning\"]\n end\n\n subgraph L5[\"Layer 5 — Technical Reference\"]\n AR[\"Architecture\"]\n API[\"TypeDoc API\"]\n ADR[\"ADRs\"]\n end\n\n subgraph L6[\"Layer 6 — Product Specs\"]\n PWA[\"PWA\"]\n AZ[\"Azure\"]\n WEB[\"Website\"]\n end\n\n CLAUDE --> L2\n L2 --> L3\n L3 --> L4\n L4 --> L5\n L5 --> L6\n\n style L1 fill:#3b82f6,color:#fff\n style L2 fill:#22c55e,color:#fff\n style L3 fill:#f59e0b,color:#fff\n style L4 fill:#8b5cf6,color:#fff\n```\n\nSix layers, each serving a different reader at a different zoom level. AI agents enter at Layer 1 (CLAUDE.md routing table). Developers enter at Layer 2 (visual maps) or Layer 3 (workflows). Product managers enter at Layer 6 (product specs).\n\n---\n\n## Why Document the Documentation?\n\nVariScout's documentation serves three audiences simultaneously:\n\n1. **AI coding agents** — need structured, cross-linked docs to navigate the codebase. CLAUDE.md's task-to-doc table routes agents to the right file in one hop.\n2. **Human developers** — need visual maps and architecture docs to understand the system. Mermaid diagrams provide sub-60-second comprehension.\n3. **Quality analysts** — need workflow docs that mirror their real analysis journey. The 4-phase model (Frame → Scout → Investigate → Improve) organizes features around how work actually happens.\n\nWith 100+ markdown files across 8 doc sections, a governing methodology prevents drift, duplication, and orphaned docs.\n\n---\n\n## Foundations: Industry Frameworks Applied\n\nVariScout's docs align naturally with three established frameworks. This wasn't retrofitted — the structure emerged from building docs alongside code.\n\n### Diataxis\n\n[Diataxis](https://diataxis.fr/) classifies documentation into four types by purpose. VariScout maps cleanly:\n\n| Diataxis Type | VariScout Section | Examples |\n|---------------|-------------------|----------|\n| **Tutorials** (learning-oriented) | `docs/04-cases/` — case studies with teaching briefs | Coffee extraction, Packaging weight, Hospital Ward |\n| **How-to Guides** (task-oriented) | `docs/03-features/workflows/` — step-by-step analysis protocols | Quick Check, Deep Dive, Drill-Down, Four Lenses |\n| **Reference** (information-oriented) | `docs/05-technical/`, TypeDoc API docs | Architecture, data-flow, api/core/ |\n| **Explanation** (understanding-oriented) | `docs/01-vision/`, `docs/07-decisions/` | Philosophy, Four Lenses theory, ADRs |\n\nThe remaining sections fit naturally: `02-journeys/` (personas informing tutorials), `06-design-system/` (reference), `08-products/` (reference per product).\n\n### C4 Model\n\nThe [C4 Model](https://c4model.com/) provides four zoom levels for architecture diagrams. VariScout implements three explicitly and one via tooling:\n\n| C4 Level | VariScout Implementation | File |\n|----------|------------------------|------|\n| **L1 System Context** | VariScout + Azure AD, OneDrive, Teams, AI Search | [system-map.md](architecture/system-map.md) (Mermaid C4Context) |\n| **L2 Container** | 5 packages + 3 apps + infra with dependency arrows | [system-map.md](architecture/system-map.md) (Mermaid flowchart) |\n| **L3 Component** | Hook dependencies, chart composition, data transforms | [component-patterns.md](architecture/component-patterns.md), [data-flow.md](architecture/data-flow.md) |\n| **L4 Code** | Auto-generated API reference for @variscout/core | [api/core/](api/core/) (TypeDoc) |\n\n### Docs-as-Code\n\n[Docs-as-Code](https://www.writethedocs.org/guide/docs-as-code/) principles treat documentation with the same rigor as source code:\n\n| Principle | VariScout Practice |\n|-----------|-------------------|\n| Markdown source in Git | All 100+ docs in `docs/` directory, same repo as code |\n| Version controlled | Documentation changes in the same PRs as code changes |\n| Automated builds | Starlight (`pnpm docs:build`) for static site generation |\n| Generated API docs | TypeDoc for `@variscout/core` (`pnpm --filter @variscout/core docs`) |\n| Review in PRs | Documentation reviewed alongside code in every PR |\n| Linting rules | `.claude/rules/documentation.md` enforces structure |\n\n---\n\n## The Journey Spine\n\nVariScout's unique contribution to its documentation model: **every doc is organized around a 4-phase analysis journey**.\n\n```mermaid\nflowchart LR\n F[\"FRAME\\nDefine problem\"] --> S[\"SCOUT\\nDiscover patterns\"]\n S --> I[\"INVESTIGATE\\nFind root causes\"]\n I --> IM[\"IMPROVE\\nVerify fixes\"]\n IM -- \"PDCA loop\" --> F\n\n style F fill:#3b82f6,color:#fff\n style S fill:#22c55e,color:#fff\n style I fill:#f59e0b,color:#fff\n style IM fill:#8b5cf6,color:#fff\n```\n\nEach phase maps to specific UI screens, data shapes, code modules, and CoScout behaviors. The full journey model is documented in [analysis-journey-map.md](../03-features/workflows/analysis-journey-map.md).\n\n### Journey Phase Tags\n\nAll workflow and feature docs include a `journey-phase:` tag — either in YAML frontmatter or as an HTML comment:\n\n```markdown\n\u003C!-- journey-phase: scout -->\n```\n\nValid phases: `frame`, `scout`, `investigate`, `improve`, `[all]`.\n\nThese tags enable AI agents and developers to discover docs by the phase of analysis they support. Combined with CLAUDE.md's task-to-doc routing table, an AI agent can resolve \"how does drill-down work?\" → `journey-phase: scout` → `drill-down-workflow.md` in one hop.\n\n### Decision Point Map\n\nThe journey defines 12 key branching points where the analyst makes a decision. Each has a clear question, evidence source, and branching outcome. See the [Decision Point Map](../03-features/workflows/analysis-journey-map.md#decision-point-map) for the full table.\n\nThese decision points serve double duty:\n- **For analysts**: they guide the investigation workflow\n- **For CoScout**: they define where AI suggestions are most valuable\n\n---\n\n## Documentation Layers\n\nEach layer serves a different reader at a different zoom level:\n\n| Layer | Content | Primary Reader | Entry Point |\n|-------|---------|---------------|-------------|\n| **1. AI Agent Routing** | CLAUDE.md task-to-doc table | AI coding agents | Task description → file path |\n| **2. Visual Maps** | system-map, journey-map, pipeline-map, lifecycle-map | Developers needing overview | Mermaid diagrams |\n| **3. Workflow Docs** | Four Lenses, Drill-Down, Quick Check, Deep Dive | Quality analysts + developers | Step-by-step protocols |\n| **4. Feature Docs** | Charts, data input, navigation, learning | Developers building features | Component specs |\n| **5. Technical Reference** | Architecture, TypeDoc API, ADRs | Developers + architects | API signatures, decisions |\n| **6. Product Specs** | PWA, Azure, Website | Product managers + developers | Platform-specific details |\n\nA developer investigating a bug starts at Layer 1 (CLAUDE.md routes to the right file). A new team member starts at Layer 2 (visual maps for orientation). A quality analyst learning the tool starts at Layer 3 (workflow docs mirror their real work).\n\n---\n\n## Documentation as CoScout's Foundation\n\nThe documentation methodology directly powers CoScout, the AI companion. Structured docs become structured AI behavior.\n\n### The Documentation-to-AI Pipeline\n\n```mermaid\nflowchart LR\n subgraph Docs[\"Documentation\"]\n VIS[\"docs/01-vision/\\nFour Lenses, Two Voices\"]\n WF[\"docs/03-features/workflows/\\nanalysis-journey-map\"]\n ARCH[\"docs/05-technical/architecture/\\ndata-pipeline-map\"]\n CASES[\"docs/04-cases/\\nCase studies\"]\n end\n\n subgraph Model[\"Knowledge Model\"]\n CON[\"concepts.ts\\n~15 methodology concepts\"]\n PHASE[\"Journey Phase Model\\nIDEOI phases\"]\n CTX[\"AIContext type\\nStructured analysis state\"]\n SAMP[\"@variscout/data\\nTeaching scenarios\"]\n end\n\n subgraph CoScout[\"CoScout Behavior\"]\n SYS[\"buildGlossaryPrompt()\\nSystem prompt\"]\n DET[\"detectInvestigationPhase()\\nPhase-adaptive prompts\"]\n BUILD[\"buildAIContext()\\nContext assembly\"]\n SQ[\"suggestedQuestions.ts\\nContext-aware prompts\"]\n end\n\n VIS --> CON --> SYS\n WF --> PHASE --> DET\n ARCH --> CTX --> BUILD\n CASES --> SAMP --> SQ\n```\n\n### How Each Layer Feeds CoScout\n\n| Doc Layer | CoScout Feature | Mechanism |\n|-----------|----------------|-----------|\n| Vision docs (Four Lenses, Two Voices) | Methodology grounding | `concepts.ts` → `buildGlossaryPrompt()` in system prompt |\n| Journey Map (Frame/Scout/Investigate/Improve) | Phase-adaptive prompts | `detectInvestigationPhase()` → `getCoScoutPhase()` |\n| Investigation Lifecycle (IDEOI states) | Hypothesis suggestions | `suggestedQuestions.ts` adapts per IDEOI state |\n| Data Pipeline Map (TypeScript interfaces) | Context assembly | `buildAIContext()` produces `AIContext` from analysis state |\n| Case studies | Teaching examples | Sample datasets inform suggested questions |\n| Glossary terms | Terminology alignment | ~41 terms in system prompt via Azure prompt caching |\n\n### Practical Implications\n\nWhen documentation is structured around the journey model, CoScout inherits that structure automatically:\n\n- Updating `analysis-journey-map.md` should trigger review of `suggestedQuestions.ts`\n- New concepts in `docs/01-vision/` should be added to `concepts.ts`\n- New workflow docs tagged with `journey-phase:` become candidates for CoScout prompt context\n- The documentation IS the spec for CoScout's behavior\n\n---\n\n## Documentation as Navigation and UX Spec\n\nThe journey model serves double duty: it documents the analysis workflow AND specifies the navigation/UX design.\n\n### Journey Phases = Navigation States\n\n```\nFRAME → HomeScreen / PasteScreen / ColumnMapping\nSCOUT → Dashboard (Four Lenses tabs, filter chips, drill-down)\nINVESTIGATE → FindingsPanel + Board view + hypothesis forms\nIMPROVE → WhatIfSimulator + ActionItems + StagedAnalysis\n```\n\n### Tier-Progressive UX\n\nThe same 4-phase journey applies to all tiers, with features progressively unlocked:\n\n| Journey Phase | PWA (Free) | Azure Standard | Azure Team |\n|---------------|-----------|---------------|------------|\n| **FRAME** | Paste only, 3 factors, 50K rows | + File upload, 6 factors, 100K rows | + OneDrive sync |\n| **SCOUT** | Four Lenses + drill-down | Same + more factors | + NarrativeBar, ChartInsightChips |\n| **INVESTIGATE** | 3 statuses, no photos | Same | + 5 statuses, photo evidence, CoScout |\n| **IMPROVE** | What-If only | Same | + Action tracking, staged verification, outcomes |\n\nThis table is the master spec for:\n- Which components render at each phase per tier\n- Where `UpgradePrompt` appears (at the feature boundary)\n- What CoScout can suggest at each phase\n- Which navigation paths exist\n\n### With and Without AI\n\n**Without AI (PWA / Azure Standard):**\n- The journey is fully manual — the analyst reads charts, makes decisions, pins findings\n- Navigation follows the Four Lenses sequence (I-Chart → Boxplot → Pareto → Capability)\n- All decision points in the Decision Point Map are human-driven\n\n**With AI (Azure Team):**\n- CoScout adds a second entry path: hypothesis-driven (AI suggests → confirm → jump to Investigate)\n- NarrativeBar provides passive guidance at each phase\n- ChartInsightChips highlight actionable patterns on charts\n\n**With Teams (Azure Team plan):**\n- Channel tabs = shared navigation context (multiple analysts, same journey)\n- Photo evidence at Investigate phase (Teams camera API)\n- OneDrive sync = persistent journey state across devices\n\n---\n\n## Visual-First Methodology\n\nRules codified in [`.claude/rules/documentation.md`](../../.claude/rules/documentation.md):\n\n| Rule | Purpose |\n|------|---------|\n| **Mermaid diagram first** | Every architecture/workflow doc opens with a diagram. Readers grasp structure in \u003C60 seconds. |\n| **Data boundary interfaces** | Architecture docs show TypeScript interface shapes at module boundaries. |\n| **Mermaid for all new diagrams** | GitHub-native rendering, machine-readable by AI agents. |\n| **Journey phase tags** | All workflow/feature docs tagged with analysis phase for discovery. |\n| **Cross-linking required** | New docs added to parent index, CLAUDE.md table, and related See Also sections. |\n| **YAML frontmatter** | Title, description, journey-phase for docs in the journey map. |\n\n---\n\n## Tooling Stack\n\n| Tool | Purpose | Status |\n|------|---------|--------|\n| **Markdown + Git** | Source of truth for all documentation | Active |\n| **Starlight** | Astro-based doc site (`pnpm docs:build`) — Pagefind search, dark/light toggle, Mermaid rendering | Active |\n| **Mermaid** | Diagrams (30+ across docs) — flowchart, sequence, state, C4 | Active |\n| **TypeDoc** | API reference for @variscout/core (`pnpm --filter @variscout/core docs`) | Active |\n| **CLAUDE.md** | AI agent routing layer (task-to-doc table) | Active |\n| **LikeC4** | C4 architecture model (`docs/architecture/likec4/`) — exports to Mermaid via `pnpm docs:c4` | Active |\n| **Storybook** | Interactive component catalog (66 components) | Active |\n\n---\n\n## Roadmap\n\n### Phase B — LikeC4 (Architecture as Code) ✓\n\nSplit [`docs/architecture/likec4/`](../architecture/likec4/) model files define the full system at C4 L1/L2/L3:\n- Source of truth for architecture topology → exports to Mermaid via `pnpm docs:c4`\n- L3 Component views decompose each package into modules\n- `pnpm docs:c4:serve` launches interactive browser; see [component-map.md](architecture/component-map.md)\n\n### Phase C — Storybook (Living Component Docs) ✓\n\nInteractive playground for 52 UI + 14 chart components:\n- Theme toggle (dark/light) + chart mode (technical/executive)\n- 66 stories across all shared packages\n- `pnpm storybook` to launch; see `.storybook/stories/README.md`\n\n### Phase D — ADR Visualization ✓\n\nMermaid dependency graph in [`docs/07-decisions/index.md`](../../07-decisions/index.md):\n- Shows supersedes/extends relationships between 18 ADRs\n- Groups by domain (Architecture, Charts, Storage, Distribution, Features, Teams)\n- ADR-018 (Channel @Mention) added to index and dependency map\n\n---\n\n## ADR Dependency Map\n\n```mermaid\nflowchart TB\n subgraph Architecture[\"Architecture\"]\n ADR001[\"001\\nMonorepo\"]\n ADR004[\"004\\nOffline-First\"]\n ADR011[\"011\\nAI Tooling\"]\n ADR013[\"013\\nDDD/Swarms\"]\n ADR001 --> ADR013\n end\n\n subgraph Charts[\"Charts & UI\"]\n ADR002[\"002\\nVisx Charts\"]\n ADR005[\"005\\nProps-Based\"]\n ADR009[\"009\\nViolin Mode\"]\n ADR017[\"017\\nFluent 2\"]\n ADR002 --> ADR005\n ADR005 --> ADR009\n end\n\n subgraph Storage[\"Storage\"]\n ADR003[\"003\\nIndexedDB\"]\n ADR012[\"012\\nPWA Browser-Only\"]\n ADR003 --> ADR004\n ADR004 --> ADR012\n end\n\n subgraph Distribution[\"Distribution\"]\n ADR006[\"006\\nEdition System\"]\n ADR007[\"007\\nAzure Marketplace\"]\n ADR008[\"008\\nWebsite Architecture\"]\n ADR006 -.->|superseded| ADR007\n end\n\n subgraph Features[\"Features\"]\n ADR010[\"010\\nGage R&R\"]\n ADR014[\"014\\nRegression Deferral\"]\n ADR015[\"015\\nInvestigation Board\"]\n end\n\n subgraph Teams[\"Teams Platform\"]\n ADR016[\"016\\nTeams Integration\"]\n ADR018[\"018\\nChannel @Mention\"]\n ADR007 --> ADR016\n ADR015 --> ADR016\n ADR016 --> ADR018\n ADR015 --> ADR018\n end\n\n style ADR006 fill:#94a3b8,color:#fff\n style ADR010 fill:#94a3b8,color:#fff\n```\n\n---\n\n## Sources and References\n\n- [Diataxis](https://diataxis.fr/) — A systematic approach to technical documentation authoring\n- [C4 Model](https://c4model.com/) — Software architecture diagrams at four zoom levels\n- [Docs-as-Code (Write the Docs)](https://www.writethedocs.org/guide/docs-as-code/) — Treat documentation with the same tools as code\n- [LikeC4](https://likec4.dev/) — Architecture models as code (npm-native, Mermaid export)\n- [Storybook](https://storybook.js.org/docs/writing-docs) — Interactive component documentation\n\n---\n\n## See Also\n\n- [Analysis Journey Map](../03-features/workflows/analysis-journey-map.md) — the 4-phase journey model\n- [System Map](architecture/system-map.md) — C4 L1/L2 architecture diagrams\n- [Data Pipeline Map](architecture/data-pipeline-map.md) — end-to-end data flow with TypeScript boundaries\n- [Investigation Lifecycle Map](../03-features/workflows/investigation-lifecycle-map.md) — IDEOI state machine\n- [Documentation Rules](../../.claude/rules/documentation.md) — enforced rules for doc structure", + "src/content/docs/05-technical/documentation-methodology.md", + "f22e9c8066d8690a", + { "html": 67, "metadata": 68 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"documentation-methodology\">Documentation Methodology\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#documentation-methodology\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Documentation Methodology”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph L1[\"Layer 1 — AI Agent Routing\"]\n CLAUDE[\"CLAUDE.md\\ntask-to-doc table\"]\n end\n\n subgraph L2[\"Layer 2 — Visual Maps\"]\n SM[\"system-map.md\"]\n JM[\"analysis-journey-map.md\"]\n PM[\"data-pipeline-map.md\"]\n LM[\"investigation-lifecycle-map.md\"]\n end\n\n subgraph L3[\"Layer 3 — Workflow Docs\"]\n FL[\"Four Lenses\"]\n DD[\"Drill-Down\"]\n QC[\"Quick Check\"]\n DV[\"Deep Dive\"]\n IA[\"Investigation to Action\"]\n end\n\n subgraph L4[\"Layer 4 — Feature Docs\"]\n CH[\"Charts\"]\n DA[\"Data\"]\n NV[\"Navigation\"]\n LN[\"Learning\"]\n end\n\n subgraph L5[\"Layer 5 — Technical Reference\"]\n AR[\"Architecture\"]\n API[\"TypeDoc API\"]\n ADR[\"ADRs\"]\n end\n\n subgraph L6[\"Layer 6 — Product Specs\"]\n PWA[\"PWA\"]\n AZ[\"Azure\"]\n WEB[\"Website\"]\n end\n\n CLAUDE --> L2\n L2 --> L3\n L3 --> L4\n L4 --> L5\n L5 --> L6\n\n style L1 fill:#3b82f6,color:#fff\n style L2 fill:#22c55e,color:#fff\n style L3 fill:#f59e0b,color:#fff\n style L4 fill:#8b5cf6,color:#fff\n\u003C/pre>\n\u003Cp>Six layers, each serving a different reader at a different zoom level. AI agents enter at Layer 1 (CLAUDE.md routing table). Developers enter at Layer 2 (visual maps) or Layer 3 (workflows). Product managers enter at Layer 6 (product specs).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-document-the-documentation\">Why Document the Documentation?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-document-the-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Document the Documentation?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s documentation serves three audiences simultaneously:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>AI coding agents\u003C/strong> — need structured, cross-linked docs to navigate the codebase. CLAUDE.md’s task-to-doc table routes agents to the right file in one hop.\u003C/li>\n\u003Cli>\u003Cstrong>Human developers\u003C/strong> — need visual maps and architecture docs to understand the system. Mermaid diagrams provide sub-60-second comprehension.\u003C/li>\n\u003Cli>\u003Cstrong>Quality analysts\u003C/strong> — need workflow docs that mirror their real analysis journey. The 4-phase model (Frame → Scout → Investigate → Improve) organizes features around how work actually happens.\u003C/li>\n\u003C/ol>\n\u003Cp>With 100+ markdown files across 8 doc sections, a governing methodology prevents drift, duplication, and orphaned docs.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"foundations-industry-frameworks-applied\">Foundations: Industry Frameworks Applied\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#foundations-industry-frameworks-applied\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Foundations: Industry Frameworks Applied”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s docs align naturally with three established frameworks. This wasn’t retrofitted — the structure emerged from building docs alongside code.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"diataxis\">Diataxis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#diataxis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Diataxis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ca href=\"https://diataxis.fr/\">Diataxis\u003C/a> classifies documentation into four types by purpose. VariScout maps cleanly:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Diataxis Type\u003C/th>\u003Cth>VariScout Section\u003C/th>\u003Cth>Examples\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Tutorials\u003C/strong> (learning-oriented)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">docs/04-cases/\u003C/code> — case studies with teaching briefs\u003C/td>\u003Ctd>Coffee extraction, Packaging weight, Hospital Ward\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>How-to Guides\u003C/strong> (task-oriented)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">docs/03-features/workflows/\u003C/code> — step-by-step analysis protocols\u003C/td>\u003Ctd>Quick Check, Deep Dive, Drill-Down, Four Lenses\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Reference\u003C/strong> (information-oriented)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">docs/05-technical/\u003C/code>, TypeDoc API docs\u003C/td>\u003Ctd>Architecture, data-flow, api/core/\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Explanation\u003C/strong> (understanding-oriented)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">docs/01-vision/\u003C/code>, \u003Ccode dir=\"auto\">docs/07-decisions/\u003C/code>\u003C/td>\u003Ctd>Philosophy, Four Lenses theory, ADRs\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The remaining sections fit naturally: \u003Ccode dir=\"auto\">02-journeys/\u003C/code> (personas informing tutorials), \u003Ccode dir=\"auto\">06-design-system/\u003C/code> (reference), \u003Ccode dir=\"auto\">08-products/\u003C/code> (reference per product).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"c4-model\">C4 Model\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#c4-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “C4 Model”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ca href=\"https://c4model.com/\">C4 Model\u003C/a> provides four zoom levels for architecture diagrams. VariScout implements three explicitly and one via tooling:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>C4 Level\u003C/th>\u003Cth>VariScout Implementation\u003C/th>\u003Cth>File\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>L1 System Context\u003C/strong>\u003C/td>\u003Ctd>VariScout + Azure AD, OneDrive, Teams, AI Search\u003C/td>\u003Ctd>\u003Ca href=\"architecture/system-map.md\">system-map.md\u003C/a> (Mermaid C4Context)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>L2 Container\u003C/strong>\u003C/td>\u003Ctd>5 packages + 3 apps + infra with dependency arrows\u003C/td>\u003Ctd>\u003Ca href=\"architecture/system-map.md\">system-map.md\u003C/a> (Mermaid flowchart)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>L3 Component\u003C/strong>\u003C/td>\u003Ctd>Hook dependencies, chart composition, data transforms\u003C/td>\u003Ctd>\u003Ca href=\"architecture/component-patterns.md\">component-patterns.md\u003C/a>, \u003Ca href=\"architecture/data-flow.md\">data-flow.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>L4 Code\u003C/strong>\u003C/td>\u003Ctd>Auto-generated API reference for @variscout/core\u003C/td>\u003Ctd>\u003Ca href=\"api/core/\">api/core/\u003C/a> (TypeDoc)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"docs-as-code\">Docs-as-Code\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#docs-as-code\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Docs-as-Code”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ca href=\"https://www.writethedocs.org/guide/docs-as-code/\">Docs-as-Code\u003C/a> principles treat documentation with the same rigor as source code:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Principle\u003C/th>\u003Cth>VariScout Practice\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Markdown source in Git\u003C/td>\u003Ctd>All 100+ docs in \u003Ccode dir=\"auto\">docs/\u003C/code> directory, same repo as code\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Version controlled\u003C/td>\u003Ctd>Documentation changes in the same PRs as code changes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Automated builds\u003C/td>\u003Ctd>Starlight (\u003Ccode dir=\"auto\">pnpm docs:build\u003C/code>) for static site generation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Generated API docs\u003C/td>\u003Ctd>TypeDoc for \u003Ccode dir=\"auto\">@variscout/core\u003C/code> (\u003Ccode dir=\"auto\">pnpm --filter @variscout/core docs\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Review in PRs\u003C/td>\u003Ctd>Documentation reviewed alongside code in every PR\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Linting rules\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">.claude/rules/documentation.md\u003C/code> enforces structure\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-journey-spine\">The Journey Spine\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-journey-spine\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Journey Spine”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s unique contribution to its documentation model: \u003Cstrong>every doc is organized around a 4-phase analysis journey\u003C/strong>.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n F[\"FRAME\\nDefine problem\"] --> S[\"SCOUT\\nDiscover patterns\"]\n S --> I[\"INVESTIGATE\\nFind root causes\"]\n I --> IM[\"IMPROVE\\nVerify fixes\"]\n IM -- \"PDCA loop\" --> F\n\n style F fill:#3b82f6,color:#fff\n style S fill:#22c55e,color:#fff\n style I fill:#f59e0b,color:#fff\n style IM fill:#8b5cf6,color:#fff\n\u003C/pre>\n\u003Cp>Each phase maps to specific UI screens, data shapes, code modules, and CoScout behaviors. The full journey model is documented in \u003Ca href=\"../03-features/workflows/analysis-journey-map.md\">analysis-journey-map.md\u003C/a>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"journey-phase-tags\">Journey Phase Tags\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#journey-phase-tags\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Phase Tags”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All workflow and feature docs include a \u003Ccode dir=\"auto\">journey-phase:\u003C/code> tag — either in YAML frontmatter or as an HTML comment:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"markdown\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"><!-- journey-phase: scout -->\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003C!-- journey-phase: scout -->\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Valid phases: \u003Ccode dir=\"auto\">frame\u003C/code>, \u003Ccode dir=\"auto\">scout\u003C/code>, \u003Ccode dir=\"auto\">investigate\u003C/code>, \u003Ccode dir=\"auto\">improve\u003C/code>, \u003Ccode dir=\"auto\">[all]\u003C/code>.\u003C/p>\n\u003Cp>These tags enable AI agents and developers to discover docs by the phase of analysis they support. Combined with CLAUDE.md’s task-to-doc routing table, an AI agent can resolve “how does drill-down work?” → \u003Ccode dir=\"auto\">journey-phase: scout\u003C/code> → \u003Ccode dir=\"auto\">drill-down-workflow.md\u003C/code> in one hop.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"decision-point-map\">Decision Point Map\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#decision-point-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision Point Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The journey defines 12 key branching points where the analyst makes a decision. Each has a clear question, evidence source, and branching outcome. See the \u003Ca href=\"../03-features/workflows/analysis-journey-map.md#decision-point-map\">Decision Point Map\u003C/a> for the full table.\u003C/p>\n\u003Cp>These decision points serve double duty:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>For analysts\u003C/strong>: they guide the investigation workflow\u003C/li>\n\u003Cli>\u003Cstrong>For CoScout\u003C/strong>: they define where AI suggestions are most valuable\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"documentation-layers\">Documentation Layers\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#documentation-layers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Documentation Layers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each layer serves a different reader at a different zoom level:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Layer\u003C/th>\u003Cth>Content\u003C/th>\u003Cth>Primary Reader\u003C/th>\u003Cth>Entry Point\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>1. AI Agent Routing\u003C/strong>\u003C/td>\u003Ctd>CLAUDE.md task-to-doc table\u003C/td>\u003Ctd>AI coding agents\u003C/td>\u003Ctd>Task description → file path\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>2. Visual Maps\u003C/strong>\u003C/td>\u003Ctd>system-map, journey-map, pipeline-map, lifecycle-map\u003C/td>\u003Ctd>Developers needing overview\u003C/td>\u003Ctd>Mermaid diagrams\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>3. Workflow Docs\u003C/strong>\u003C/td>\u003Ctd>Four Lenses, Drill-Down, Quick Check, Deep Dive\u003C/td>\u003Ctd>Quality analysts + developers\u003C/td>\u003Ctd>Step-by-step protocols\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>4. Feature Docs\u003C/strong>\u003C/td>\u003Ctd>Charts, data input, navigation, learning\u003C/td>\u003Ctd>Developers building features\u003C/td>\u003Ctd>Component specs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>5. Technical Reference\u003C/strong>\u003C/td>\u003Ctd>Architecture, TypeDoc API, ADRs\u003C/td>\u003Ctd>Developers + architects\u003C/td>\u003Ctd>API signatures, decisions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>6. Product Specs\u003C/strong>\u003C/td>\u003Ctd>PWA, Azure, Website\u003C/td>\u003Ctd>Product managers + developers\u003C/td>\u003Ctd>Platform-specific details\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>A developer investigating a bug starts at Layer 1 (CLAUDE.md routes to the right file). A new team member starts at Layer 2 (visual maps for orientation). A quality analyst learning the tool starts at Layer 3 (workflow docs mirror their real work).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"documentation-as-coscouts-foundation\">Documentation as CoScout’s Foundation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#documentation-as-coscouts-foundation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Documentation as CoScout’s Foundation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The documentation methodology directly powers CoScout, the AI companion. Structured docs become structured AI behavior.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-documentation-to-ai-pipeline\">The Documentation-to-AI Pipeline\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-documentation-to-ai-pipeline\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Documentation-to-AI Pipeline”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n subgraph Docs[\"Documentation\"]\n VIS[\"docs/01-vision/\\nFour Lenses, Two Voices\"]\n WF[\"docs/03-features/workflows/\\nanalysis-journey-map\"]\n ARCH[\"docs/05-technical/architecture/\\ndata-pipeline-map\"]\n CASES[\"docs/04-cases/\\nCase studies\"]\n end\n\n subgraph Model[\"Knowledge Model\"]\n CON[\"concepts.ts\\n~15 methodology concepts\"]\n PHASE[\"Journey Phase Model\\nIDEOI phases\"]\n CTX[\"AIContext type\\nStructured analysis state\"]\n SAMP[\"@variscout/data\\nTeaching scenarios\"]\n end\n\n subgraph CoScout[\"CoScout Behavior\"]\n SYS[\"buildGlossaryPrompt()\\nSystem prompt\"]\n DET[\"detectInvestigationPhase()\\nPhase-adaptive prompts\"]\n BUILD[\"buildAIContext()\\nContext assembly\"]\n SQ[\"suggestedQuestions.ts\\nContext-aware prompts\"]\n end\n\n VIS --> CON --> SYS\n WF --> PHASE --> DET\n ARCH --> CTX --> BUILD\n CASES --> SAMP --> SQ\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"how-each-layer-feeds-coscout\">How Each Layer Feeds CoScout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#how-each-layer-feeds-coscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How Each Layer Feeds CoScout”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Doc Layer\u003C/th>\u003Cth>CoScout Feature\u003C/th>\u003Cth>Mechanism\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Vision docs (Four Lenses, Two Voices)\u003C/td>\u003Ctd>Methodology grounding\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">concepts.ts\u003C/code> → \u003Ccode dir=\"auto\">buildGlossaryPrompt()\u003C/code> in system prompt\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Journey Map (Frame/Scout/Investigate/Improve)\u003C/td>\u003Ctd>Phase-adaptive prompts\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">detectInvestigationPhase()\u003C/code> → \u003Ccode dir=\"auto\">getCoScoutPhase()\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Investigation Lifecycle (IDEOI states)\u003C/td>\u003Ctd>Hypothesis suggestions\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">suggestedQuestions.ts\u003C/code> adapts per IDEOI state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data Pipeline Map (TypeScript interfaces)\u003C/td>\u003Ctd>Context assembly\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">buildAIContext()\u003C/code> produces \u003Ccode dir=\"auto\">AIContext\u003C/code> from analysis state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Case studies\u003C/td>\u003Ctd>Teaching examples\u003C/td>\u003Ctd>Sample datasets inform suggested questions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Glossary terms\u003C/td>\u003Ctd>Terminology alignment\u003C/td>\u003Ctd>~41 terms in system prompt via Azure prompt caching\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"practical-implications\">Practical Implications\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#practical-implications\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Practical Implications”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When documentation is structured around the journey model, CoScout inherits that structure automatically:\u003C/p>\n\u003Cul>\n\u003Cli>Updating \u003Ccode dir=\"auto\">analysis-journey-map.md\u003C/code> should trigger review of \u003Ccode dir=\"auto\">suggestedQuestions.ts\u003C/code>\u003C/li>\n\u003Cli>New concepts in \u003Ccode dir=\"auto\">docs/01-vision/\u003C/code> should be added to \u003Ccode dir=\"auto\">concepts.ts\u003C/code>\u003C/li>\n\u003Cli>New workflow docs tagged with \u003Ccode dir=\"auto\">journey-phase:\u003C/code> become candidates for CoScout prompt context\u003C/li>\n\u003Cli>The documentation IS the spec for CoScout’s behavior\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"documentation-as-navigation-and-ux-spec\">Documentation as Navigation and UX Spec\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#documentation-as-navigation-and-ux-spec\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Documentation as Navigation and UX Spec”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The journey model serves double duty: it documents the analysis workflow AND specifies the navigation/UX design.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"journey-phases--navigation-states\">Journey Phases = Navigation States\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#journey-phases--navigation-states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Phases = Navigation States”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">FRAME → HomeScreen / PasteScreen / ColumnMapping\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SCOUT → Dashboard (Four Lenses tabs, filter chips, drill-down)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">INVESTIGATE → FindingsPanel + Board view + hypothesis forms\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">IMPROVE → WhatIfSimulator + ActionItems + StagedAnalysis\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"FRAME → HomeScreen / PasteScreen / ColumnMappingSCOUT → Dashboard (Four Lenses tabs, filter chips, drill-down)INVESTIGATE → FindingsPanel + Board view + hypothesis formsIMPROVE → WhatIfSimulator + ActionItems + StagedAnalysis\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tier-progressive-ux\">Tier-Progressive UX\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tier-progressive-ux\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier-Progressive UX”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The same 4-phase journey applies to all tiers, with features progressively unlocked:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Journey Phase\u003C/th>\u003Cth>PWA (Free)\u003C/th>\u003Cth>Azure Standard\u003C/th>\u003Cth>Azure Team\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>FRAME\u003C/strong>\u003C/td>\u003Ctd>Paste only, 3 factors, 50K rows\u003C/td>\u003Ctd>+ File upload, 6 factors, 100K rows\u003C/td>\u003Ctd>+ OneDrive sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>SCOUT\u003C/strong>\u003C/td>\u003Ctd>Four Lenses + drill-down\u003C/td>\u003Ctd>Same + more factors\u003C/td>\u003Ctd>+ NarrativeBar, ChartInsightChips\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>INVESTIGATE\u003C/strong>\u003C/td>\u003Ctd>3 statuses, no photos\u003C/td>\u003Ctd>Same\u003C/td>\u003Ctd>+ 5 statuses, photo evidence, CoScout\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>IMPROVE\u003C/strong>\u003C/td>\u003Ctd>What-If only\u003C/td>\u003Ctd>Same\u003C/td>\u003Ctd>+ Action tracking, staged verification, outcomes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>This table is the master spec for:\u003C/p>\n\u003Cul>\n\u003Cli>Which components render at each phase per tier\u003C/li>\n\u003Cli>Where \u003Ccode dir=\"auto\">UpgradePrompt\u003C/code> appears (at the feature boundary)\u003C/li>\n\u003Cli>What CoScout can suggest at each phase\u003C/li>\n\u003Cli>Which navigation paths exist\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"with-and-without-ai\">With and Without AI\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#with-and-without-ai\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “With and Without AI”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Without AI (PWA / Azure Standard):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>The journey is fully manual — the analyst reads charts, makes decisions, pins findings\u003C/li>\n\u003Cli>Navigation follows the Four Lenses sequence (I-Chart → Boxplot → Pareto → Capability)\u003C/li>\n\u003Cli>All decision points in the Decision Point Map are human-driven\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>With AI (Azure Team):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>CoScout adds a second entry path: hypothesis-driven (AI suggests → confirm → jump to Investigate)\u003C/li>\n\u003Cli>NarrativeBar provides passive guidance at each phase\u003C/li>\n\u003Cli>ChartInsightChips highlight actionable patterns on charts\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>With Teams (Azure Team plan):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Channel tabs = shared navigation context (multiple analysts, same journey)\u003C/li>\n\u003Cli>Photo evidence at Investigate phase (Teams camera API)\u003C/li>\n\u003Cli>OneDrive sync = persistent journey state across devices\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visual-first-methodology\">Visual-First Methodology\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visual-first-methodology\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual-First Methodology”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Rules codified in \u003Ca href=\"../../.claude/rules/documentation.md\">\u003Ccode dir=\"auto\">.claude/rules/documentation.md\u003C/code>\u003C/a>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Rule\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Mermaid diagram first\u003C/strong>\u003C/td>\u003Ctd>Every architecture/workflow doc opens with a diagram. Readers grasp structure in <60 seconds.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Data boundary interfaces\u003C/strong>\u003C/td>\u003Ctd>Architecture docs show TypeScript interface shapes at module boundaries.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mermaid for all new diagrams\u003C/strong>\u003C/td>\u003Ctd>GitHub-native rendering, machine-readable by AI agents.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Journey phase tags\u003C/strong>\u003C/td>\u003Ctd>All workflow/feature docs tagged with analysis phase for discovery.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Cross-linking required\u003C/strong>\u003C/td>\u003Ctd>New docs added to parent index, CLAUDE.md table, and related See Also sections.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>YAML frontmatter\u003C/strong>\u003C/td>\u003Ctd>Title, description, journey-phase for docs in the journey map.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tooling-stack\">Tooling Stack\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tooling-stack\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tooling Stack”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tool\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Markdown + Git\u003C/strong>\u003C/td>\u003Ctd>Source of truth for all documentation\u003C/td>\u003Ctd>Active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Starlight\u003C/strong>\u003C/td>\u003Ctd>Astro-based doc site (\u003Ccode dir=\"auto\">pnpm docs:build\u003C/code>) — Pagefind search, dark/light toggle, Mermaid rendering\u003C/td>\u003Ctd>Active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mermaid\u003C/strong>\u003C/td>\u003Ctd>Diagrams (30+ across docs) — flowchart, sequence, state, C4\u003C/td>\u003Ctd>Active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>TypeDoc\u003C/strong>\u003C/td>\u003Ctd>API reference for @variscout/core (\u003Ccode dir=\"auto\">pnpm --filter @variscout/core docs\u003C/code>)\u003C/td>\u003Ctd>Active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>CLAUDE.md\u003C/strong>\u003C/td>\u003Ctd>AI agent routing layer (task-to-doc table)\u003C/td>\u003Ctd>Active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>LikeC4\u003C/strong>\u003C/td>\u003Ctd>C4 architecture model (\u003Ccode dir=\"auto\">docs/architecture/likec4/\u003C/code>) — exports to Mermaid via \u003Ccode dir=\"auto\">pnpm docs:c4\u003C/code>\u003C/td>\u003Ctd>Active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Storybook\u003C/strong>\u003C/td>\u003Ctd>Interactive component catalog (66 components)\u003C/td>\u003Ctd>Active\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"roadmap\">Roadmap\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#roadmap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Roadmap”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-b--likec4-architecture-as-code\">Phase B — LikeC4 (Architecture as Code) ✓\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-b--likec4-architecture-as-code\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase B — LikeC4 (Architecture as Code) ✓”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Split \u003Ca href=\"../architecture/likec4/\">\u003Ccode dir=\"auto\">docs/architecture/likec4/\u003C/code>\u003C/a> model files define the full system at C4 L1/L2/L3:\u003C/p>\n\u003Cul>\n\u003Cli>Source of truth for architecture topology → exports to Mermaid via \u003Ccode dir=\"auto\">pnpm docs:c4\u003C/code>\u003C/li>\n\u003Cli>L3 Component views decompose each package into modules\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">pnpm docs:c4:serve\u003C/code> launches interactive browser; see \u003Ca href=\"architecture/component-map.md\">component-map.md\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-c--storybook-living-component-docs\">Phase C — Storybook (Living Component Docs) ✓\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-c--storybook-living-component-docs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase C — Storybook (Living Component Docs) ✓”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Interactive playground for 52 UI + 14 chart components:\u003C/p>\n\u003Cul>\n\u003Cli>Theme toggle (dark/light) + chart mode (technical/executive)\u003C/li>\n\u003Cli>66 stories across all shared packages\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">pnpm storybook\u003C/code> to launch; see \u003Ccode dir=\"auto\">.storybook/stories/README.md\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-d--adr-visualization\">Phase D — ADR Visualization ✓\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-d--adr-visualization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase D — ADR Visualization ✓”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Mermaid dependency graph in \u003Ca href=\"../../07-decisions/index.md\">\u003Ccode dir=\"auto\">docs/07-decisions/index.md\u003C/code>\u003C/a>:\u003C/p>\n\u003Cul>\n\u003Cli>Shows supersedes/extends relationships between 18 ADRs\u003C/li>\n\u003Cli>Groups by domain (Architecture, Charts, Storage, Distribution, Features, Teams)\u003C/li>\n\u003Cli>ADR-018 (Channel @Mention) added to index and dependency map\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"adr-dependency-map\">ADR Dependency Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#adr-dependency-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR Dependency Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph Architecture[\"Architecture\"]\n ADR001[\"001\\nMonorepo\"]\n ADR004[\"004\\nOffline-First\"]\n ADR011[\"011\\nAI Tooling\"]\n ADR013[\"013\\nDDD/Swarms\"]\n ADR001 --> ADR013\n end\n\n subgraph Charts[\"Charts & UI\"]\n ADR002[\"002\\nVisx Charts\"]\n ADR005[\"005\\nProps-Based\"]\n ADR009[\"009\\nViolin Mode\"]\n ADR017[\"017\\nFluent 2\"]\n ADR002 --> ADR005\n ADR005 --> ADR009\n end\n\n subgraph Storage[\"Storage\"]\n ADR003[\"003\\nIndexedDB\"]\n ADR012[\"012\\nPWA Browser-Only\"]\n ADR003 --> ADR004\n ADR004 --> ADR012\n end\n\n subgraph Distribution[\"Distribution\"]\n ADR006[\"006\\nEdition System\"]\n ADR007[\"007\\nAzure Marketplace\"]\n ADR008[\"008\\nWebsite Architecture\"]\n ADR006 -.->|superseded| ADR007\n end\n\n subgraph Features[\"Features\"]\n ADR010[\"010\\nGage R&R\"]\n ADR014[\"014\\nRegression Deferral\"]\n ADR015[\"015\\nInvestigation Board\"]\n end\n\n subgraph Teams[\"Teams Platform\"]\n ADR016[\"016\\nTeams Integration\"]\n ADR018[\"018\\nChannel @Mention\"]\n ADR007 --> ADR016\n ADR015 --> ADR016\n ADR016 --> ADR018\n ADR015 --> ADR018\n end\n\n style ADR006 fill:#94a3b8,color:#fff\n style ADR010 fill:#94a3b8,color:#fff\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sources-and-references\">Sources and References\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sources-and-references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sources and References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://diataxis.fr/\">Diataxis\u003C/a> — A systematic approach to technical documentation authoring\u003C/li>\n\u003Cli>\u003Ca href=\"https://c4model.com/\">C4 Model\u003C/a> — Software architecture diagrams at four zoom levels\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.writethedocs.org/guide/docs-as-code/\">Docs-as-Code (Write the Docs)\u003C/a> — Treat documentation with the same tools as code\u003C/li>\n\u003Cli>\u003Ca href=\"https://likec4.dev/\">LikeC4\u003C/a> — Architecture models as code (npm-native, Mermaid export)\u003C/li>\n\u003Cli>\u003Ca href=\"https://storybook.js.org/docs/writing-docs\">Storybook\u003C/a> — Interactive component documentation\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../03-features/workflows/analysis-journey-map.md\">Analysis Journey Map\u003C/a> — the 4-phase journey model\u003C/li>\n\u003Cli>\u003Ca href=\"architecture/system-map.md\">System Map\u003C/a> — C4 L1/L2 architecture diagrams\u003C/li>\n\u003Cli>\u003Ca href=\"architecture/data-pipeline-map.md\">Data Pipeline Map\u003C/a> — end-to-end data flow with TypeScript boundaries\u003C/li>\n\u003Cli>\u003Ca href=\"../03-features/workflows/investigation-lifecycle-map.md\">Investigation Lifecycle Map\u003C/a> — IDEOI state machine\u003C/li>\n\u003Cli>\u003Ca href=\"../../.claude/rules/documentation.md\">Documentation Rules\u003C/a> — enforced rules for doc structure\u003C/li>\n\u003C/ul>", + { + "headings": 69, + "localImagePaths": 151, + "remoteImagePaths": 152, + "frontmatter": 153, + "imagePaths": 156 + }, + [ + 70, 72, 75, 78, 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124, 127, 130, + 133, 136, 139, 142, 145, 148 + ], + { "depth": 30, "slug": 71, "text": 58 }, + "documentation-methodology", + { "depth": 33, "slug": 73, "text": 74 }, + "why-document-the-documentation", + "Why Document the Documentation?", + { "depth": 33, "slug": 76, "text": 77 }, + "foundations-industry-frameworks-applied", + "Foundations: Industry Frameworks Applied", + { "depth": 79, "slug": 80, "text": 81 }, + 3, + "diataxis", + "Diataxis", + { "depth": 79, "slug": 83, "text": 84 }, + "c4-model", + "C4 Model", + { "depth": 79, "slug": 86, "text": 87 }, + "docs-as-code", + "Docs-as-Code", + { "depth": 33, "slug": 89, "text": 90 }, + "the-journey-spine", + "The Journey Spine", + { "depth": 79, "slug": 92, "text": 93 }, + "journey-phase-tags", + "Journey Phase Tags", + { "depth": 79, "slug": 95, "text": 96 }, + "decision-point-map", + "Decision Point Map", + { "depth": 33, "slug": 98, "text": 99 }, + "documentation-layers", + "Documentation Layers", + { "depth": 33, "slug": 101, "text": 102 }, + "documentation-as-coscouts-foundation", + "Documentation as CoScout’s Foundation", + { "depth": 79, "slug": 104, "text": 105 }, + "the-documentation-to-ai-pipeline", + "The Documentation-to-AI Pipeline", + { "depth": 79, "slug": 107, "text": 108 }, + "how-each-layer-feeds-coscout", + "How Each Layer Feeds CoScout", + { "depth": 79, "slug": 110, "text": 111 }, + "practical-implications", + "Practical Implications", + { "depth": 33, "slug": 113, "text": 114 }, + "documentation-as-navigation-and-ux-spec", + "Documentation as Navigation and UX Spec", + { "depth": 79, "slug": 116, "text": 117 }, + "journey-phases--navigation-states", + "Journey Phases = Navigation States", + { "depth": 79, "slug": 119, "text": 120 }, + "tier-progressive-ux", + "Tier-Progressive UX", + { "depth": 79, "slug": 122, "text": 123 }, + "with-and-without-ai", + "With and Without AI", + { "depth": 33, "slug": 125, "text": 126 }, + "visual-first-methodology", + "Visual-First Methodology", + { "depth": 33, "slug": 128, "text": 129 }, + "tooling-stack", + "Tooling Stack", + { "depth": 33, "slug": 131, "text": 132 }, + "roadmap", + "Roadmap", + { "depth": 79, "slug": 134, "text": 135 }, + "phase-b--likec4-architecture-as-code", + "Phase B — LikeC4 (Architecture as Code) ✓", + { "depth": 79, "slug": 137, "text": 138 }, + "phase-c--storybook-living-component-docs", + "Phase C — Storybook (Living Component Docs) ✓", + { "depth": 79, "slug": 140, "text": 141 }, + "phase-d--adr-visualization", + "Phase D — ADR Visualization ✓", + { "depth": 33, "slug": 143, "text": 144 }, + "adr-dependency-map", + "ADR Dependency Map", + { "depth": 33, "slug": 146, "text": 147 }, + "sources-and-references", + "Sources and References", + { "depth": 33, "slug": 149, "text": 150 }, + "see-also", + "See Also", + [], + [], + { "title": 58, "description": 59, "journey-phase": 154 }, + [155], + "all", + [], + "05-technical/architecture/data-pipeline-map", + { "id": 157, "data": 159, "body": 165, "filePath": 166, "digest": 167, "rendered": 168 }, + { + "title": 160, + "description": 161, + "editUrl": 16, + "head": 162, + "template": 18, + "sidebar": 163, + "pagefind": 16, + "draft": 20 + }, + "Data Pipeline Map", + "End-to-end data flow from CSV upload through statistics, charts, and AI — with TypeScript interfaces at every boundary", + [], + { "hidden": 20, "attrs": 164 }, + {}, + "# Data Pipeline Map\n\nEnd-to-end data flow from CSV upload through statistics, charts, and AI — with TypeScript interfaces at every boundary. Extends [data-flow.md](data-flow.md) with the full pipeline view including AI integration.\n\n---\n\n## 1. Full Pipeline Overview\n\n```mermaid\nflowchart TB\n subgraph Input[\"Data Input\"]\n CSV[CSV File] --> Parse[parseCSV]\n XLS[Excel File] --> ParseXL[parseExcel]\n Paste[Paste Data] --> ParseTxt[parseText]\n Sample[Sample Dataset] --> Direct[Pre-parsed DataRow array]\n end\n\n subgraph Detection[\"Column Detection\"]\n Parse --> DC[detectColumns]\n ParseXL --> DC\n ParseTxt --> DC\n Direct --> DC\n DC --> CM[ColumnMapping UI]\n end\n\n subgraph Validation[\"Validation\"]\n CM --> VD[validateData]\n VD --> DQR[DataQualityReport]\n end\n\n subgraph State[\"DataContext\"]\n DQR --> CTX[rawData + specs + filters]\n CTX --> FD[filteredData]\n end\n\n subgraph Stats[\"Statistics Engine\"]\n FD --> CS[calculateStats]\n CS --> SR[StatsResult]\n FD --> CA[calculateAnova]\n CA --> AR[AnovaResult]\n end\n\n subgraph Charts[\"Chart Transforms\"]\n FD --> IC[useIChartData]\n IC --> ICP[IChartPoint array]\n FD --> BD[useBoxplotData]\n BD --> BDD[BoxplotData array]\n FD --> PD[useParetoChartData]\n PD --> PI[ParetoItem array]\n end\n\n subgraph Presentation[\"Chart Components\"]\n ICP --> ICH[I-Chart]\n BDD --> BOX[Boxplot]\n PI --> PAR[Pareto]\n SR --> STP[StatsPanel]\n AR --> ANV[AnovaResults]\n end\n\n subgraph Investigation[\"Findings\"]\n Presentation --> FND[Finding array]\n FND --> Board[FindingBoardView]\n end\n\n subgraph AI[\"AI Layer (preview)\"]\n SR --> AIC[buildAIContext]\n AR --> AIC\n FD --> AIC\n FND --> AIC\n AIC --> Prompts[3-tier prompt templates]\n Prompts --> SVC[AI Service - Azure OpenAI]\n SVC --> NB[NarrativeBar]\n SVC --> CIC[ChartInsightChips]\n SVC --> COS[CoScout - conversational]\n end\n\n subgraph Persistence[\"Storage\"]\n CTX --> IDB[(IndexedDB)]\n CTX --> OD[(\"OneDrive (Team plan)\")]\n end\n```\n\n---\n\n## 2. TypeScript Interfaces at Boundaries\n\nEach boundary between pipeline stages has a well-defined TypeScript interface. The shapes below are abbreviated from the actual source.\n\n### Input Boundary\n\n```typescript\n// packages/core/src/types.ts\ntype DataCellValue = string | number | boolean | null | undefined;\n\ninterface DataRow {\n [columnName: string]: DataCellValue;\n}\n```\n\nAll parsers (`parseCSV`, `parseText`, `parseExcel`) return `DataRow[]`.\n\n### Column Detection Boundary\n\n```typescript\n// packages/core/src/parser/types.ts\ninterface DetectedColumns {\n outcome: string | null;\n factors: string[];\n timeColumn: string | null;\n confidence: 'high' | 'medium' | 'low';\n columnAnalysis: ColumnAnalysis[];\n}\n```\n\n### Validation Boundary\n\n```typescript\n// packages/core/src/parser/types.ts\ninterface DataQualityReport {\n totalRows: number;\n validRows: number;\n excludedRows: ExcludedRow[];\n columnIssues: ColumnIssue[];\n}\n\ninterface ExclusionReason {\n type: 'missing' | 'non_numeric' | 'empty';\n column: string;\n value?: string;\n}\n```\n\n### Stats Boundary\n\n```typescript\n// packages/core/src/types.ts\ninterface StatsResult {\n mean: number;\n median: number;\n stdDev: number; // Sample std dev (sigma_overall)\n sigmaWithin: number; // Within-subgroup std dev (MR-bar / d2)\n mrBar: number; // Mean moving range\n ucl: number; // Upper Control Limit (mean + 3 * sigmaWithin)\n lcl: number; // Lower Control Limit (mean - 3 * sigmaWithin)\n cp?: number; // Process Capability (requires USL + LSL)\n cpk?: number; // Process Capability accounting for centering\n outOfSpecPercentage: number;\n}\n```\n\n### ANOVA Boundary\n\n```typescript\n// packages/core/src/types.ts\ninterface AnovaResult {\n groups: AnovaGroup[];\n ssb: number; // Sum of squares between groups\n ssw: number; // Sum of squares within groups\n dfBetween: number; // Degrees of freedom (k-1)\n dfWithin: number; // Degrees of freedom (N-k)\n msb: number; // Mean square between\n msw: number; // Mean square within\n fStatistic: number; // F = MSB / MSW\n pValue: number;\n isSignificant: boolean; // p \u003C 0.05\n etaSquared: number; // Effect size (SSB / SST)\n insight: string; // Plain-language interpretation\n}\n```\n\n### Filter Boundary\n\n```typescript\n// packages/core/src/navigation.ts\ninterface FilterAction {\n id: string;\n type: FilterType; // 'filter' | 'highlight'\n source: FilterSource; // Which chart initiated\n factor?: string; // Column being filtered\n values: (string | number)[];\n rowIndex?: number; // I-Chart row highlight\n timestamp: number;\n}\n```\n\n### Finding Boundary\n\n```typescript\n// packages/core/src/findings.ts\ntype FindingStatus = 'observed' | 'investigating' | 'analyzed';\ntype FindingTag = 'key-driver' | 'low-impact';\n\ntype FindingSource =\n | { chart: 'boxplot' | 'pareto'; category: string }\n | { chart: 'ichart'; anchorX: number; anchorY: number };\n\ninterface FindingContext {\n activeFilters: Record\u003Cstring, (string | number)[]>;\n cumulativeScope: number | null;\n stats?: { mean: number; median?: number; cpk?: number; samples: number };\n}\n\ninterface Finding {\n id: string;\n text: string;\n createdAt: number;\n context: FindingContext;\n status: FindingStatus;\n tag?: FindingTag;\n comments: FindingComment[];\n statusChangedAt: number;\n source?: FindingSource;\n assignee?: FindingAssignee;\n}\n```\n\n### Persistence Boundary\n\n```typescript\n// packages/hooks/src/types.ts\ninterface AnalysisState {\n version: string;\n rawData: DataRow[];\n outcome: string | null;\n factors: string[];\n specs: SpecLimits;\n measureSpecs?: Record\u003Cstring, SpecLimits>;\n filters: Record\u003Cstring, (string | number)[]>;\n axisSettings: { min?: number; max?: number; scaleMode?: ScaleMode };\n columnAliases?: Record\u003Cstring, string>;\n valueLabels?: Record\u003Cstring, Record\u003Cstring, string>>;\n displayOptions?: DisplayOptions;\n cpkTarget?: number;\n stageColumn?: string | null;\n stageOrderMode?: StageOrderMode;\n isPerformanceMode?: boolean;\n measureColumns?: string[];\n selectedMeasure?: string | null;\n measureLabel?: string | null;\n chartTitles?: Record\u003Cstring, string>;\n filterStack?: FilterAction[];\n viewState?: ViewState;\n findings?: Finding[];\n}\n```\n\n---\n\n## 3. Stats Pipeline Swim Lane\n\n```mermaid\nflowchart LR\n subgraph Input[\"Filtered Data\"]\n FD[\"filteredData (DataRow[])\"]\n SP[\"specs (SpecLimits)\"]\n FC[\"factor (string)\"]\n end\n\n subgraph Core[\"@variscout/core\"]\n CS[\"calculateStats(values, specs)\"]\n CA[\"calculateAnova(data, factor)\"]\n end\n\n subgraph Output[\"Results\"]\n SR[\"StatsResult\"]\n AR[\"AnovaResult\"]\n end\n\n subgraph Hooks[\"@variscout/hooks — Chart Transforms\"]\n ICD[\"useIChartData()\"]\n BPD[\"useBoxplotData()\"]\n PCD[\"useParetoChartData()\"]\n end\n\n subgraph ChartData[\"Chart Data Shapes\"]\n ICP[\"IChartPoint[]\"]\n BDD[\"BoxplotData[]\"]\n PI[\"ParetoItem[]\"]\n end\n\n FD --> CS\n SP --> CS\n CS --> SR\n\n FD --> CA\n FC --> CA\n CA --> AR\n\n FD --> ICD\n FD --> BPD\n FD --> PCD\n SR --> ICD\n\n ICD --> ICP\n BPD --> BDD\n PCD --> PI\n```\n\n---\n\n## 4. AI Pipeline Swim Lane\n\n> **Note**: AI features are shipped behind a preview gate. The pipeline components (NarrativeBar, ChartInsightChips, CoScout) are defined in the knowledge layer but not yet wired to live AI services in the main codebase. See the [investigation lifecycle map](../../03-features/workflows/investigation-lifecycle-map.md) for IDEOI phase definitions and CoScout behavior per phase.\n\n```mermaid\nflowchart LR\n subgraph Context[\"Analysis Context\"]\n SR[StatsResult]\n AR[AnovaResult]\n FA[\"FilterAction[]\"]\n FND[\"Finding[]\"]\n Phase[\"IDEOI Phase\"]\n end\n\n subgraph Build[\"Context Assembly\"]\n BAC[\"buildAIContext()\"]\n end\n\n subgraph Prompts[\"Prompt Templates (3-tier)\"]\n SYS[\"System prompt (role + rules)\"]\n DOM[\"Domain prompt (SPC methodology)\"]\n CTX[\"Context prompt (current data state)\"]\n end\n\n subgraph Service[\"AI Service\"]\n AOAI[\"Azure OpenAI\"]\n end\n\n subgraph Output[\"AI Output Components\"]\n NB[\"NarrativeBar — summary text\"]\n CIC[\"ChartInsightChips — per-chart suggestions\"]\n COS[\"CoScout — conversational, phase-aware\"]\n end\n\n SR --> BAC\n AR --> BAC\n FA --> BAC\n FND --> BAC\n Phase --> BAC\n\n BAC --> SYS\n BAC --> DOM\n BAC --> CTX\n\n SYS --> AOAI\n DOM --> AOAI\n CTX --> AOAI\n\n AOAI --> NB\n AOAI --> CIC\n AOAI --> COS\n```\n\n### IDEOI Phase Mapping\n\nThe AI layer adapts behavior based on the current investigation phase:\n\n| IDEOI Phase | Trigger | CoScout Behavior |\n|-------------|---------|-----------------|\n| **Initial** | Data loaded | Suggests patterns in data |\n| **Diverging** | First finding pinned | Suggests possible hypotheses |\n| **Evaluating** | Hypothesis linked | Challenges assumptions, suggests validation |\n| **Organizing** | Finding analyzed | Summarizes root causes, suggests actions |\n| **Implementing** | Actions defined | Tracks progress, projects improvement |\n\n---\n\n## 5. Persistence Pipeline\n\n```mermaid\nflowchart TB\n subgraph State[\"Application State\"]\n AS[\"AnalysisState\"]\n end\n\n subgraph Local[\"Local Storage (all platforms)\"]\n IDB[(\"IndexedDB\")]\n end\n\n subgraph Cloud[\"Cloud Storage (Team plan only)\"]\n EA[\"EasyAuth\"] --> TK[\"Access Token\"]\n TK --> GRAPH[\"Graph API\"]\n GRAPH --> OD[(\"OneDrive\")]\n end\n\n AS -->|\"Dexie.js\"| IDB\n AS -->|\"StorageProvider\"| EA\n IDB \u003C-->|\"Bi-directional sync\"| OD\n\n style Cloud fill:#f0f9ff,stroke:#3b82f6\n```\n\n`AnalysisState` is the single serializable shape that captures the full state of an analysis session. Key fields for persistence:\n\n| Field | Purpose |\n|-------|---------|\n| `rawData` | Original uploaded data rows |\n| `specs` | USL, LSL, target specifications |\n| `filters` | Active filter selections |\n| `filterStack` | Ordered `FilterAction[]` drill trail |\n| `findings` | Investigation findings with status |\n| `viewState` | Active tab, focused chart, panel state |\n| `isPerformanceMode` | Multi-measure mode flag |\n| `measureColumns` | Selected measure columns |\n| `cpkTarget` | Capability target (default 1.33) |\n\n---\n\n## 6. Filter Recalculation Flow\n\nA single filter click triggers a cascade of recalculations through the pipeline:\n\n```mermaid\nflowchart TD\n A[\"User clicks Boxplot category\"] --> B[\"useFilterNavigation.addFilter()\"]\n B --> C[\"DataContext.dispatch( SET_FILTERS )\"]\n C --> D[\"filteredData recomputed\"]\n D --> E[\"calculateStats(filteredData)\"]\n D --> F[\"calculateAnova(filteredData, nextFactor)\"]\n E --> G[\"New StatsResult\"]\n F --> H[\"New AnovaResult\"]\n G --> I[\"All chart hooks recompute\"]\n H --> I\n I --> J[\"All chart components re-render\"]\n J --> K{\"AI enabled?\"}\n K -->|Yes| L[\"Debounce 500ms\"]\n L --> M[\"buildAIContext()\"]\n M --> N[\"NarrativeBar updates\"]\n K -->|No| O[\"Done\"]\n```\n\n### What gets recomputed\n\n| Stage | Function / Hook | Output |\n|-------|----------------|--------|\n| Filter | `useFilterNavigation` | Updated `FilterAction[]` |\n| Data | DataContext reducer | `filteredData` (subset of `rawData`) |\n| Stats | `calculateStats()` | New `StatsResult` (mean, Cpk, control limits) |\n| ANOVA | `calculateAnova()` | New `AnovaResult` (F, p, eta-squared) |\n| I-Chart | `useIChartData()` | New `IChartPoint[]` |\n| Boxplot | `useBoxplotData()` | New `BoxplotData[]` |\n| Pareto | `useParetoChartData()` | New `ParetoItem[]` |\n| Variation | `useVariationTracking` | Updated scope fraction and cumulative % |\n| AI (preview) | `buildAIContext()` | Refreshed narrative and insights |\n\n---\n\n## 7. Filter Drill-Down Sequence Diagram\n\nComplete round-trip from user click to updated UI:\n\n```mermaid\nsequenceDiagram\n participant User\n participant Boxplot\n participant useFilterNavigation\n participant DataContext\n participant Stats as calculateStats\n participant ANOVA as calculateAnova\n participant Charts as Chart hooks\n participant AI as AI layer (debounced)\n\n User->>Boxplot: Click category bar\n Boxplot->>useFilterNavigation: addFilter(factor, value)\n useFilterNavigation->>DataContext: dispatch SET_FILTERS\n DataContext->>DataContext: Recompute filteredData\n\n par Statistics\n DataContext->>Stats: calculateStats(filteredData, specs)\n Stats-->>DataContext: StatsResult\n and ANOVA\n DataContext->>ANOVA: calculateAnova(filteredData, nextFactor)\n ANOVA-->>DataContext: AnovaResult\n end\n\n DataContext-->>Charts: New props (filteredData, stats, anova)\n Charts->>Charts: useIChartData + useBoxplotData + useParetoChartData\n\n Charts-->>Boxplot: Re-render with drill-down data\n Note over Boxplot: Next factor level displayed\n\n opt AI preview enabled\n DataContext-->>AI: AIContext (debounced 500ms)\n AI-->>User: NarrativeBar update\n end\n```\n\n---\n\n## 8. See Also\n\n- [Data Flow](data-flow.md) -- detailed input/validation stages and platform-specific flows\n- [System Map](system-map.md) -- package topology and dependency graph\n- [Component Patterns](component-patterns.md) -- hook integration details and DataContext structure\n- [Investigation Lifecycle Map](../../03-features/workflows/investigation-lifecycle-map.md) -- IDEOI phases and CoScout behavior\n- [Investigation to Action](../../03-features/workflows/investigation-to-action.md) -- findings workflow specification", + "src/content/docs/05-technical/architecture/data-pipeline-map.md", + "4b43caf7bf592a3e", + { "html": 169, "metadata": 170 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"data-pipeline-map\">Data Pipeline Map\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#data-pipeline-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Pipeline Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>End-to-end data flow from CSV upload through statistics, charts, and AI — with TypeScript interfaces at every boundary. Extends \u003Ca href=\"data-flow.md\">data-flow.md\u003C/a> with the full pipeline view including AI integration.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"1-full-pipeline-overview\">1. Full Pipeline Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#1-full-pipeline-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Full Pipeline Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph Input[\"Data Input\"]\n CSV[CSV File] --> Parse[parseCSV]\n XLS[Excel File] --> ParseXL[parseExcel]\n Paste[Paste Data] --> ParseTxt[parseText]\n Sample[Sample Dataset] --> Direct[Pre-parsed DataRow array]\n end\n\n subgraph Detection[\"Column Detection\"]\n Parse --> DC[detectColumns]\n ParseXL --> DC\n ParseTxt --> DC\n Direct --> DC\n DC --> CM[ColumnMapping UI]\n end\n\n subgraph Validation[\"Validation\"]\n CM --> VD[validateData]\n VD --> DQR[DataQualityReport]\n end\n\n subgraph State[\"DataContext\"]\n DQR --> CTX[rawData + specs + filters]\n CTX --> FD[filteredData]\n end\n\n subgraph Stats[\"Statistics Engine\"]\n FD --> CS[calculateStats]\n CS --> SR[StatsResult]\n FD --> CA[calculateAnova]\n CA --> AR[AnovaResult]\n end\n\n subgraph Charts[\"Chart Transforms\"]\n FD --> IC[useIChartData]\n IC --> ICP[IChartPoint array]\n FD --> BD[useBoxplotData]\n BD --> BDD[BoxplotData array]\n FD --> PD[useParetoChartData]\n PD --> PI[ParetoItem array]\n end\n\n subgraph Presentation[\"Chart Components\"]\n ICP --> ICH[I-Chart]\n BDD --> BOX[Boxplot]\n PI --> PAR[Pareto]\n SR --> STP[StatsPanel]\n AR --> ANV[AnovaResults]\n end\n\n subgraph Investigation[\"Findings\"]\n Presentation --> FND[Finding array]\n FND --> Board[FindingBoardView]\n end\n\n subgraph AI[\"AI Layer (preview)\"]\n SR --> AIC[buildAIContext]\n AR --> AIC\n FD --> AIC\n FND --> AIC\n AIC --> Prompts[3-tier prompt templates]\n Prompts --> SVC[AI Service - Azure OpenAI]\n SVC --> NB[NarrativeBar]\n SVC --> CIC[ChartInsightChips]\n SVC --> COS[CoScout - conversational]\n end\n\n subgraph Persistence[\"Storage\"]\n CTX --> IDB[(IndexedDB)]\n CTX --> OD[(\"OneDrive (Team plan)\")]\n end\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"2-typescript-interfaces-at-boundaries\">2. TypeScript Interfaces at Boundaries\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#2-typescript-interfaces-at-boundaries\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. TypeScript Interfaces at Boundaries”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each boundary between pipeline stages has a well-defined TypeScript interface. The shapes below are abbreviated from the actual source.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input-boundary\">Input Boundary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input-boundary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input Boundary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/core/src/types.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> DataCellValue \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> DataRow {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">columnName\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DataCellValue\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"type DataCellValue = string | number | boolean | null | undefined;interface DataRow { [columnName: string]: DataCellValue;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>All parsers (\u003Ccode dir=\"auto\">parseCSV\u003C/code>, \u003Ccode dir=\"auto\">parseText\u003C/code>, \u003Ccode dir=\"auto\">parseExcel\u003C/code>) return \u003Ccode dir=\"auto\">DataRow[]\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"column-detection-boundary\">Column Detection Boundary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#column-detection-boundary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Column Detection Boundary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/core/src/parser/types.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> DetectedColumns {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factors\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">timeColumn\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">confidence\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">high\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">medium\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">low\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">columnAnalysis\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ColumnAnalysis\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface DetectedColumns { outcome: string | null; factors: string[]; timeColumn: string | null; confidence: 'high' | 'medium' | 'low'; columnAnalysis: ColumnAnalysis[];}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"validation-boundary\">Validation Boundary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#validation-boundary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Validation Boundary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/core/src/parser/types.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> DataQualityReport {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">totalRows\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">validRows\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">excludedRows\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ExcludedRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">columnIssues\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ColumnIssue\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ExclusionReason {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">type\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">missing\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">non_numeric\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">empty\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">column\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface DataQualityReport { totalRows: number; validRows: number; excludedRows: ExcludedRow[]; columnIssues: ColumnIssue[];}interface ExclusionReason { type: 'missing' | 'non_numeric' | 'empty'; column: string; value?: string;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"stats-boundary\">Stats Boundary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#stats-boundary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Stats Boundary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/core/src/types.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> StatsResult {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">median\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stdDev\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Sample std dev (sigma_overall)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">sigmaWithin\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Within-subgroup std dev (MR-bar / d2)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mrBar\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mean moving range\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ucl\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Upper Control Limit (mean + 3 * sigmaWithin)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">lcl\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Lower Control Limit (mean - 3 * sigmaWithin)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cp\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Process Capability (requires USL + LSL)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cpk\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Process Capability accounting for centering\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outOfSpecPercentage\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface StatsResult { mean: number; median: number; stdDev: number; // Sample std dev (sigma_overall) sigmaWithin: number; // Within-subgroup std dev (MR-bar / d2) mrBar: number; // Mean moving range ucl: number; // Upper Control Limit (mean + 3 * sigmaWithin) lcl: number; // Lower Control Limit (mean - 3 * sigmaWithin) cp?: number; // Process Capability (requires USL + LSL) cpk?: number; // Process Capability accounting for centering outOfSpecPercentage: number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"anova-boundary\">ANOVA Boundary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#anova-boundary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ANOVA Boundary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/core/src/types.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> AnovaResult {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">groups\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">AnovaGroup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ssb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Sum of squares between groups\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ssw\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Sum of squares within groups\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">dfBetween\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Degrees of freedom (k-1)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">dfWithin\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Degrees of freedom (N-k)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">msb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mean square between\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">msw\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mean square within\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fStatistic\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// F = MSB / MSW\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">pValue\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isSignificant\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// p < 0.05\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">etaSquared\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Effect size (SSB / SST)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">insight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Plain-language interpretation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface AnovaResult { groups: AnovaGroup[]; ssb: number; // Sum of squares between groups ssw: number; // Sum of squares within groups dfBetween: number; // Degrees of freedom (k-1) dfWithin: number; // Degrees of freedom (N-k) msb: number; // Mean square between msw: number; // Mean square within fStatistic: number; // F = MSB / MSW pValue: number; isSignificant: boolean; // p \u003C 0.05 etaSquared: number; // Effect size (SSB / SST) insight: string; // Plain-language interpretation}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filter-boundary\">Filter Boundary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filter-boundary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter Boundary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/core/src/navigation.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FilterAction {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">type\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FilterType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 'filter' | 'highlight'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">source\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FilterSource\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Which chart initiated\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Column being filtered\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">rowIndex\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// I-Chart row highlight\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">timestamp\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface FilterAction { id: string; type: FilterType; // 'filter' | 'highlight' source: FilterSource; // Which chart initiated factor?: string; // Column being filtered values: (string | number)[]; rowIndex?: number; // I-Chart row highlight timestamp: number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"finding-boundary\">Finding Boundary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#finding-boundary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Finding Boundary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/core/src/findings.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FindingStatus \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">observed\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">investigating\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">analyzed\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FindingTag \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">key-driver\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">low-impact\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FindingSource \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { chart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; category\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { chart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ichart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; anchorX\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; anchorY\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> };\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FindingContext {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">activeFilters\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Record\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)[]>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cumulativeScope\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { mean\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; median\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; cpk\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; samples\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> };\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Finding {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">createdAt\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">context\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FindingContext\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">status\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FindingStatus\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tag\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FindingTag\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">comments\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FindingComment\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">statusChangedAt\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">source\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FindingSource\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">assignee\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FindingAssignee\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"type FindingStatus = 'observed' | 'investigating' | 'analyzed';type FindingTag = 'key-driver' | 'low-impact';type FindingSource = | { chart: 'boxplot' | 'pareto'; category: string } | { chart: 'ichart'; anchorX: number; anchorY: number };interface FindingContext { activeFilters: Record\u003Cstring, (string | number)[]>; cumulativeScope: number | null; stats?: { mean: number; median?: number; cpk?: number; samples: number };}interface Finding { id: string; text: string; createdAt: number; context: FindingContext; status: FindingStatus; tag?: FindingTag; comments: FindingComment[]; statusChangedAt: number; source?: FindingSource; assignee?: FindingAssignee;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"persistence-boundary\">Persistence Boundary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#persistence-boundary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persistence Boundary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/hooks/src/types.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> AnalysisState {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">version\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">rawData\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DataRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factors\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measureSpecs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Record\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filters\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Record\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)[]>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">axisSettings\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { min\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; max\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; scaleMode\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ScaleMode\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> };\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">columnAliases\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Record\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">valueLabels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Record\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Record\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">displayOptions\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DisplayOptions\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cpkTarget\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stageColumn\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stageOrderMode\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">StageOrderMode\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isPerformanceMode\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measureColumns\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measureLabel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartTitles\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Record\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterStack\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FilterAction\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">viewState\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ViewState\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">findings\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Finding\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface AnalysisState { version: string; rawData: DataRow[]; outcome: string | null; factors: string[]; specs: SpecLimits; measureSpecs?: Record\u003Cstring, SpecLimits>; filters: Record\u003Cstring, (string | number)[]>; axisSettings: { min?: number; max?: number; scaleMode?: ScaleMode }; columnAliases?: Record\u003Cstring, string>; valueLabels?: Record\u003Cstring, Record\u003Cstring, string>>; displayOptions?: DisplayOptions; cpkTarget?: number; stageColumn?: string | null; stageOrderMode?: StageOrderMode; isPerformanceMode?: boolean; measureColumns?: string[]; selectedMeasure?: string | null; measureLabel?: string | null; chartTitles?: Record\u003Cstring, string>; filterStack?: FilterAction[]; viewState?: ViewState; findings?: Finding[];}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"3-stats-pipeline-swim-lane\">3. Stats Pipeline Swim Lane\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#3-stats-pipeline-swim-lane\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Stats Pipeline Swim Lane”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n subgraph Input[\"Filtered Data\"]\n FD[\"filteredData (DataRow[])\"]\n SP[\"specs (SpecLimits)\"]\n FC[\"factor (string)\"]\n end\n\n subgraph Core[\"@variscout/core\"]\n CS[\"calculateStats(values, specs)\"]\n CA[\"calculateAnova(data, factor)\"]\n end\n\n subgraph Output[\"Results\"]\n SR[\"StatsResult\"]\n AR[\"AnovaResult\"]\n end\n\n subgraph Hooks[\"@variscout/hooks — Chart Transforms\"]\n ICD[\"useIChartData()\"]\n BPD[\"useBoxplotData()\"]\n PCD[\"useParetoChartData()\"]\n end\n\n subgraph ChartData[\"Chart Data Shapes\"]\n ICP[\"IChartPoint[]\"]\n BDD[\"BoxplotData[]\"]\n PI[\"ParetoItem[]\"]\n end\n\n FD --> CS\n SP --> CS\n CS --> SR\n\n FD --> CA\n FC --> CA\n CA --> AR\n\n FD --> ICD\n FD --> BPD\n FD --> PCD\n SR --> ICD\n\n ICD --> ICP\n BPD --> BDD\n PCD --> PI\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-ai-pipeline-swim-lane\">4. AI Pipeline Swim Lane\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-ai-pipeline-swim-lane\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. AI Pipeline Swim Lane”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note\u003C/strong>: AI features are shipped behind a preview gate. The pipeline components (NarrativeBar, ChartInsightChips, CoScout) are defined in the knowledge layer but not yet wired to live AI services in the main codebase. See the \u003Ca href=\"../../03-features/workflows/investigation-lifecycle-map.md\">investigation lifecycle map\u003C/a> for IDEOI phase definitions and CoScout behavior per phase.\u003C/p>\n\u003C/blockquote>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n subgraph Context[\"Analysis Context\"]\n SR[StatsResult]\n AR[AnovaResult]\n FA[\"FilterAction[]\"]\n FND[\"Finding[]\"]\n Phase[\"IDEOI Phase\"]\n end\n\n subgraph Build[\"Context Assembly\"]\n BAC[\"buildAIContext()\"]\n end\n\n subgraph Prompts[\"Prompt Templates (3-tier)\"]\n SYS[\"System prompt (role + rules)\"]\n DOM[\"Domain prompt (SPC methodology)\"]\n CTX[\"Context prompt (current data state)\"]\n end\n\n subgraph Service[\"AI Service\"]\n AOAI[\"Azure OpenAI\"]\n end\n\n subgraph Output[\"AI Output Components\"]\n NB[\"NarrativeBar — summary text\"]\n CIC[\"ChartInsightChips — per-chart suggestions\"]\n COS[\"CoScout — conversational, phase-aware\"]\n end\n\n SR --> BAC\n AR --> BAC\n FA --> BAC\n FND --> BAC\n Phase --> BAC\n\n BAC --> SYS\n BAC --> DOM\n BAC --> CTX\n\n SYS --> AOAI\n DOM --> AOAI\n CTX --> AOAI\n\n AOAI --> NB\n AOAI --> CIC\n AOAI --> COS\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ideoi-phase-mapping\">IDEOI Phase Mapping\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ideoi-phase-mapping\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “IDEOI Phase Mapping”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The AI layer adapts behavior based on the current investigation phase:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>IDEOI Phase\u003C/th>\u003Cth>Trigger\u003C/th>\u003Cth>CoScout Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Initial\u003C/strong>\u003C/td>\u003Ctd>Data loaded\u003C/td>\u003Ctd>Suggests patterns in data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Diverging\u003C/strong>\u003C/td>\u003Ctd>First finding pinned\u003C/td>\u003Ctd>Suggests possible hypotheses\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Evaluating\u003C/strong>\u003C/td>\u003Ctd>Hypothesis linked\u003C/td>\u003Ctd>Challenges assumptions, suggests validation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Organizing\u003C/strong>\u003C/td>\u003Ctd>Finding analyzed\u003C/td>\u003Ctd>Summarizes root causes, suggests actions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Implementing\u003C/strong>\u003C/td>\u003Ctd>Actions defined\u003C/td>\u003Ctd>Tracks progress, projects improvement\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"5-persistence-pipeline\">5. Persistence Pipeline\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#5-persistence-pipeline\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Persistence Pipeline”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph State[\"Application State\"]\n AS[\"AnalysisState\"]\n end\n\n subgraph Local[\"Local Storage (all platforms)\"]\n IDB[(\"IndexedDB\")]\n end\n\n subgraph Cloud[\"Cloud Storage (Team plan only)\"]\n EA[\"EasyAuth\"] --> TK[\"Access Token\"]\n TK --> GRAPH[\"Graph API\"]\n GRAPH --> OD[(\"OneDrive\")]\n end\n\n AS -->|\"Dexie.js\"| IDB\n AS -->|\"StorageProvider\"| EA\n IDB <-->|\"Bi-directional sync\"| OD\n\n style Cloud fill:#f0f9ff,stroke:#3b82f6\n\u003C/pre>\n\u003Cp>\u003Ccode dir=\"auto\">AnalysisState\u003C/code> is the single serializable shape that captures the full state of an analysis session. Key fields for persistence:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Field\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">rawData\u003C/code>\u003C/td>\u003Ctd>Original uploaded data rows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">specs\u003C/code>\u003C/td>\u003Ctd>USL, LSL, target specifications\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">filters\u003C/code>\u003C/td>\u003Ctd>Active filter selections\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">filterStack\u003C/code>\u003C/td>\u003Ctd>Ordered \u003Ccode dir=\"auto\">FilterAction[]\u003C/code> drill trail\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">findings\u003C/code>\u003C/td>\u003Ctd>Investigation findings with status\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">viewState\u003C/code>\u003C/td>\u003Ctd>Active tab, focused chart, panel state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">isPerformanceMode\u003C/code>\u003C/td>\u003Ctd>Multi-measure mode flag\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">measureColumns\u003C/code>\u003C/td>\u003Ctd>Selected measure columns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">cpkTarget\u003C/code>\u003C/td>\u003Ctd>Capability target (default 1.33)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"6-filter-recalculation-flow\">6. Filter Recalculation Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#6-filter-recalculation-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Filter Recalculation Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A single filter click triggers a cascade of recalculations through the pipeline:\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[\"User clicks Boxplot category\"] --> B[\"useFilterNavigation.addFilter()\"]\n B --> C[\"DataContext.dispatch( SET_FILTERS )\"]\n C --> D[\"filteredData recomputed\"]\n D --> E[\"calculateStats(filteredData)\"]\n D --> F[\"calculateAnova(filteredData, nextFactor)\"]\n E --> G[\"New StatsResult\"]\n F --> H[\"New AnovaResult\"]\n G --> I[\"All chart hooks recompute\"]\n H --> I\n I --> J[\"All chart components re-render\"]\n J --> K{\"AI enabled?\"}\n K -->|Yes| L[\"Debounce 500ms\"]\n L --> M[\"buildAIContext()\"]\n M --> N[\"NarrativeBar updates\"]\n K -->|No| O[\"Done\"]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-gets-recomputed\">What gets recomputed\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-gets-recomputed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What gets recomputed”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Function / Hook\u003C/th>\u003Cth>Output\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Filter\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useFilterNavigation\u003C/code>\u003C/td>\u003Ctd>Updated \u003Ccode dir=\"auto\">FilterAction[]\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data\u003C/td>\u003Ctd>DataContext reducer\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">filteredData\u003C/code> (subset of \u003Ccode dir=\"auto\">rawData\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Stats\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">calculateStats()\u003C/code>\u003C/td>\u003Ctd>New \u003Ccode dir=\"auto\">StatsResult\u003C/code> (mean, Cpk, control limits)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ANOVA\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">calculateAnova()\u003C/code>\u003C/td>\u003Ctd>New \u003Ccode dir=\"auto\">AnovaResult\u003C/code> (F, p, eta-squared)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>I-Chart\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useIChartData()\u003C/code>\u003C/td>\u003Ctd>New \u003Ccode dir=\"auto\">IChartPoint[]\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useBoxplotData()\u003C/code>\u003C/td>\u003Ctd>New \u003Ccode dir=\"auto\">BoxplotData[]\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useParetoChartData()\u003C/code>\u003C/td>\u003Ctd>New \u003Ccode dir=\"auto\">ParetoItem[]\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Variation\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code>\u003C/td>\u003Ctd>Updated scope fraction and cumulative %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>AI (preview)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">buildAIContext()\u003C/code>\u003C/td>\u003Ctd>Refreshed narrative and insights\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"7-filter-drill-down-sequence-diagram\">7. Filter Drill-Down Sequence Diagram\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#7-filter-drill-down-sequence-diagram\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “7. Filter Drill-Down Sequence Diagram”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Complete round-trip from user click to updated UI:\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">sequenceDiagram\n participant User\n participant Boxplot\n participant useFilterNavigation\n participant DataContext\n participant Stats as calculateStats\n participant ANOVA as calculateAnova\n participant Charts as Chart hooks\n participant AI as AI layer (debounced)\n\n User->>Boxplot: Click category bar\n Boxplot->>useFilterNavigation: addFilter(factor, value)\n useFilterNavigation->>DataContext: dispatch SET_FILTERS\n DataContext->>DataContext: Recompute filteredData\n\n par Statistics\n DataContext->>Stats: calculateStats(filteredData, specs)\n Stats-->>DataContext: StatsResult\n and ANOVA\n DataContext->>ANOVA: calculateAnova(filteredData, nextFactor)\n ANOVA-->>DataContext: AnovaResult\n end\n\n DataContext-->>Charts: New props (filteredData, stats, anova)\n Charts->>Charts: useIChartData + useBoxplotData + useParetoChartData\n\n Charts-->>Boxplot: Re-render with drill-down data\n Note over Boxplot: Next factor level displayed\n\n opt AI preview enabled\n DataContext-->>AI: AIContext (debounced 500ms)\n AI-->>User: NarrativeBar update\n end\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"8-see-also\">8. See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#8-see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “8. See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"data-flow.md\">Data Flow\u003C/a> — detailed input/validation stages and platform-specific flows\u003C/li>\n\u003Cli>\u003Ca href=\"system-map.md\">System Map\u003C/a> — package topology and dependency graph\u003C/li>\n\u003Cli>\u003Ca href=\"component-patterns.md\">Component Patterns\u003C/a> — hook integration details and DataContext structure\u003C/li>\n\u003Cli>\u003Ca href=\"../../03-features/workflows/investigation-lifecycle-map.md\">Investigation Lifecycle Map\u003C/a> — IDEOI phases and CoScout behavior\u003C/li>\n\u003Cli>\u003Ca href=\"../../03-features/workflows/investigation-to-action.md\">Investigation to Action\u003C/a> — findings workflow specification\u003C/li>\n\u003C/ul>", + { + "headings": 171, + "localImagePaths": 228, + "remoteImagePaths": 229, + "frontmatter": 230, + "imagePaths": 232 + }, + [172, 174, 177, 180, 183, 186, 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225], + { "depth": 30, "slug": 173, "text": 160 }, + "data-pipeline-map", + { "depth": 33, "slug": 175, "text": 176 }, + "1-full-pipeline-overview", + "1. Full Pipeline Overview", + { "depth": 33, "slug": 178, "text": 179 }, + "2-typescript-interfaces-at-boundaries", + "2. TypeScript Interfaces at Boundaries", + { "depth": 79, "slug": 181, "text": 182 }, + "input-boundary", + "Input Boundary", + { "depth": 79, "slug": 184, "text": 185 }, + "column-detection-boundary", + "Column Detection Boundary", + { "depth": 79, "slug": 187, "text": 188 }, + "validation-boundary", + "Validation Boundary", + { "depth": 79, "slug": 190, "text": 191 }, + "stats-boundary", + "Stats Boundary", + { "depth": 79, "slug": 193, "text": 194 }, + "anova-boundary", + "ANOVA Boundary", + { "depth": 79, "slug": 196, "text": 197 }, + "filter-boundary", + "Filter Boundary", + { "depth": 79, "slug": 199, "text": 200 }, + "finding-boundary", + "Finding Boundary", + { "depth": 79, "slug": 202, "text": 203 }, + "persistence-boundary", + "Persistence Boundary", + { "depth": 33, "slug": 205, "text": 206 }, + "3-stats-pipeline-swim-lane", + "3. Stats Pipeline Swim Lane", + { "depth": 33, "slug": 208, "text": 209 }, + "4-ai-pipeline-swim-lane", + "4. AI Pipeline Swim Lane", + { "depth": 79, "slug": 211, "text": 212 }, + "ideoi-phase-mapping", + "IDEOI Phase Mapping", + { "depth": 33, "slug": 214, "text": 215 }, + "5-persistence-pipeline", + "5. Persistence Pipeline", + { "depth": 33, "slug": 217, "text": 218 }, + "6-filter-recalculation-flow", + "6. Filter Recalculation Flow", + { "depth": 79, "slug": 220, "text": 221 }, + "what-gets-recomputed", + "What gets recomputed", + { "depth": 33, "slug": 223, "text": 224 }, + "7-filter-drill-down-sequence-diagram", + "7. Filter Drill-Down Sequence Diagram", + { "depth": 33, "slug": 226, "text": 227 }, + "8-see-also", + "8. See Also", + [], + [], + { "title": 160, "description": 161, "journey-phase": 231 }, + [155], + [], + "05-technical/architecture/component-map", + { "id": 233, "data": 235, "body": 241, "filePath": 242, "digest": 243, "rendered": 244 }, + { + "title": 236, + "description": 237, + "editUrl": 16, + "head": 238, + "template": 18, + "sidebar": 239, + "pagefind": 16, + "draft": 20 + }, + "Component Map", + "L3 component views per package — internal modules and their responsibilities", + [], + { "hidden": 20, "attrs": 240 }, + {}, + "# Component Map\n\n\u003C!-- journey-phase: [all] -->\n\nL3 component decomposition for each VariScout package. These diagrams are manually maintained Mermaid translations of the canonical architecture model in [`docs/architecture/likec4/`](../../architecture/likec4/).\n\n## Package Overview\n\nAll packages and their internal module counts at a glance.\n\n```mermaid\nflowchart LR\n subgraph core[\"@variscout/core (9 modules)\"]\n direction TB\n c1[\"Statistics Engine\"]\n c2[\"CSV/Excel Parser\"]\n c3[\"Tier System\"]\n c4[\"Navigation\"]\n c5[\"Types\"]\n c6[\"Variation Analysis\"]\n c7[\"Glossary\"]\n c8[\"Export\"]\n c9[\"Utilities\"]\n end\n\n subgraph charts[\"@variscout/charts (14 components)\"]\n direction TB\n ch1[\"6 Standard Charts\"]\n ch2[\"4 Performance Charts\"]\n ch3[\"4 Supporting\"]\n end\n\n subgraph hooks[\"@variscout/hooks (13 hooks)\"]\n direction TB\n h1[\"2 State\"]\n h2[\"2 Navigation\"]\n h3[\"6 Chart Data\"]\n h4[\"1 Export\"]\n h5[\"3 Tracking\"]\n end\n\n subgraph ui[\"@variscout/ui (52 components)\"]\n direction TB\n u1[\"10 Input\"]\n u2[\"4 Data Display\"]\n u3[\"8 Analysis\"]\n u4[\"6 Chart Wrappers\"]\n u5[\"4 Navigation\"]\n u6[\"8 Findings\"]\n u7[\"2 Simulation\"]\n u8[\"5 Dashboard\"]\n u9[\"3 Utilities\"]\n end\n\n subgraph data[\"@variscout/data (4 datasets)\"]\n direction TB\n d1[\"coffee\"]\n d2[\"journey\"]\n d3[\"bottleneck\"]\n d4[\"sachets\"]\n end\n\n charts --> core\n hooks --> core\n ui --> core\n ui --> hooks\n ui --> charts\n```\n\n---\n\n## @variscout/core\n\nPure TypeScript — zero React dependencies. The foundation layer that all other packages depend on.\n\n```mermaid\nflowchart TB\n subgraph core[\"@variscout/core\"]\n stats[\"Statistics Engine\u003Cbr/>\u003Csmall>stats.ts\u003C/small>\u003Cbr/>\u003Csmall>calculateStats, mean, stddev,\u003Cbr/>Cp, Cpk, ANOVA, Nelson rules\u003C/small>\"]\n parser[\"CSV/Excel Parser\u003Cbr/>\u003Csmall>parser.ts\u003C/small>\u003Cbr/>\u003Csmall>parseCSV, parseExcel,\u003Cbr/>detectColumns, keyword detection\u003C/small>\"]\n tier[\"Tier System\u003Cbr/>\u003Csmall>tier.ts\u003C/small>\u003Cbr/>\u003Csmall>getTier, isPaidTier,\u003Cbr/>channel limits, plan gating\u003C/small>\"]\n nav[\"Navigation\u003Cbr/>\u003Csmall>navigation.ts\u003C/small>\u003Cbr/>\u003Csmall>drill path, filter types,\u003Cbr/>breadcrumb state\u003C/small>\"]\n types[\"Types\u003Cbr/>\u003Csmall>types.ts\u003C/small>\u003Cbr/>\u003Csmall>StatsResult, DataRow,\u003Cbr/>Finding, AnalysisState\u003C/small>\"]\n variation[\"Variation Analysis\u003Cbr/>\u003Csmall>variation/\u003C/small>\u003Cbr/>\u003Csmall>contributions, simulation,\u003Cbr/>decomposition, Total SS\u003C/small>\"]\n glossary[\"Glossary\u003Cbr/>\u003Csmall>glossary/\u003C/small>\u003Cbr/>\u003Csmall>terms, types,\u003Cbr/>concept definitions\u003C/small>\"]\n export[\"Export\u003Cbr/>\u003Csmall>export/\u003C/small>\u003Cbr/>\u003Csmall>CSV export,\u003Cbr/>chart data formatting\u003C/small>\"]\n utils[\"Utilities\u003Cbr/>\u003Csmall>utils/\u003C/small>\u003Cbr/>\u003Csmall>EXIF stripping,\u003Cbr/>data transforms\u003C/small>\"]\n end\n\n stats --> types\n parser --> types\n variation --> stats\n variation --> types\n export --> types\n glossary --> types\n nav --> types\n tier --> types\n```\n\n**Key dependency rule:** `types.ts` is the shared foundation. Statistics and variation analysis are the most complex modules; everything else is relatively independent.\n\n---\n\n## @variscout/charts\n\nReact + Visx chart components. Every chart exports both a responsive wrapper (uses `withParentSize`) and a `*Base` variant for explicit sizing.\n\n```mermaid\nflowchart TB\n subgraph standard[\"Standard Charts\"]\n ichart[\"IChart\u003Cbr/>\u003Csmall>Individual control chart\u003Cbr/>UCL/LCL, Nelson violations\u003C/small>\"]\n boxplot[\"Boxplot\u003Cbr/>\u003Csmall>Category boxplot\u003Cbr/>violin mode, sorting, annotations\u003C/small>\"]\n pareto[\"ParetoChart\u003Cbr/>\u003Csmall>Pareto ranking\u003Cbr/>cumulative line, annotations\u003C/small>\"]\n capability[\"CapabilityHistogram\u003Cbr/>\u003Csmall>Process capability\u003Cbr/>normal curve overlay\u003C/small>\"]\n probability[\"ProbabilityPlot\u003Cbr/>\u003Csmall>Normal probability\u003Cbr/>distribution assessment\u003C/small>\"]\n scatter[\"ScatterPlot\u003Cbr/>\u003Csmall>X-Y scatter\u003Cbr/>trend line\u003C/small>\"]\n end\n\n subgraph performance[\"Performance Charts (multi-measure)\"]\n perf_ichart[\"PerformanceIChart\u003Cbr/>\u003Csmall>Cpk scatter by channel\u003C/small>\"]\n perf_boxplot[\"PerformanceBoxplot\u003Cbr/>\u003Csmall>Distribution comparison\u003Cbr/>max 5 channels\u003C/small>\"]\n perf_pareto[\"PerformancePareto\u003Cbr/>\u003Csmall>Cpk ranking\u003Cbr/>max 20 channels\u003C/small>\"]\n perf_capability[\"PerformanceCapability\u003Cbr/>\u003Csmall>Single channel histogram\u003C/small>\"]\n end\n\n subgraph supporting[\"Supporting Components\"]\n stats_table[\"BoxplotStatsTable\u003Cbr/>\u003Csmall>Summary statistics table\u003C/small>\"]\n legend[\"ChartLegend\"]\n signature[\"ChartSignature\u003Cbr/>\u003Csmall>Branding for exports\u003C/small>\"]\n sourcebar[\"ChartSourceBar\u003Cbr/>\u003Csmall>Footer branding (free tier)\u003C/small>\"]\n end\n\n subgraph deps[\"@variscout/core\"]\n core_stats[\"Statistics Engine\"]\n core_types[\"Types\"]\n end\n\n standard --> core_types\n standard --> core_stats\n performance --> core_types\n performance --> core_stats\n supporting --> core_types\n```\n\n---\n\n## @variscout/hooks\n\nShared React hooks organized by concern. Depends on `@variscout/core` for types, statistics utilities, and tier logic.\n\n```mermaid\nflowchart TB\n subgraph state[\"State Hooks\"]\n datastate[\"useDataState\u003Cbr/>\u003Csmall>Shared DataContext\u003Cbr/>state management\u003C/small>\"]\n usetier[\"useTier\u003Cbr/>\u003Csmall>License tier state\u003Cbr/>and limits\u003C/small>\"]\n end\n\n subgraph navigation[\"Navigation Hooks\"]\n filternav[\"useFilterNavigation\u003Cbr/>\u003Csmall>Multi-select filters\u003Cbr/>breadcrumbs, drill trail\u003C/small>\"]\n keyboard[\"useKeyboardNavigation\u003Cbr/>\u003Csmall>Arrow key focus\u003Cbr/>management\u003C/small>\"]\n end\n\n subgraph chartdata[\"Chart Data Hooks\"]\n chartscale[\"useChartScale\u003Cbr/>\u003Csmall>Y-axis scale calculation\u003C/small>\"]\n boxplotdata[\"useBoxplotData\u003Cbr/>\u003Csmall>d3 boxplot computation\u003C/small>\"]\n ichartdata[\"useIChartData\u003Cbr/>\u003Csmall>I-Chart data transform\u003C/small>\"]\n margins[\"useResponsiveChartMargins\u003Cbr/>\u003Csmall>Dynamic margins\u003C/small>\"]\n paretodata[\"useParetoChartData\u003Cbr/>\u003Csmall>Pareto data prep\u003C/small>\"]\n dashdata[\"useDashboardComputedData\u003Cbr/>\u003Csmall>Dashboard stats\u003C/small>\"]\n end\n\n subgraph exporthooks[\"Export Hooks\"]\n chartcopy[\"useChartCopy\u003Cbr/>\u003Csmall>Clipboard, PNG, SVG\u003C/small>\"]\n end\n\n subgraph tracking[\"Tracking Hooks\"]\n vartrack[\"useVariationTracking\u003Cbr/>\u003Csmall>Cumulative Total SS\u003Cbr/>scope tracking\u003C/small>\"]\n annotation[\"useAnnotationMode\u003Cbr/>\u003Csmall>Chart annotation state\u003C/small>\"]\n violations[\"useControlViolations\u003Cbr/>\u003Csmall>Control chart violation\u003Cbr/>detection\u003C/small>\"]\n end\n\n subgraph deps[\"@variscout/core\"]\n core_types[\"Types\"]\n core_stats[\"Statistics Engine\"]\n core_tier[\"Tier System\"]\n end\n\n state --> core_types\n state --> core_tier\n navigation --> core_types\n chartdata --> core_types\n chartdata --> core_stats\n tracking --> core_types\n tracking --> core_stats\n```\n\n---\n\n## @variscout/ui\n\n52 shared UI components across 9 categories. Uses the `colorScheme` pattern with `defaultScheme` semantic tokens. Depends on core, hooks, and charts.\n\n```mermaid\nflowchart TB\n subgraph input[\"Input (10)\"]\n columnmapping[\"ColumnMapping\"]\n createfactor[\"CreateFactorModal\"]\n measuresel[\"MeasureColumnSelector\"]\n chartype[\"CharacteristicTypeSelector\"]\n manualentry[\"ManualEntryBase\"]\n manualsetup[\"ManualEntrySetupBase\"]\n slider[\"Slider\"]\n speceditor[\"SpecEditor\"]\n specspopover[\"SpecsPopover\"]\n pastescreen[\"PasteScreenBase\"]\n end\n\n subgraph datadisplay[\"Data Display (4)\"]\n dataquality[\"DataQualityBanner\"]\n datatable[\"DataTableBase\"]\n perfdetected[\"PerformanceDetectedModal\"]\n mobilesheet[\"MobileCategorySheet\"]\n end\n\n subgraph analysis[\"Analysis (8)\"]\n anova[\"AnovaResults\"]\n statspanel[\"StatsPanelBase\"]\n variationbar[\"VariationBar\"]\n yaxispopover[\"YAxisPopover\"]\n axiseditor[\"AxisEditor\"]\n factorsel[\"FactorSelector\"]\n investprompt[\"InvestigationPrompt\"]\n boxplottoggle[\"BoxplotDisplayToggle\"]\n end\n\n subgraph chartwrappers[\"Chart Wrappers (6)\"]\n annotationlayer[\"ChartAnnotationLayer\"]\n annotationmenu[\"AnnotationContextMenu\"]\n chartcard[\"ChartCard\"]\n downloadmenu[\"ChartDownloadMenu\"]\n edittitle[\"EditableChartTitle\"]\n focusedview[\"FocusedChartViewBase\"]\n end\n\n subgraph navcomps[\"Navigation (4)\"]\n breadcrumb[\"FilterBreadcrumb\"]\n chipdropdown[\"FilterChipDropdown\"]\n contextbar[\"FilterContextBar\"]\n selectionpanel[\"SelectionPanel\"]\n end\n\n subgraph findings[\"Findings (8)\"]\n findingslog[\"FindingsLog\"]\n findingcard[\"FindingCard\"]\n findingeditor[\"FindingEditor\"]\n findingstatus[\"FindingStatusBadge\"]\n findingcomments[\"FindingComments\"]\n findingboard[\"FindingBoardView\"]\n findingspanel[\"FindingsPanel\"]\n findingswindow[\"FindingsWindow\"]\n end\n\n subgraph simulation[\"Simulation (2)\"]\n whatif[\"WhatIfSimulator\"]\n whatifpage[\"WhatIfPageBase\"]\n end\n\n subgraph dashboard[\"Dashboard (5)\"]\n dashgrid[\"DashboardGrid\"]\n dashcard[\"DashboardChartCard\"]\n focusedcard[\"FocusedChartCard\"]\n focusedoverlay[\"FocusedViewOverlay\"]\n settingspanel[\"SettingsPanelBase\"]\n end\n\n subgraph utilities[\"Utilities (3)\"]\n helptooltip[\"HelpTooltip\"]\n upgradeprompt[\"UpgradePrompt\"]\n errorboundary[\"ErrorBoundary\"]\n end\n```\n\n### UI dependency flow\n\nThe UI package composes all three lower-level packages:\n\n```mermaid\nflowchart LR\n ui[\"@variscout/ui\u003Cbr/>(52 components)\"]\n core[\"@variscout/core\u003Cbr/>types, tier\"]\n hooks[\"@variscout/hooks\u003Cbr/>state, navigation, data\"]\n charts[\"@variscout/charts\u003Cbr/>chart components\"]\n\n ui --> core\n ui --> hooks\n ui --> charts\n```\n\n---\n\n## @variscout/data\n\nPre-computed sample datasets. No internal package dependencies — pure TypeScript data files consumed by apps and website.\n\n```mermaid\nflowchart TB\n subgraph data[\"@variscout/data\"]\n coffee[\"coffeeSample\u003Cbr/>\u003Csmall>Extraction temperature\u003Cbr/>multi-factor\u003C/small>\"]\n journey[\"journeySample\u003Cbr/>\u003Csmall>Customer journey\u003Cbr/>staged analysis\u003C/small>\"]\n bottleneck[\"bottleneckSample\u003Cbr/>\u003Csmall>Production bottleneck\u003Cbr/>multi-measure\u003C/small>\"]\n sachets[\"sachetsSample\u003Cbr/>\u003Csmall>Packaging weight\u003Cbr/>basic SPC\u003C/small>\"]\n end\n\n pwa[\"apps/pwa\"] --> data\n azure[\"apps/azure\"] --> data\n website[\"apps/website\"] --> data\n```\n\n---\n\n## Cross-Package Component Flow\n\nHow components compose across package boundaries during a typical analysis session:\n\n```mermaid\nflowchart TB\n subgraph app[\"App Layer (pwa / azure)\"]\n dashboard[\"Dashboard\"]\n datacontext[\"DataContext\"]\n end\n\n subgraph ui_layer[\"@variscout/ui\"]\n dashgrid[\"DashboardGrid\"]\n chartcard[\"DashboardChartCard\"]\n statspanel[\"StatsPanelBase\"]\n filternav_ui[\"FilterBreadcrumb\"]\n findingslog[\"FindingsLog\"]\n end\n\n subgraph hooks_layer[\"@variscout/hooks\"]\n datastate[\"useDataState\"]\n filternav[\"useFilterNavigation\"]\n boxplotdata[\"useBoxplotData\"]\n chartscale[\"useChartScale\"]\n end\n\n subgraph charts_layer[\"@variscout/charts\"]\n ichart[\"IChart\"]\n boxplot[\"Boxplot\"]\n pareto[\"ParetoChart\"]\n end\n\n subgraph core_layer[\"@variscout/core\"]\n stats[\"calculateStats\"]\n parser[\"parseCSV\"]\n types[\"Types\"]\n end\n\n dashboard --> dashgrid\n dashboard --> chartcard\n dashboard --> statspanel\n dashboard --> filternav_ui\n dashboard --> findingslog\n\n datacontext --> datastate\n filternav_ui --> filternav\n\n chartcard --> ichart\n chartcard --> boxplot\n chartcard --> pareto\n\n boxplotdata --> stats\n chartscale --> types\n datastate --> parser\n datastate --> types\n ichart --> types\n boxplot --> types\n pareto --> types\n```\n\n---\n\n## Source of Truth\n\nThe canonical architecture model is defined in **LikeC4**:\n\n```\ndocs/architecture/likec4/\n├── model.c4 — L1 context + L2 containers + relationships\n├── core.c4 — L3 @variscout/core components\n├── charts.c4 — L3 @variscout/charts components\n├── hooks.c4 — L3 @variscout/hooks components\n├── ui.c4 — L3 @variscout/ui components\n└── views.c4 — View definitions (L1-L3)\n```\n\nTo render or export:\n\n- **Interactive browser:** `pnpm docs:c4:serve`\n- **Export to Mermaid:** `pnpm docs:c4`\n\nThe Mermaid diagrams in this file are manually maintained translations. When the LikeC4 model changes, update these diagrams to match.\n\n## See Also\n\n- [system-map.md](system-map.md) -- L1 Context + L2 Container diagrams\n- [shared-packages.md](shared-packages.md) -- Detailed package APIs and export inventories\n- [component-patterns.md](component-patterns.md) -- React component conventions and hook patterns\n- [data-flow.md](data-flow.md) -- End-to-end data pipeline\n- [data-pipeline-map.md](data-pipeline-map.md) -- Step-by-step data transformation pipeline", + "src/content/docs/05-technical/architecture/component-map.md", + "add33844162747fb", + { "html": 245, "metadata": 246 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"component-map\">Component Map\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#component-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Component Map”\u003C/span>\u003C/a>\u003C/div>\n\u003C!-- journey-phase: [all] -->\n\u003Cp>L3 component decomposition for each VariScout package. These diagrams are manually maintained Mermaid translations of the canonical architecture model in \u003Ca href=\"../../architecture/likec4/\">\u003Ccode dir=\"auto\">docs/architecture/likec4/\u003C/code>\u003C/a>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"package-overview\">Package Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#package-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Package Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All packages and their internal module counts at a glance.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n subgraph core[\"@variscout/core (9 modules)\"]\n direction TB\n c1[\"Statistics Engine\"]\n c2[\"CSV/Excel Parser\"]\n c3[\"Tier System\"]\n c4[\"Navigation\"]\n c5[\"Types\"]\n c6[\"Variation Analysis\"]\n c7[\"Glossary\"]\n c8[\"Export\"]\n c9[\"Utilities\"]\n end\n\n subgraph charts[\"@variscout/charts (14 components)\"]\n direction TB\n ch1[\"6 Standard Charts\"]\n ch2[\"4 Performance Charts\"]\n ch3[\"4 Supporting\"]\n end\n\n subgraph hooks[\"@variscout/hooks (13 hooks)\"]\n direction TB\n h1[\"2 State\"]\n h2[\"2 Navigation\"]\n h3[\"6 Chart Data\"]\n h4[\"1 Export\"]\n h5[\"3 Tracking\"]\n end\n\n subgraph ui[\"@variscout/ui (52 components)\"]\n direction TB\n u1[\"10 Input\"]\n u2[\"4 Data Display\"]\n u3[\"8 Analysis\"]\n u4[\"6 Chart Wrappers\"]\n u5[\"4 Navigation\"]\n u6[\"8 Findings\"]\n u7[\"2 Simulation\"]\n u8[\"5 Dashboard\"]\n u9[\"3 Utilities\"]\n end\n\n subgraph data[\"@variscout/data (4 datasets)\"]\n direction TB\n d1[\"coffee\"]\n d2[\"journey\"]\n d3[\"bottleneck\"]\n d4[\"sachets\"]\n end\n\n charts --> core\n hooks --> core\n ui --> core\n ui --> hooks\n ui --> charts\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscoutcore\">@variscout/core\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutcore\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/core”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pure TypeScript — zero React dependencies. The foundation layer that all other packages depend on.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph core[\"@variscout/core\"]\n stats[\"Statistics Engine<br/><small>stats.ts</small><br/><small>calculateStats, mean, stddev,<br/>Cp, Cpk, ANOVA, Nelson rules</small>\"]\n parser[\"CSV/Excel Parser<br/><small>parser.ts</small><br/><small>parseCSV, parseExcel,<br/>detectColumns, keyword detection</small>\"]\n tier[\"Tier System<br/><small>tier.ts</small><br/><small>getTier, isPaidTier,<br/>channel limits, plan gating</small>\"]\n nav[\"Navigation<br/><small>navigation.ts</small><br/><small>drill path, filter types,<br/>breadcrumb state</small>\"]\n types[\"Types<br/><small>types.ts</small><br/><small>StatsResult, DataRow,<br/>Finding, AnalysisState</small>\"]\n variation[\"Variation Analysis<br/><small>variation/</small><br/><small>contributions, simulation,<br/>decomposition, Total SS</small>\"]\n glossary[\"Glossary<br/><small>glossary/</small><br/><small>terms, types,<br/>concept definitions</small>\"]\n export[\"Export<br/><small>export/</small><br/><small>CSV export,<br/>chart data formatting</small>\"]\n utils[\"Utilities<br/><small>utils/</small><br/><small>EXIF stripping,<br/>data transforms</small>\"]\n end\n\n stats --> types\n parser --> types\n variation --> stats\n variation --> types\n export --> types\n glossary --> types\n nav --> types\n tier --> types\n\u003C/pre>\n\u003Cp>\u003Cstrong>Key dependency rule:\u003C/strong> \u003Ccode dir=\"auto\">types.ts\u003C/code> is the shared foundation. Statistics and variation analysis are the most complex modules; everything else is relatively independent.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscoutcharts\">@variscout/charts\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutcharts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>React + Visx chart components. Every chart exports both a responsive wrapper (uses \u003Ccode dir=\"auto\">withParentSize\u003C/code>) and a \u003Ccode dir=\"auto\">*Base\u003C/code> variant for explicit sizing.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph standard[\"Standard Charts\"]\n ichart[\"IChart<br/><small>Individual control chart<br/>UCL/LCL, Nelson violations</small>\"]\n boxplot[\"Boxplot<br/><small>Category boxplot<br/>violin mode, sorting, annotations</small>\"]\n pareto[\"ParetoChart<br/><small>Pareto ranking<br/>cumulative line, annotations</small>\"]\n capability[\"CapabilityHistogram<br/><small>Process capability<br/>normal curve overlay</small>\"]\n probability[\"ProbabilityPlot<br/><small>Normal probability<br/>distribution assessment</small>\"]\n scatter[\"ScatterPlot<br/><small>X-Y scatter<br/>trend line</small>\"]\n end\n\n subgraph performance[\"Performance Charts (multi-measure)\"]\n perf_ichart[\"PerformanceIChart<br/><small>Cpk scatter by channel</small>\"]\n perf_boxplot[\"PerformanceBoxplot<br/><small>Distribution comparison<br/>max 5 channels</small>\"]\n perf_pareto[\"PerformancePareto<br/><small>Cpk ranking<br/>max 20 channels</small>\"]\n perf_capability[\"PerformanceCapability<br/><small>Single channel histogram</small>\"]\n end\n\n subgraph supporting[\"Supporting Components\"]\n stats_table[\"BoxplotStatsTable<br/><small>Summary statistics table</small>\"]\n legend[\"ChartLegend\"]\n signature[\"ChartSignature<br/><small>Branding for exports</small>\"]\n sourcebar[\"ChartSourceBar<br/><small>Footer branding (free tier)</small>\"]\n end\n\n subgraph deps[\"@variscout/core\"]\n core_stats[\"Statistics Engine\"]\n core_types[\"Types\"]\n end\n\n standard --> core_types\n standard --> core_stats\n performance --> core_types\n performance --> core_stats\n supporting --> core_types\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscouthooks\">@variscout/hooks\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscouthooks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/hooks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shared React hooks organized by concern. Depends on \u003Ccode dir=\"auto\">@variscout/core\u003C/code> for types, statistics utilities, and tier logic.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph state[\"State Hooks\"]\n datastate[\"useDataState<br/><small>Shared DataContext<br/>state management</small>\"]\n usetier[\"useTier<br/><small>License tier state<br/>and limits</small>\"]\n end\n\n subgraph navigation[\"Navigation Hooks\"]\n filternav[\"useFilterNavigation<br/><small>Multi-select filters<br/>breadcrumbs, drill trail</small>\"]\n keyboard[\"useKeyboardNavigation<br/><small>Arrow key focus<br/>management</small>\"]\n end\n\n subgraph chartdata[\"Chart Data Hooks\"]\n chartscale[\"useChartScale<br/><small>Y-axis scale calculation</small>\"]\n boxplotdata[\"useBoxplotData<br/><small>d3 boxplot computation</small>\"]\n ichartdata[\"useIChartData<br/><small>I-Chart data transform</small>\"]\n margins[\"useResponsiveChartMargins<br/><small>Dynamic margins</small>\"]\n paretodata[\"useParetoChartData<br/><small>Pareto data prep</small>\"]\n dashdata[\"useDashboardComputedData<br/><small>Dashboard stats</small>\"]\n end\n\n subgraph exporthooks[\"Export Hooks\"]\n chartcopy[\"useChartCopy<br/><small>Clipboard, PNG, SVG</small>\"]\n end\n\n subgraph tracking[\"Tracking Hooks\"]\n vartrack[\"useVariationTracking<br/><small>Cumulative Total SS<br/>scope tracking</small>\"]\n annotation[\"useAnnotationMode<br/><small>Chart annotation state</small>\"]\n violations[\"useControlViolations<br/><small>Control chart violation<br/>detection</small>\"]\n end\n\n subgraph deps[\"@variscout/core\"]\n core_types[\"Types\"]\n core_stats[\"Statistics Engine\"]\n core_tier[\"Tier System\"]\n end\n\n state --> core_types\n state --> core_tier\n navigation --> core_types\n chartdata --> core_types\n chartdata --> core_stats\n tracking --> core_types\n tracking --> core_stats\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscoutui\">@variscout/ui\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutui\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/ui”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>52 shared UI components across 9 categories. Uses the \u003Ccode dir=\"auto\">colorScheme\u003C/code> pattern with \u003Ccode dir=\"auto\">defaultScheme\u003C/code> semantic tokens. Depends on core, hooks, and charts.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph input[\"Input (10)\"]\n columnmapping[\"ColumnMapping\"]\n createfactor[\"CreateFactorModal\"]\n measuresel[\"MeasureColumnSelector\"]\n chartype[\"CharacteristicTypeSelector\"]\n manualentry[\"ManualEntryBase\"]\n manualsetup[\"ManualEntrySetupBase\"]\n slider[\"Slider\"]\n speceditor[\"SpecEditor\"]\n specspopover[\"SpecsPopover\"]\n pastescreen[\"PasteScreenBase\"]\n end\n\n subgraph datadisplay[\"Data Display (4)\"]\n dataquality[\"DataQualityBanner\"]\n datatable[\"DataTableBase\"]\n perfdetected[\"PerformanceDetectedModal\"]\n mobilesheet[\"MobileCategorySheet\"]\n end\n\n subgraph analysis[\"Analysis (8)\"]\n anova[\"AnovaResults\"]\n statspanel[\"StatsPanelBase\"]\n variationbar[\"VariationBar\"]\n yaxispopover[\"YAxisPopover\"]\n axiseditor[\"AxisEditor\"]\n factorsel[\"FactorSelector\"]\n investprompt[\"InvestigationPrompt\"]\n boxplottoggle[\"BoxplotDisplayToggle\"]\n end\n\n subgraph chartwrappers[\"Chart Wrappers (6)\"]\n annotationlayer[\"ChartAnnotationLayer\"]\n annotationmenu[\"AnnotationContextMenu\"]\n chartcard[\"ChartCard\"]\n downloadmenu[\"ChartDownloadMenu\"]\n edittitle[\"EditableChartTitle\"]\n focusedview[\"FocusedChartViewBase\"]\n end\n\n subgraph navcomps[\"Navigation (4)\"]\n breadcrumb[\"FilterBreadcrumb\"]\n chipdropdown[\"FilterChipDropdown\"]\n contextbar[\"FilterContextBar\"]\n selectionpanel[\"SelectionPanel\"]\n end\n\n subgraph findings[\"Findings (8)\"]\n findingslog[\"FindingsLog\"]\n findingcard[\"FindingCard\"]\n findingeditor[\"FindingEditor\"]\n findingstatus[\"FindingStatusBadge\"]\n findingcomments[\"FindingComments\"]\n findingboard[\"FindingBoardView\"]\n findingspanel[\"FindingsPanel\"]\n findingswindow[\"FindingsWindow\"]\n end\n\n subgraph simulation[\"Simulation (2)\"]\n whatif[\"WhatIfSimulator\"]\n whatifpage[\"WhatIfPageBase\"]\n end\n\n subgraph dashboard[\"Dashboard (5)\"]\n dashgrid[\"DashboardGrid\"]\n dashcard[\"DashboardChartCard\"]\n focusedcard[\"FocusedChartCard\"]\n focusedoverlay[\"FocusedViewOverlay\"]\n settingspanel[\"SettingsPanelBase\"]\n end\n\n subgraph utilities[\"Utilities (3)\"]\n helptooltip[\"HelpTooltip\"]\n upgradeprompt[\"UpgradePrompt\"]\n errorboundary[\"ErrorBoundary\"]\n end\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ui-dependency-flow\">UI dependency flow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ui-dependency-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “UI dependency flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The UI package composes all three lower-level packages:\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n ui[\"@variscout/ui<br/>(52 components)\"]\n core[\"@variscout/core<br/>types, tier\"]\n hooks[\"@variscout/hooks<br/>state, navigation, data\"]\n charts[\"@variscout/charts<br/>chart components\"]\n\n ui --> core\n ui --> hooks\n ui --> charts\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscoutdata\">@variscout/data\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutdata\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pre-computed sample datasets. No internal package dependencies — pure TypeScript data files consumed by apps and website.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph data[\"@variscout/data\"]\n coffee[\"coffeeSample<br/><small>Extraction temperature<br/>multi-factor</small>\"]\n journey[\"journeySample<br/><small>Customer journey<br/>staged analysis</small>\"]\n bottleneck[\"bottleneckSample<br/><small>Production bottleneck<br/>multi-measure</small>\"]\n sachets[\"sachetsSample<br/><small>Packaging weight<br/>basic SPC</small>\"]\n end\n\n pwa[\"apps/pwa\"] --> data\n azure[\"apps/azure\"] --> data\n website[\"apps/website\"] --> data\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-package-component-flow\">Cross-Package Component Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-package-component-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Package Component Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How components compose across package boundaries during a typical analysis session:\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph app[\"App Layer (pwa / azure)\"]\n dashboard[\"Dashboard\"]\n datacontext[\"DataContext\"]\n end\n\n subgraph ui_layer[\"@variscout/ui\"]\n dashgrid[\"DashboardGrid\"]\n chartcard[\"DashboardChartCard\"]\n statspanel[\"StatsPanelBase\"]\n filternav_ui[\"FilterBreadcrumb\"]\n findingslog[\"FindingsLog\"]\n end\n\n subgraph hooks_layer[\"@variscout/hooks\"]\n datastate[\"useDataState\"]\n filternav[\"useFilterNavigation\"]\n boxplotdata[\"useBoxplotData\"]\n chartscale[\"useChartScale\"]\n end\n\n subgraph charts_layer[\"@variscout/charts\"]\n ichart[\"IChart\"]\n boxplot[\"Boxplot\"]\n pareto[\"ParetoChart\"]\n end\n\n subgraph core_layer[\"@variscout/core\"]\n stats[\"calculateStats\"]\n parser[\"parseCSV\"]\n types[\"Types\"]\n end\n\n dashboard --> dashgrid\n dashboard --> chartcard\n dashboard --> statspanel\n dashboard --> filternav_ui\n dashboard --> findingslog\n\n datacontext --> datastate\n filternav_ui --> filternav\n\n chartcard --> ichart\n chartcard --> boxplot\n chartcard --> pareto\n\n boxplotdata --> stats\n chartscale --> types\n datastate --> parser\n datastate --> types\n ichart --> types\n boxplot --> types\n pareto --> types\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"source-of-truth\">Source of Truth\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#source-of-truth\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Source of Truth”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The canonical architecture model is defined in \u003Cstrong>LikeC4\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">docs/architecture/likec4/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── model.c4 — L1 context + L2 containers + relationships\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── core.c4 — L3 @variscout/core components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── charts.c4 — L3 @variscout/charts components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── hooks.c4 — L3 @variscout/hooks components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── ui.c4 — L3 @variscout/ui components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── views.c4 — View definitions (L1-L3)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"docs/architecture/likec4/├── model.c4 — L1 context + L2 containers + relationships├── core.c4 — L3 @variscout/core components├── charts.c4 — L3 @variscout/charts components├── hooks.c4 — L3 @variscout/hooks components├── ui.c4 — L3 @variscout/ui components└── views.c4 — View definitions (L1-L3)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>To render or export:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Interactive browser:\u003C/strong> \u003Ccode dir=\"auto\">pnpm docs:c4:serve\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Export to Mermaid:\u003C/strong> \u003Ccode dir=\"auto\">pnpm docs:c4\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>The Mermaid diagrams in this file are manually maintained translations. When the LikeC4 model changes, update these diagrams to match.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"system-map.md\">system-map.md\u003C/a> — L1 Context + L2 Container diagrams\u003C/li>\n\u003Cli>\u003Ca href=\"shared-packages.md\">shared-packages.md\u003C/a> — Detailed package APIs and export inventories\u003C/li>\n\u003Cli>\u003Ca href=\"component-patterns.md\">component-patterns.md\u003C/a> — React component conventions and hook patterns\u003C/li>\n\u003Cli>\u003Ca href=\"data-flow.md\">data-flow.md\u003C/a> — End-to-end data pipeline\u003C/li>\n\u003Cli>\u003Ca href=\"data-pipeline-map.md\">data-pipeline-map.md\u003C/a> — Step-by-step data transformation pipeline\u003C/li>\n\u003C/ul>", + { + "headings": 247, + "localImagePaths": 278, + "remoteImagePaths": 279, + "frontmatter": 280, + "imagePaths": 282 + }, + [248, 250, 253, 256, 259, 262, 265, 268, 271, 274, 277], + { "depth": 30, "slug": 249, "text": 236 }, + "component-map", + { "depth": 33, "slug": 251, "text": 252 }, + "package-overview", + "Package Overview", + { "depth": 33, "slug": 254, "text": 255 }, + "variscoutcore", + "@variscout/core", + { "depth": 33, "slug": 257, "text": 258 }, + "variscoutcharts", + "@variscout/charts", + { "depth": 33, "slug": 260, "text": 261 }, + "variscouthooks", + "@variscout/hooks", + { "depth": 33, "slug": 263, "text": 264 }, + "variscoutui", + "@variscout/ui", + { "depth": 79, "slug": 266, "text": 267 }, + "ui-dependency-flow", + "UI dependency flow", + { "depth": 33, "slug": 269, "text": 270 }, + "variscoutdata", + "@variscout/data", + { "depth": 33, "slug": 272, "text": 273 }, + "cross-package-component-flow", + "Cross-Package Component Flow", + { "depth": 33, "slug": 275, "text": 276 }, + "source-of-truth", + "Source of Truth", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 236, "description": 237, "journey-phase": 281 }, + [155], + [], + "05-technical/architecture/system-map", + { "id": 283, "data": 285, "body": 291, "filePath": 292, "digest": 293, "rendered": 294 }, + { + "title": 286, + "description": 287, + "editUrl": 16, + "head": 288, + "template": 18, + "sidebar": 289, + "pagefind": 16, + "draft": 20 + }, + "System Map", + "Visual architecture overview of VariScout's packages, apps, and external integrations", + [], + { "hidden": 20, "attrs": 290 }, + {}, + "# System Map\n\nVisual entry point for understanding VariScout's architecture. Start here, then drill into component-level docs linked below.\n\n## Context Diagram (C4 L1)\n\nWho uses VariScout and what external systems does it touch?\n\n```mermaid\nC4Context\n title VariScout System Context\n\n Person(analyst, \"Quality Analyst\", \"Analyses process variation using control charts, capability indices, and Pareto rankings\")\n\n System(variscout, \"VariScout\", \"Offline-first variation analysis tool (PWA + Azure App)\")\n\n System_Ext(azuread, \"Azure AD\", \"EasyAuth identity provider\")\n System_Ext(onedrive, \"Microsoft OneDrive\", \"Cloud file sync via Graph API\")\n System_Ext(teams, \"Microsoft Teams\", \"Channel tabs, SSO, photo capture\")\n System_Ext(aisearch, \"Azure AI Search\", \"AI-powered analysis suggestions\")\n\n Rel(analyst, variscout, \"Uploads data, reviews charts, investigates variation\")\n Rel(variscout, azuread, \"Authenticates via EasyAuth\")\n Rel(variscout, onedrive, \"Syncs projects (Team plan)\")\n Rel(variscout, teams, \"Embeds as channel tab, captures photos\")\n Rel(variscout, aisearch, \"Queries for AI-assisted analysis\")\n```\n\n## Container Diagram (C4 L2)\n\nMonorepo packages, apps, and their dependency relationships.\n\n```mermaid\nflowchart TB\n subgraph apps[\"Apps\"]\n pwa[\"apps/pwa\u003Cbr/>\u003Ci>React + Vite\u003C/i>\u003Cbr/>FREE demo tool\"]\n azure[\"apps/azure\u003Cbr/>\u003Ci>React + Vite\u003C/i>\u003Cbr/>Azure Team App\"]\n website[\"apps/website\u003Cbr/>\u003Ci>Astro + React Islands\u003C/i>\u003Cbr/>Marketing site\"]\n end\n\n subgraph packages[\"Packages\"]\n ui[\"@variscout/ui\u003Cbr/>\u003Ci>Shared UI components\u003C/i>\"]\n hooks[\"@variscout/hooks\u003Cbr/>\u003Ci>Shared React hooks\u003C/i>\"]\n charts[\"@variscout/charts\u003Cbr/>\u003Ci>React + Visx charts\u003C/i>\"]\n core[\"@variscout/core\u003Cbr/>\u003Ci>Pure logic, stats, parser, tier\u003C/i>\"]\n data[\"@variscout/data\u003Cbr/>\u003Ci>Sample datasets\u003C/i>\"]\n end\n\n subgraph infra[\"Infrastructure\"]\n arm[\"infra/mainTemplate.json\u003Cbr/>\u003Ci>ARM template\u003C/i>\"]\n end\n\n subgraph external[\"External Systems\"]\n azuread[\"Azure AD\"]\n onedrive[\"OneDrive\"]\n teams[\"Teams\"]\n aisearch[\"Azure AI Search\"]\n end\n\n %% App dependencies\n pwa --> core & charts & hooks & ui & data\n azure --> core & charts & hooks & ui & data\n website --> charts & data\n\n %% Package dependencies\n ui --> core & hooks & charts\n hooks --> core\n charts --> core\n\n %% External integrations (Azure app only)\n azure -.-> azuread & onedrive & teams & aisearch\n arm -.-> azure\n```\n\n### Key dependency rules\n\n- **Apps** import from packages; packages never import from apps.\n- **`@variscout/core`** has zero React dependencies (pure TypeScript + d3-array, exceljs, papaparse).\n- **`@variscout/data`** has no internal package dependencies.\n- **`@variscout/ui`** is the highest-level shared package, composing core, hooks, and charts.\n\n## Package Responsibilities\n\n| Package | Role | Key exports | Docs |\n|---------|------|-------------|------|\n| `@variscout/core` | Statistics engine, CSV/Excel parser, tier system, glossary, types | `calculateStats`, `parseCSV`, `getTier`, `GlossaryTerm` | [shared-packages.md](shared-packages.md) |\n| `@variscout/charts` | Visx chart components (I-Chart, Boxplot, Pareto, Performance suite) | `IChart`, `Boxplot`, `ParetoChart`, `PerformanceIChart`, `useChartTheme` | [component-patterns.md](component-patterns.md) |\n| `@variscout/data` | Pre-computed sample datasets for demo and testing | `coffeeSample`, `journeySample`, `bottleneckSample` | [shared-packages.md](shared-packages.md) |\n| `@variscout/hooks` | Shared React hooks for state, navigation, data transforms | `useDataState`, `useFilterNavigation`, `useChartScale`, `useTier` | [component-patterns.md](component-patterns.md) |\n| `@variscout/ui` | Shared UI components with colorScheme theming pattern | `StatsPanelBase`, `FindingsLog`, `DashboardGrid`, `WhatIfSimulator` | [component-patterns.md](component-patterns.md) |\n\n## App Responsibilities\n\n| App | Distribution | Technology | Key characteristics |\n|-----|-------------|------------|---------------------|\n| `apps/pwa` | Public URL (free) | React + Vite PWA | Session-only storage, 3 factors max, 50K rows |\n| `apps/azure` | Azure Marketplace | React + Vite + EasyAuth | IndexedDB + OneDrive sync, 6 factors, 100K rows, Teams integration |\n| `apps/website` | Public URL | Astro + React Islands | Static marketing site with embedded chart demos |\n\n## Infrastructure\n\n| Component | Purpose | Docs |\n|-----------|---------|------|\n| `infra/mainTemplate.json` | ARM template for Azure Marketplace Managed Application deployment | [arm-template.md](../../08-products/azure/arm-template.md) |\n| `.github/workflows/deploy-azure-staging.yml` | CI/CD pipeline: build + OIDC deploy to staging | [deployment.md](../implementation/deployment.md) |\n\n## See Also\n\n- [component-map.md](component-map.md) -- L3 component views per package (internal modules)\n- [data-flow.md](data-flow.md) -- End-to-end data pipeline from ingestion to chart rendering\n- [shared-packages.md](shared-packages.md) -- Detailed package APIs and export inventories\n- [monorepo.md](monorepo.md) -- Build system, workspace configuration, import rules\n- [component-patterns.md](component-patterns.md) -- React component conventions and hook patterns\n- [offline-first.md](offline-first.md) -- Storage strategy, sync architecture, conflict resolution\n- [data-pipeline-map.md](data-pipeline-map.md) -- Step-by-step data transformation pipeline\n- [`docs/architecture/likec4/`](../../architecture/likec4/) -- LikeC4 model: canonical source of truth for C4 architecture topology (L1-L3)", + "src/content/docs/05-technical/architecture/system-map.md", + "eeae19a623e608e0", + { "html": 295, "metadata": 296 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"system-map\">System Map\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#system-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “System Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Visual entry point for understanding VariScout’s architecture. Start here, then drill into component-level docs linked below.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context-diagram-c4-l1\">Context Diagram (C4 L1)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context-diagram-c4-l1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context Diagram (C4 L1)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Who uses VariScout and what external systems does it touch?\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">C4Context\n title VariScout System Context\n\n Person(analyst, \"Quality Analyst\", \"Analyses process variation using control charts, capability indices, and Pareto rankings\")\n\n System(variscout, \"VariScout\", \"Offline-first variation analysis tool (PWA + Azure App)\")\n\n System_Ext(azuread, \"Azure AD\", \"EasyAuth identity provider\")\n System_Ext(onedrive, \"Microsoft OneDrive\", \"Cloud file sync via Graph API\")\n System_Ext(teams, \"Microsoft Teams\", \"Channel tabs, SSO, photo capture\")\n System_Ext(aisearch, \"Azure AI Search\", \"AI-powered analysis suggestions\")\n\n Rel(analyst, variscout, \"Uploads data, reviews charts, investigates variation\")\n Rel(variscout, azuread, \"Authenticates via EasyAuth\")\n Rel(variscout, onedrive, \"Syncs projects (Team plan)\")\n Rel(variscout, teams, \"Embeds as channel tab, captures photos\")\n Rel(variscout, aisearch, \"Queries for AI-assisted analysis\")\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"container-diagram-c4-l2\">Container Diagram (C4 L2)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#container-diagram-c4-l2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Container Diagram (C4 L2)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Monorepo packages, apps, and their dependency relationships.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph apps[\"Apps\"]\n pwa[\"apps/pwa<br/><i>React + Vite</i><br/>FREE demo tool\"]\n azure[\"apps/azure<br/><i>React + Vite</i><br/>Azure Team App\"]\n website[\"apps/website<br/><i>Astro + React Islands</i><br/>Marketing site\"]\n end\n\n subgraph packages[\"Packages\"]\n ui[\"@variscout/ui<br/><i>Shared UI components</i>\"]\n hooks[\"@variscout/hooks<br/><i>Shared React hooks</i>\"]\n charts[\"@variscout/charts<br/><i>React + Visx charts</i>\"]\n core[\"@variscout/core<br/><i>Pure logic, stats, parser, tier</i>\"]\n data[\"@variscout/data<br/><i>Sample datasets</i>\"]\n end\n\n subgraph infra[\"Infrastructure\"]\n arm[\"infra/mainTemplate.json<br/><i>ARM template</i>\"]\n end\n\n subgraph external[\"External Systems\"]\n azuread[\"Azure AD\"]\n onedrive[\"OneDrive\"]\n teams[\"Teams\"]\n aisearch[\"Azure AI Search\"]\n end\n\n %% App dependencies\n pwa --> core & charts & hooks & ui & data\n azure --> core & charts & hooks & ui & data\n website --> charts & data\n\n %% Package dependencies\n ui --> core & hooks & charts\n hooks --> core\n charts --> core\n\n %% External integrations (Azure app only)\n azure -.-> azuread & onedrive & teams & aisearch\n arm -.-> azure\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-dependency-rules\">Key dependency rules\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-dependency-rules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key dependency rules”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Apps\u003C/strong> import from packages; packages never import from apps.\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/strong> has zero React dependencies (pure TypeScript + d3-array, exceljs, papaparse).\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode dir=\"auto\">@variscout/data\u003C/code>\u003C/strong> has no internal package dependencies.\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/strong> is the highest-level shared package, composing core, hooks, and charts.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"package-responsibilities\">Package Responsibilities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#package-responsibilities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Package Responsibilities”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Package\u003C/th>\u003Cth>Role\u003C/th>\u003Cth>Key exports\u003C/th>\u003Cth>Docs\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/td>\u003Ctd>Statistics engine, CSV/Excel parser, tier system, glossary, types\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">calculateStats\u003C/code>, \u003Ccode dir=\"auto\">parseCSV\u003C/code>, \u003Ccode dir=\"auto\">getTier\u003C/code>, \u003Ccode dir=\"auto\">GlossaryTerm\u003C/code>\u003C/td>\u003Ctd>\u003Ca href=\"shared-packages.md\">shared-packages.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/td>\u003Ctd>Visx chart components (I-Chart, Boxplot, Pareto, Performance suite)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">IChart\u003C/code>, \u003Ccode dir=\"auto\">Boxplot\u003C/code>, \u003Ccode dir=\"auto\">ParetoChart\u003C/code>, \u003Ccode dir=\"auto\">PerformanceIChart\u003C/code>, \u003Ccode dir=\"auto\">useChartTheme\u003C/code>\u003C/td>\u003Ctd>\u003Ca href=\"component-patterns.md\">component-patterns.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/data\u003C/code>\u003C/td>\u003Ctd>Pre-computed sample datasets for demo and testing\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">coffeeSample\u003C/code>, \u003Ccode dir=\"auto\">journeySample\u003C/code>, \u003Ccode dir=\"auto\">bottleneckSample\u003C/code>\u003C/td>\u003Ctd>\u003Ca href=\"shared-packages.md\">shared-packages.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003Ctd>Shared React hooks for state, navigation, data transforms\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useDataState\u003C/code>, \u003Ccode dir=\"auto\">useFilterNavigation\u003C/code>, \u003Ccode dir=\"auto\">useChartScale\u003C/code>, \u003Ccode dir=\"auto\">useTier\u003C/code>\u003C/td>\u003Ctd>\u003Ca href=\"component-patterns.md\">component-patterns.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Shared UI components with colorScheme theming pattern\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">StatsPanelBase\u003C/code>, \u003Ccode dir=\"auto\">FindingsLog\u003C/code>, \u003Ccode dir=\"auto\">DashboardGrid\u003C/code>, \u003Ccode dir=\"auto\">WhatIfSimulator\u003C/code>\u003C/td>\u003Ctd>\u003Ca href=\"component-patterns.md\">component-patterns.md\u003C/a>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"app-responsibilities\">App Responsibilities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#app-responsibilities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “App Responsibilities”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>App\u003C/th>\u003Cth>Distribution\u003C/th>\u003Cth>Technology\u003C/th>\u003Cth>Key characteristics\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa\u003C/code>\u003C/td>\u003Ctd>Public URL (free)\u003C/td>\u003Ctd>React + Vite PWA\u003C/td>\u003Ctd>Session-only storage, 3 factors max, 50K rows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">apps/azure\u003C/code>\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>React + Vite + EasyAuth\u003C/td>\u003Ctd>IndexedDB + OneDrive sync, 6 factors, 100K rows, Teams integration\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">apps/website\u003C/code>\u003C/td>\u003Ctd>Public URL\u003C/td>\u003Ctd>Astro + React Islands\u003C/td>\u003Ctd>Static marketing site with embedded chart demos\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"infrastructure\">Infrastructure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#infrastructure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Infrastructure”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Docs\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json\u003C/code>\u003C/td>\u003Ctd>ARM template for Azure Marketplace Managed Application deployment\u003C/td>\u003Ctd>\u003Ca href=\"../../08-products/azure/arm-template.md\">arm-template.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">.github/workflows/deploy-azure-staging.yml\u003C/code>\u003C/td>\u003Ctd>CI/CD pipeline: build + OIDC deploy to staging\u003C/td>\u003Ctd>\u003Ca href=\"../implementation/deployment.md\">deployment.md\u003C/a>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"component-map.md\">component-map.md\u003C/a> — L3 component views per package (internal modules)\u003C/li>\n\u003Cli>\u003Ca href=\"data-flow.md\">data-flow.md\u003C/a> — End-to-end data pipeline from ingestion to chart rendering\u003C/li>\n\u003Cli>\u003Ca href=\"shared-packages.md\">shared-packages.md\u003C/a> — Detailed package APIs and export inventories\u003C/li>\n\u003Cli>\u003Ca href=\"monorepo.md\">monorepo.md\u003C/a> — Build system, workspace configuration, import rules\u003C/li>\n\u003Cli>\u003Ca href=\"component-patterns.md\">component-patterns.md\u003C/a> — React component conventions and hook patterns\u003C/li>\n\u003Cli>\u003Ca href=\"offline-first.md\">offline-first.md\u003C/a> — Storage strategy, sync architecture, conflict resolution\u003C/li>\n\u003Cli>\u003Ca href=\"data-pipeline-map.md\">data-pipeline-map.md\u003C/a> — Step-by-step data transformation pipeline\u003C/li>\n\u003Cli>\u003Ca href=\"../../architecture/likec4/\">\u003Ccode dir=\"auto\">docs/architecture/likec4/\u003C/code>\u003C/a> — LikeC4 model: canonical source of truth for C4 architecture topology (L1-L3)\u003C/li>\n\u003C/ul>", + { + "headings": 297, + "localImagePaths": 319, + "remoteImagePaths": 320, + "frontmatter": 321, + "imagePaths": 323 + }, + [298, 300, 303, 306, 309, 312, 315, 318], + { "depth": 30, "slug": 299, "text": 286 }, + "system-map", + { "depth": 33, "slug": 301, "text": 302 }, + "context-diagram-c4-l1", + "Context Diagram (C4 L1)", + { "depth": 33, "slug": 304, "text": 305 }, + "container-diagram-c4-l2", + "Container Diagram (C4 L2)", + { "depth": 79, "slug": 307, "text": 308 }, + "key-dependency-rules", + "Key dependency rules", + { "depth": 33, "slug": 310, "text": 311 }, + "package-responsibilities", + "Package Responsibilities", + { "depth": 33, "slug": 313, "text": 314 }, + "app-responsibilities", + "App Responsibilities", + { "depth": 33, "slug": 316, "text": 317 }, + "infrastructure", + "Infrastructure", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 286, "description": 287, "journey-phase": 322 }, + [155], + [], + "03-features/workflows/analysis-journey-map", + { "id": 324, "data": 326, "body": 332, "filePath": 333, "digest": 334, "rendered": 335 }, + { + "title": 327, + "description": 328, + "editUrl": 16, + "head": 329, + "template": 18, + "sidebar": 330, + "pagefind": 16, + "draft": 20 + }, + "Analysis Journey Map", + "Visual map of the 4-phase analysis journey — Frame, Scout, Investigate, Improve — with CoScout companion and PDCA loop", + [], + { "hidden": 20, "attrs": 331 }, + {}, + "# Analysis Journey Map\n\nVariScout guides quality analysts through four distinct phases: **Frame**, **Scout**, **Investigate**, and **Improve**. Each phase has a clear purpose, specific data shapes at its boundaries, and defined decision points that move the analyst forward. CoScout, the AI companion, adapts its behaviour at each phase to provide contextually relevant guidance.\n\n## Journey Overview\n\n```mermaid\nflowchart LR\n subgraph CoScout[\"CoScout AI Companion\"]\n direction LR\n F[\"FRAME\\nDefine the problem space\"]\n S[\"SCOUT\\nDiscover variation patterns\"]\n I[\"INVESTIGATE\\nFind root causes\"]\n IM[\"IMPROVE\\nProject and verify fixes\"]\n end\n\n F --> S\n S --> I\n I --> IM\n IM -- \"PDCA loop\" --> F\n S -- \"Add Data\" --> F\n\n style F fill:#3b82f6,color:#fff\n style S fill:#22c55e,color:#fff\n style I fill:#f59e0b,color:#fff\n style IM fill:#8b5cf6,color:#fff\n```\n\nThe journey is not strictly linear. Two feedback loops connect the phases:\n\n- **PDCA loop** -- After verifying an improvement, the analyst re-enters Frame with new data to confirm the gains hold.\n- **Add Data loop** -- While scouting, the analyst may realise the dataset is incomplete and return to Frame to add more data or remap columns.\n\n---\n\n## Phase 1: FRAME\n\n**Purpose:** Define the problem space by loading data, mapping columns, and setting specification limits.\n\n```mermaid\nflowchart TD\n U[\"Upload / Paste data\"] --> P[\"Parse rows\"]\n P --> CM[\"Column Mapping\\n(measure + factors)\"]\n CM --> SS[\"Set Spec Limits\\n(USL, LSL, Target)\"]\n SS --> PD[\"Describe Process Context\"]\n PD --> R[\"Ready for analysis\"]\n\n style U fill:#3b82f6,color:#fff\n style R fill:#22c55e,color:#fff\n```\n\n### Steps\n\n1. **Upload or paste data** -- CSV, Excel, or clipboard paste. The parser (`parseText` / `parseFile`) detects delimiters and validates structure.\n2. **Map columns** -- Assign one measurement column and up to N factor columns. The `ColumnMapping` component provides data-rich cards with type badges and preview values.\n3. **Set specification limits** -- Enter USL, LSL, and optional target via `SpecsPopover`. These flow through to capability calculations.\n4. **Describe process context** -- Optional but valuable for CoScout. Process name, characteristic type, and any known constraints.\n\n### Data Shapes at Boundary\n\n| Entry | Exit |\n|-------|------|\n| Raw file / clipboard text | `DataRow[]` (parsed, validated) |\n| -- | `ValidationResult` (quality checks) |\n| -- | `ColumnMapping` (measure + factors assigned) |\n| -- | `AnalysisState` (specs, settings, ready flag) |\n\n### Tier Differences\n\n| Dimension | PWA (Free) | Azure (Standard / Team) |\n|-----------|-----------|------------------------|\n| Max factors | 3 | 6 |\n| Max rows | 50,000 | 100,000 |\n| Persistence | Session only | IndexedDB (+ OneDrive for Team) |\n\n### CoScout in Frame\n\nCoScout is **not active** during Frame -- there is no analysed data to reason about yet. Once the analyst clicks \"Start\", data flows into the Scout phase and CoScout activates.\n\n### Key Code References\n\n- `useDataIngestion` -- shared file upload and parsing hook\n- `useDataState` -- shared DataContext state management\n- `ColumnMapping` component -- column assignment UI\n- `parser.ts` -- CSV/Excel parsing and validation\n\n---\n\n## Phase 2: SCOUT\n\n**Purpose:** Discover variation patterns using the Four Lenses -- CHANGE, FLOW, FAILURE, VALUE.\n\n```mermaid\nflowchart TD\n IC[\"I-Chart\\n(CHANGE)\"] --> BP[\"Boxplot\\n(FLOW)\"]\n BP --> PA[\"Pareto\\n(FAILURE)\"]\n PA --> CA[\"Capability\\n(VALUE)\"]\n\n IC -- \"Special cause?\" --> PIN1[\"Pin finding\"]\n BP -- \"High eta-squared?\" --> DRILL[\"Drill down\"]\n PA -- \"Vital few?\" --> PIN2[\"Pin finding\"]\n CA -- \"Cpk concern?\" --> PIN3[\"Pin finding\"]\n\n DRILL --> IC\n CA -- \"Need more data?\" --> ADD[\"Add Data\\n(back to Frame)\"]\n\n style IC fill:#3b82f6,color:#fff\n style BP fill:#3b82f6,color:#fff\n style PA fill:#3b82f6,color:#fff\n style CA fill:#3b82f6,color:#fff\n style PIN1 fill:#f59e0b,color:#fff\n style PIN2 fill:#f59e0b,color:#fff\n style PIN3 fill:#f59e0b,color:#fff\n```\n\n### Steps\n\n1. **Scan I-Chart for stability** -- Look for points outside control limits, runs, and trends. Red dots signal special causes.\n2. **Compare factors in Boxplot** -- Read ANOVA eta-squared to identify which factor explains the most variation.\n3. **Rank in Pareto** -- See which categories within a factor contribute most to failures or out-of-spec results.\n4. **Check Cpk** -- After filtering, assess whether the isolated subset meets specification requirements.\n\nAt any point, the analyst can **pin a finding** to capture an observation for later investigation.\n\n### Two Speeds\n\n| Path | Duration | When to Use |\n|------|----------|-------------|\n| **Quick Check** | ~5 min | Daily monitoring, shift handover |\n| **Deep Dive** | ~30 min | Customer complaint, root cause project, process qualification |\n\nSee [quick-check.md](quick-check.md) and [deep-dive.md](deep-dive.md) for detailed protocols.\n\n### Data Shapes\n\n| Type | Purpose |\n|------|---------|\n| `StatsResult` | Mean, sigma, Cp, Cpk, median for current filter scope |\n| `AnovaResult` | F-statistic, p-value, eta-squared for factor comparison |\n| `FilterAction[]` | Ordered drill trail (filter stack) |\n| `Finding` (status: `observed`) | Pinned observations from charts |\n\n### Tier Differences\n\n| Dimension | PWA (Free) | Azure (Standard / Team) |\n|-----------|-----------|------------------------|\n| Max drill factors | 3 | 6 |\n| Finding statuses | 3 (observed, investigating, analyzed) | 5 (+ improving, resolved) |\n| Variation tracking | Cumulative Total SS | Cumulative Total SS |\n\n### CoScout in Scout\n\n- **NarrativeBar** suggests patterns detected in the data (\"Shift detected after sample 47\")\n- **ChartInsightChips** appear on individual charts with contextual observations\n\n### Key Code References\n\n- `useFilterNavigation` -- filter navigation with multi-select and breadcrumbs\n- `useVariationTracking` -- cumulative Total SS scope tracking\n- `useChartScale` -- Y-axis scale calculation\n- `useBoxplotData`, `useIChartData` -- chart data transforms\n\n---\n\n## Phase 3: INVESTIGATE\n\n**Purpose:** Move from observations to validated root causes through structured hypothesis testing.\n\n```mermaid\nstateDiagram-v2\n [*] --> Initial: Pin finding\n Initial --> Diverging: Generate sub-hypotheses\n Diverging --> Validating: Select hypothesis to test\n Validating --> Diverging: Needs more hypotheses\n Validating --> Converging: Evidence confirms\n Converging --> Acting: Root cause identified\n Acting --> [*]: Ready for Improve phase\n\n note right of Diverging\n Brainstorm possible causes\n (CoScout suggests)\n end note\n\n note right of Validating\n Data evidence (ANOVA)\n Gemba observation\n Expert input\n end note\n```\n\n### IDEOI Phases\n\nThe investigation follows the IDEOI lifecycle within each finding:\n\n| Phase | Status | Activity |\n|-------|--------|----------|\n| **I**nitial | `observed` | Finding pinned from chart, no hypothesis yet |\n| **D**iverging | `investigating` | Generate multiple sub-hypotheses, brainstorm causes |\n| **V**alidating | `investigating` | Test hypotheses against data (eta-squared thresholds), gemba walks, expert consultation |\n| **C**onverging | `analyzed` | Confirm root cause, tag as key-driver or low-impact |\n| **A**cting | `improving` (Azure) | Define corrective actions, enter Improve phase |\n\n### Steps\n\n1. **Formulate hypotheses** -- Based on Scout observations, propose why the variation exists. CoScout can suggest hypotheses grounded in the data.\n2. **Test with data** -- Use ANOVA results and drill-down filtering to validate or reject each hypothesis. Auto-validation uses eta-squared thresholds.\n3. **Gemba observation** -- Go to the process and observe. Azure Team plan supports photo evidence (EXIF-stripped).\n4. **Expert input** -- Add comments and notes from domain experts to findings.\n5. **Converge** -- Select the validated root cause and classify the finding (key-driver vs low-impact).\n\n### Data Shapes\n\n| Type | Purpose |\n|------|---------|\n| `Finding` | Core investigation record with status progression |\n| `Hypothesis` | Sub-hypothesis linked to a finding, with validation state |\n| `FindingStatus` | `observed` / `investigating` / `analyzed` / `improving` / `resolved` |\n| `FindingTag` | `key-driver` or `low-impact` classification |\n\n### Tier Differences\n\n| Dimension | PWA (Free) | Azure (Standard / Team) |\n|-----------|-----------|------------------------|\n| Finding statuses | 3 (observed, investigating, analyzed) | 5 (all statuses) |\n| Photo evidence | No | Team plan only |\n| Hypothesis management | Full | Full |\n| Board view | 3 columns | 5 columns with drag-and-drop |\n\n### CoScout in Investigate\n\n- Suggests hypotheses based on data patterns and process context\n- Validates hypotheses against statistical evidence\n- Links related findings across investigation sessions\n\n### Key Code References\n\n- `useFindings` -- finding CRUD, status transitions, hypothesis linking\n- `useHypotheses` -- hypothesis CRUD, auto-validation with eta-squared thresholds\n- `FindingsLog`, `FindingBoardView` -- UI components for findings management\n\n---\n\n## Phase 4: IMPROVE\n\n**Purpose:** Project improvements, define corrective actions, verify with staged analysis, and record outcomes.\n\n```mermaid\nflowchart TD\n ID[\"Ideas from investigation\"] --> WI[\"What-If Simulator\\n(project Cpk/yield)\"]\n WI --> ACT[\"Define Corrective Actions\"]\n ACT --> IMPL[\"Implement changes\"]\n IMPL --> STAGE[\"Staged Analysis\\n(before vs after)\"]\n STAGE --> CHK{Verification\\npassed?}\n CHK -- \"Yes\" --> OUT[\"Record Outcome\\n(report / share)\"]\n CHK -- \"No\" --> PDCA[\"PDCA loop\\n(back to Frame)\"]\n OUT --> CLOSE[\"Resolve finding\"]\n\n style ID fill:#8b5cf6,color:#fff\n style WI fill:#8b5cf6,color:#fff\n style OUT fill:#22c55e,color:#fff\n style PDCA fill:#3b82f6,color:#fff\n```\n\n### Steps\n\n1. **Generate improvement ideas** -- Based on root cause analysis, propose specific changes. Each idea can have a projected impact.\n2. **Model with What-If Simulator** -- Use `directAdjustment` to project how changes would affect Cpk and yield.\n3. **Define corrective actions** -- Create trackable action items with owners, dates, and status.\n4. **Verify with staged analysis** -- Load before-and-after data into staged analysis to confirm the improvement. Compare control limits and Cpk.\n5. **Record outcome** -- Document whether the action resolved the variation source. Mark the finding as resolved.\n\n### Data Shapes\n\n| Type | Purpose |\n|------|---------|\n| `ActionItem` | Corrective action with owner, date, status |\n| `FindingOutcome` | Documented result of the improvement |\n| `Finding` (status: `resolved`) | Closed investigation |\n\n### Tier Differences\n\n| Dimension | PWA (Free) | Azure (Standard / Team) |\n|-----------|-----------|------------------------|\n| What-If Simulator | Available | Available |\n| Action tracking | Limited | Full (improving + resolved statuses) |\n| Staged analysis | Available | Available |\n| Outcome recording | No | Team plan |\n\n### CoScout in Improve\n\n- Suggests corrective actions based on validated root cause\n- Assists with What-If parameter selection\n- Summarises before/after comparison\n\n### Key Code References\n\n- `WhatIfSimulator` / `WhatIfPageBase` -- simulation UI\n- `simulation.ts` -- `directAdjustment` computation\n- [staged-analysis.md](../analysis/staged-analysis.md) -- staged comparison methodology\n\n---\n\n## Two Entry Paths into Scout\n\nNot every analysis starts the same way. VariScout supports two distinct paths into the Scout phase:\n\n```mermaid\nflowchart TD\n START[\"Data loaded\\n(Frame complete)\"] --> PATH\n\n PATH --> DISC[\"Discovery Path\"]\n PATH --> HYPO[\"Hypothesis-Driven Path\"]\n\n DISC --> SCAN[\"Scan all Four Lenses\"]\n SCAN --> DRILL[\"Drill into patterns\"]\n DRILL --> FIND[\"Pin findings\"]\n FIND --> INV[\"Move to Investigate\"]\n\n HYPO --> SUGGEST[\"CoScout suggests pattern\"]\n SUGGEST --> CONFIRM[\"Confirm with chart evidence\"]\n CONFIRM --> JUMP[\"Jump directly to Investigate\"]\n\n style DISC fill:#22c55e,color:#fff\n style HYPO fill:#f59e0b,color:#fff\n```\n\n| Path | Starting Point | Duration | Best For |\n|------|---------------|----------|----------|\n| **Discovery** | No prior knowledge | 15-30 min | New datasets, exploratory analysis |\n| **Hypothesis-driven** | CoScout suggestion or prior knowledge | 5-10 min | Known issues, repeat monitoring |\n\n---\n\n## The Drill-Down Loop\n\nThe drill-down loop is the core interaction pattern within the Scout phase. Each iteration narrows the data scope and increases the percentage of variation explained.\n\n```mermaid\nflowchart TD\n ALL[\"All Data\"] --> READ[\"Read eta-squared\\n(ANOVA under Boxplot)\"]\n READ --> CLICK[\"Click highest-eta factor\"]\n CLICK --> FILTER[\"Filter applied\\n(chip shows contribution %)\"]\n FILTER --> UPDATE[\"Charts update\\nfor filtered subset\"]\n UPDATE --> CHECK{Enough variation\\nisolated?}\n CHECK -- \"Yes (>50%)\" --> PIN[\"Pin finding\"]\n CHECK -- \"No\" --> READ\n\n style ALL fill:#3b82f6,color:#fff\n style PIN fill:#22c55e,color:#fff\n```\n\nEach filter chip displays the cumulative contribution percentage (Total SS scope), giving the analyst a running measure of how much variation has been explained by the current drill path. See [drill-down-workflow.md](drill-down-workflow.md) for the detailed protocol.\n\n---\n\n## Decision Point Map\n\nTwelve key decision points shape the analysis journey. Each has a clear question, evidence source, and branching outcome.\n\n| # | Decision Point | Phase | Evidence | Yes Path | No Path |\n|---|---------------|-------|----------|----------|---------|\n| 1 | Stable? | Scout | I-Chart (control limits, Nelson rules) | Proceed to Boxplot | Investigate special causes first |\n| 2 | Which factor drives variation? | Scout | Boxplot eta-squared | Drill into highest eta-squared | Check interactions |\n| 3 | Enough variation isolated? | Scout | Cumulative Total SS > 50% | Pin finding, move to Investigate | Continue drilling |\n| 4 | Capable? | Scout | Cpk vs target (1.33 default) | Process acceptable | Needs improvement |\n| 5 | Quick Check or Deep Dive? | Scout | Time available, severity | Quick Check (~5 min) | Deep Dive (~30 min) |\n| 6 | Discovery or Hypothesis-driven? | Scout | Prior knowledge, CoScout input | Discovery (scan all lenses) | Hypothesis-driven (confirm and jump) |\n| 7 | Key Driver or Low Impact? | Investigate | eta-squared magnitude, Pareto rank | Tag as key-driver | Tag as low-impact |\n| 8 | Single or multiple hypotheses? | Investigate | Complexity of problem | Test single hypothesis | Diverge into sub-hypotheses |\n| 9 | Data, gemba, or expert validation? | Investigate | Available evidence | Statistical test (ANOVA) | Physical observation or consultation |\n| 10 | Converged on root cause? | Investigate | Hypothesis validation status | Enter Improve phase | Generate more hypotheses |\n| 11 | What-If projection effective? | Improve | Projected Cpk meets target | Define corrective actions | Revise approach |\n| 12 | Verification passed? | Improve | Staged analysis (before vs after) | Resolve finding, close | PDCA loop back to Frame |\n\n---\n\n## All Loops Visualized\n\nFive feedback loops keep the analysis iterative and self-correcting:\n\n```mermaid\nflowchart TD\n FRAME[\"FRAME\"] --> SCOUT[\"SCOUT\"]\n SCOUT --> INVESTIGATE[\"INVESTIGATE\"]\n INVESTIGATE --> IMPROVE[\"IMPROVE\"]\n\n %% Drill-down loop (Scout)\n SCOUT -- \"Drill-down loop\\n(filter, read, repeat)\" --> SCOUT\n\n %% Hypothesis validation loop (Investigate)\n INVESTIGATE -- \"Hypothesis loop\\n(diverge, validate, converge)\" --> INVESTIGATE\n\n %% What-If iteration loop (Improve)\n IMPROVE -- \"What-If loop\\n(project, adjust, re-project)\" --> IMPROVE\n\n %% PDCA re-entry loop\n IMPROVE -- \"PDCA loop\\n(verify failed or new cycle)\" --> FRAME\n\n %% Add Data loop\n SCOUT -- \"Add Data loop\\n(incomplete dataset)\" --> FRAME\n\n style FRAME fill:#3b82f6,color:#fff\n style SCOUT fill:#22c55e,color:#fff\n style INVESTIGATE fill:#f59e0b,color:#fff\n style IMPROVE fill:#8b5cf6,color:#fff\n```\n\n| Loop | Phase | Trigger | Exit Condition |\n|------|-------|---------|----------------|\n| Drill-down | Scout | eta-squared suggests deeper factor | >50% variation explained or no more factors |\n| Hypothesis validation | Investigate | Hypothesis not yet confirmed | Root cause validated with evidence |\n| What-If iteration | Improve | Projected Cpk below target | Projection meets target or approach revised |\n| PDCA re-entry | Improve to Frame | Staged verification fails or new improvement cycle | Verification passes |\n| Add Data | Scout to Frame | Dataset missing factors or insufficient samples | Data reloaded with additional columns/rows |\n\n---\n\n## Related Documentation\n\n- [Four Lenses Workflow](four-lenses-workflow.md) -- detailed CHANGE / FLOW / FAILURE / VALUE methodology\n- [Drill-Down Workflow](drill-down-workflow.md) -- progressive stratification using filter chips\n- [Quick Check](quick-check.md) -- 5-minute monitoring protocol\n- [Deep Dive](deep-dive.md) -- 30-minute investigation protocol\n- [Investigation to Action](investigation-to-action.md) -- findings and What-If workflow\n- [Investigation Lifecycle Map](investigation-lifecycle-map.md) -- IDEOI state machine detail\n- [Decision Trees](decision-trees.md) -- branching logic for analysis decisions", + "src/content/docs/03-features/workflows/analysis-journey-map.md", + "38a56c65ee75e6d9", + { "html": 336, "metadata": 337 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"analysis-journey-map\">Analysis Journey Map\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-journey-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis Journey Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout guides quality analysts through four distinct phases: \u003Cstrong>Frame\u003C/strong>, \u003Cstrong>Scout\u003C/strong>, \u003Cstrong>Investigate\u003C/strong>, and \u003Cstrong>Improve\u003C/strong>. Each phase has a clear purpose, specific data shapes at its boundaries, and defined decision points that move the analyst forward. CoScout, the AI companion, adapts its behaviour at each phase to provide contextually relevant guidance.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-overview\">Journey Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n subgraph CoScout[\"CoScout AI Companion\"]\n direction LR\n F[\"FRAME\\nDefine the problem space\"]\n S[\"SCOUT\\nDiscover variation patterns\"]\n I[\"INVESTIGATE\\nFind root causes\"]\n IM[\"IMPROVE\\nProject and verify fixes\"]\n end\n\n F --> S\n S --> I\n I --> IM\n IM -- \"PDCA loop\" --> F\n S -- \"Add Data\" --> F\n\n style F fill:#3b82f6,color:#fff\n style S fill:#22c55e,color:#fff\n style I fill:#f59e0b,color:#fff\n style IM fill:#8b5cf6,color:#fff\n\u003C/pre>\n\u003Cp>The journey is not strictly linear. Two feedback loops connect the phases:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>PDCA loop\u003C/strong> — After verifying an improvement, the analyst re-enters Frame with new data to confirm the gains hold.\u003C/li>\n\u003Cli>\u003Cstrong>Add Data loop\u003C/strong> — While scouting, the analyst may realise the dataset is incomplete and return to Frame to add more data or remap columns.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-1-frame\">Phase 1: FRAME\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-1-frame\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 1: FRAME”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Purpose:\u003C/strong> Define the problem space by loading data, mapping columns, and setting specification limits.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n U[\"Upload / Paste data\"] --> P[\"Parse rows\"]\n P --> CM[\"Column Mapping\\n(measure + factors)\"]\n CM --> SS[\"Set Spec Limits\\n(USL, LSL, Target)\"]\n SS --> PD[\"Describe Process Context\"]\n PD --> R[\"Ready for analysis\"]\n\n style U fill:#3b82f6,color:#fff\n style R fill:#22c55e,color:#fff\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"steps\">Steps\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#steps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Steps”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Upload or paste data\u003C/strong> — CSV, Excel, or clipboard paste. The parser (\u003Ccode dir=\"auto\">parseText\u003C/code> / \u003Ccode dir=\"auto\">parseFile\u003C/code>) detects delimiters and validates structure.\u003C/li>\n\u003Cli>\u003Cstrong>Map columns\u003C/strong> — Assign one measurement column and up to N factor columns. The \u003Ccode dir=\"auto\">ColumnMapping\u003C/code> component provides data-rich cards with type badges and preview values.\u003C/li>\n\u003Cli>\u003Cstrong>Set specification limits\u003C/strong> — Enter USL, LSL, and optional target via \u003Ccode dir=\"auto\">SpecsPopover\u003C/code>. These flow through to capability calculations.\u003C/li>\n\u003Cli>\u003Cstrong>Describe process context\u003C/strong> — Optional but valuable for CoScout. Process name, characteristic type, and any known constraints.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-shapes-at-boundary\">Data Shapes at Boundary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-shapes-at-boundary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Shapes at Boundary”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Entry\u003C/th>\u003Cth>Exit\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Raw file / clipboard text\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code> (parsed, validated)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>—\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ValidationResult\u003C/code> (quality checks)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>—\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ColumnMapping\u003C/code> (measure + factors assigned)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>—\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">AnalysisState\u003C/code> (specs, settings, ready flag)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tier-differences\">Tier Differences\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tier-differences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier Differences”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>PWA (Free)\u003C/th>\u003Cth>Azure (Standard / Team)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Max factors\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>6\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Max rows\u003C/td>\u003Ctd>50,000\u003C/td>\u003Ctd>100,000\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Persistence\u003C/td>\u003Ctd>Session only\u003C/td>\u003Ctd>IndexedDB (+ OneDrive for Team)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"coscout-in-frame\">CoScout in Frame\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#coscout-in-frame\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CoScout in Frame”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>CoScout is \u003Cstrong>not active\u003C/strong> during Frame — there is no analysed data to reason about yet. Once the analyst clicks “Start”, data flows into the Scout phase and CoScout activates.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-code-references\">Key Code References\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-code-references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Code References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">useDataIngestion\u003C/code> — shared file upload and parsing hook\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useDataState\u003C/code> — shared DataContext state management\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">ColumnMapping\u003C/code> component — column assignment UI\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">parser.ts\u003C/code> — CSV/Excel parsing and validation\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-2-scout\">Phase 2: SCOUT\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-scout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2: SCOUT”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Purpose:\u003C/strong> Discover variation patterns using the Four Lenses — CHANGE, FLOW, FAILURE, VALUE.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n IC[\"I-Chart\\n(CHANGE)\"] --> BP[\"Boxplot\\n(FLOW)\"]\n BP --> PA[\"Pareto\\n(FAILURE)\"]\n PA --> CA[\"Capability\\n(VALUE)\"]\n\n IC -- \"Special cause?\" --> PIN1[\"Pin finding\"]\n BP -- \"High eta-squared?\" --> DRILL[\"Drill down\"]\n PA -- \"Vital few?\" --> PIN2[\"Pin finding\"]\n CA -- \"Cpk concern?\" --> PIN3[\"Pin finding\"]\n\n DRILL --> IC\n CA -- \"Need more data?\" --> ADD[\"Add Data\\n(back to Frame)\"]\n\n style IC fill:#3b82f6,color:#fff\n style BP fill:#3b82f6,color:#fff\n style PA fill:#3b82f6,color:#fff\n style CA fill:#3b82f6,color:#fff\n style PIN1 fill:#f59e0b,color:#fff\n style PIN2 fill:#f59e0b,color:#fff\n style PIN3 fill:#f59e0b,color:#fff\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"steps-1\">Steps\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#steps-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Steps”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Scan I-Chart for stability\u003C/strong> — Look for points outside control limits, runs, and trends. Red dots signal special causes.\u003C/li>\n\u003Cli>\u003Cstrong>Compare factors in Boxplot\u003C/strong> — Read ANOVA eta-squared to identify which factor explains the most variation.\u003C/li>\n\u003Cli>\u003Cstrong>Rank in Pareto\u003C/strong> — See which categories within a factor contribute most to failures or out-of-spec results.\u003C/li>\n\u003Cli>\u003Cstrong>Check Cpk\u003C/strong> — After filtering, assess whether the isolated subset meets specification requirements.\u003C/li>\n\u003C/ol>\n\u003Cp>At any point, the analyst can \u003Cstrong>pin a finding\u003C/strong> to capture an observation for later investigation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"two-speeds\">Two Speeds\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#two-speeds\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two Speeds”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Path\u003C/th>\u003Cth>Duration\u003C/th>\u003Cth>When to Use\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Quick Check\u003C/strong>\u003C/td>\u003Ctd>~5 min\u003C/td>\u003Ctd>Daily monitoring, shift handover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Deep Dive\u003C/strong>\u003C/td>\u003Ctd>~30 min\u003C/td>\u003Ctd>Customer complaint, root cause project, process qualification\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"quick-check.md\">quick-check.md\u003C/a> and \u003Ca href=\"deep-dive.md\">deep-dive.md\u003C/a> for detailed protocols.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-shapes\">Data Shapes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-shapes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Shapes”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">StatsResult\u003C/code>\u003C/td>\u003Ctd>Mean, sigma, Cp, Cpk, median for current filter scope\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">AnovaResult\u003C/code>\u003C/td>\u003Ctd>F-statistic, p-value, eta-squared for factor comparison\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FilterAction[]\u003C/code>\u003C/td>\u003Ctd>Ordered drill trail (filter stack)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Finding\u003C/code> (status: \u003Ccode dir=\"auto\">observed\u003C/code>)\u003C/td>\u003Ctd>Pinned observations from charts\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tier-differences-1\">Tier Differences\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tier-differences-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier Differences”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>PWA (Free)\u003C/th>\u003Cth>Azure (Standard / Team)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Max drill factors\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>6\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Finding statuses\u003C/td>\u003Ctd>3 (observed, investigating, analyzed)\u003C/td>\u003Ctd>5 (+ improving, resolved)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Variation tracking\u003C/td>\u003Ctd>Cumulative Total SS\u003C/td>\u003Ctd>Cumulative Total SS\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"coscout-in-scout\">CoScout in Scout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#coscout-in-scout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CoScout in Scout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>NarrativeBar\u003C/strong> suggests patterns detected in the data (“Shift detected after sample 47”)\u003C/li>\n\u003Cli>\u003Cstrong>ChartInsightChips\u003C/strong> appear on individual charts with contextual observations\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-code-references-1\">Key Code References\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-code-references-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Code References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">useFilterNavigation\u003C/code> — filter navigation with multi-select and breadcrumbs\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code> — cumulative Total SS scope tracking\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useChartScale\u003C/code> — Y-axis scale calculation\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useBoxplotData\u003C/code>, \u003Ccode dir=\"auto\">useIChartData\u003C/code> — chart data transforms\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-3-investigate\">Phase 3: INVESTIGATE\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3-investigate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3: INVESTIGATE”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Purpose:\u003C/strong> Move from observations to validated root causes through structured hypothesis testing.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">stateDiagram-v2\n [*] --> Initial: Pin finding\n Initial --> Diverging: Generate sub-hypotheses\n Diverging --> Validating: Select hypothesis to test\n Validating --> Diverging: Needs more hypotheses\n Validating --> Converging: Evidence confirms\n Converging --> Acting: Root cause identified\n Acting --> [*]: Ready for Improve phase\n\n note right of Diverging\n Brainstorm possible causes\n (CoScout suggests)\n end note\n\n note right of Validating\n Data evidence (ANOVA)\n Gemba observation\n Expert input\n end note\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ideoi-phases\">IDEOI Phases\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ideoi-phases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “IDEOI Phases”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The investigation follows the IDEOI lifecycle within each finding:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Phase\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Activity\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>I\u003C/strong>nitial\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">observed\u003C/code>\u003C/td>\u003Ctd>Finding pinned from chart, no hypothesis yet\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>D\u003C/strong>iverging\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">investigating\u003C/code>\u003C/td>\u003Ctd>Generate multiple sub-hypotheses, brainstorm causes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>V\u003C/strong>alidating\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">investigating\u003C/code>\u003C/td>\u003Ctd>Test hypotheses against data (eta-squared thresholds), gemba walks, expert consultation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>C\u003C/strong>onverging\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">analyzed\u003C/code>\u003C/td>\u003Ctd>Confirm root cause, tag as key-driver or low-impact\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>A\u003C/strong>cting\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">improving\u003C/code> (Azure)\u003C/td>\u003Ctd>Define corrective actions, enter Improve phase\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"steps-2\">Steps\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#steps-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Steps”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Formulate hypotheses\u003C/strong> — Based on Scout observations, propose why the variation exists. CoScout can suggest hypotheses grounded in the data.\u003C/li>\n\u003Cli>\u003Cstrong>Test with data\u003C/strong> — Use ANOVA results and drill-down filtering to validate or reject each hypothesis. Auto-validation uses eta-squared thresholds.\u003C/li>\n\u003Cli>\u003Cstrong>Gemba observation\u003C/strong> — Go to the process and observe. Azure Team plan supports photo evidence (EXIF-stripped).\u003C/li>\n\u003Cli>\u003Cstrong>Expert input\u003C/strong> — Add comments and notes from domain experts to findings.\u003C/li>\n\u003Cli>\u003Cstrong>Converge\u003C/strong> — Select the validated root cause and classify the finding (key-driver vs low-impact).\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-shapes-1\">Data Shapes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-shapes-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Shapes”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Finding\u003C/code>\u003C/td>\u003Ctd>Core investigation record with status progression\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Hypothesis\u003C/code>\u003C/td>\u003Ctd>Sub-hypothesis linked to a finding, with validation state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FindingStatus\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">observed\u003C/code> / \u003Ccode dir=\"auto\">investigating\u003C/code> / \u003Ccode dir=\"auto\">analyzed\u003C/code> / \u003Ccode dir=\"auto\">improving\u003C/code> / \u003Ccode dir=\"auto\">resolved\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FindingTag\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">key-driver\u003C/code> or \u003Ccode dir=\"auto\">low-impact\u003C/code> classification\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tier-differences-2\">Tier Differences\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tier-differences-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier Differences”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>PWA (Free)\u003C/th>\u003Cth>Azure (Standard / Team)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Finding statuses\u003C/td>\u003Ctd>3 (observed, investigating, analyzed)\u003C/td>\u003Ctd>5 (all statuses)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Photo evidence\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Team plan only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hypothesis management\u003C/td>\u003Ctd>Full\u003C/td>\u003Ctd>Full\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Board view\u003C/td>\u003Ctd>3 columns\u003C/td>\u003Ctd>5 columns with drag-and-drop\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"coscout-in-investigate\">CoScout in Investigate\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#coscout-in-investigate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CoScout in Investigate”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Suggests hypotheses based on data patterns and process context\u003C/li>\n\u003Cli>Validates hypotheses against statistical evidence\u003C/li>\n\u003Cli>Links related findings across investigation sessions\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-code-references-2\">Key Code References\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-code-references-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Code References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">useFindings\u003C/code> — finding CRUD, status transitions, hypothesis linking\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useHypotheses\u003C/code> — hypothesis CRUD, auto-validation with eta-squared thresholds\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">FindingsLog\u003C/code>, \u003Ccode dir=\"auto\">FindingBoardView\u003C/code> — UI components for findings management\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-4-improve\">Phase 4: IMPROVE\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-4-improve\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 4: IMPROVE”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Purpose:\u003C/strong> Project improvements, define corrective actions, verify with staged analysis, and record outcomes.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n ID[\"Ideas from investigation\"] --> WI[\"What-If Simulator\\n(project Cpk/yield)\"]\n WI --> ACT[\"Define Corrective Actions\"]\n ACT --> IMPL[\"Implement changes\"]\n IMPL --> STAGE[\"Staged Analysis\\n(before vs after)\"]\n STAGE --> CHK{Verification\\npassed?}\n CHK -- \"Yes\" --> OUT[\"Record Outcome\\n(report / share)\"]\n CHK -- \"No\" --> PDCA[\"PDCA loop\\n(back to Frame)\"]\n OUT --> CLOSE[\"Resolve finding\"]\n\n style ID fill:#8b5cf6,color:#fff\n style WI fill:#8b5cf6,color:#fff\n style OUT fill:#22c55e,color:#fff\n style PDCA fill:#3b82f6,color:#fff\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"steps-3\">Steps\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#steps-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Steps”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Generate improvement ideas\u003C/strong> — Based on root cause analysis, propose specific changes. Each idea can have a projected impact.\u003C/li>\n\u003Cli>\u003Cstrong>Model with What-If Simulator\u003C/strong> — Use \u003Ccode dir=\"auto\">directAdjustment\u003C/code> to project how changes would affect Cpk and yield.\u003C/li>\n\u003Cli>\u003Cstrong>Define corrective actions\u003C/strong> — Create trackable action items with owners, dates, and status.\u003C/li>\n\u003Cli>\u003Cstrong>Verify with staged analysis\u003C/strong> — Load before-and-after data into staged analysis to confirm the improvement. Compare control limits and Cpk.\u003C/li>\n\u003Cli>\u003Cstrong>Record outcome\u003C/strong> — Document whether the action resolved the variation source. Mark the finding as resolved.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-shapes-2\">Data Shapes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-shapes-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Shapes”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ActionItem\u003C/code>\u003C/td>\u003Ctd>Corrective action with owner, date, status\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FindingOutcome\u003C/code>\u003C/td>\u003Ctd>Documented result of the improvement\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Finding\u003C/code> (status: \u003Ccode dir=\"auto\">resolved\u003C/code>)\u003C/td>\u003Ctd>Closed investigation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tier-differences-3\">Tier Differences\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tier-differences-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier Differences”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>PWA (Free)\u003C/th>\u003Cth>Azure (Standard / Team)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>What-If Simulator\u003C/td>\u003Ctd>Available\u003C/td>\u003Ctd>Available\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Action tracking\u003C/td>\u003Ctd>Limited\u003C/td>\u003Ctd>Full (improving + resolved statuses)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Staged analysis\u003C/td>\u003Ctd>Available\u003C/td>\u003Ctd>Available\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Outcome recording\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Team plan\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"coscout-in-improve\">CoScout in Improve\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#coscout-in-improve\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CoScout in Improve”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Suggests corrective actions based on validated root cause\u003C/li>\n\u003Cli>Assists with What-If parameter selection\u003C/li>\n\u003Cli>Summarises before/after comparison\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-code-references-3\">Key Code References\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-code-references-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Code References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">WhatIfSimulator\u003C/code> / \u003Ccode dir=\"auto\">WhatIfPageBase\u003C/code> — simulation UI\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">simulation.ts\u003C/code> — \u003Ccode dir=\"auto\">directAdjustment\u003C/code> computation\u003C/li>\n\u003Cli>\u003Ca href=\"../analysis/staged-analysis.md\">staged-analysis.md\u003C/a> — staged comparison methodology\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"two-entry-paths-into-scout\">Two Entry Paths into Scout\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#two-entry-paths-into-scout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two Entry Paths into Scout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Not every analysis starts the same way. VariScout supports two distinct paths into the Scout phase:\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n START[\"Data loaded\\n(Frame complete)\"] --> PATH\n\n PATH --> DISC[\"Discovery Path\"]\n PATH --> HYPO[\"Hypothesis-Driven Path\"]\n\n DISC --> SCAN[\"Scan all Four Lenses\"]\n SCAN --> DRILL[\"Drill into patterns\"]\n DRILL --> FIND[\"Pin findings\"]\n FIND --> INV[\"Move to Investigate\"]\n\n HYPO --> SUGGEST[\"CoScout suggests pattern\"]\n SUGGEST --> CONFIRM[\"Confirm with chart evidence\"]\n CONFIRM --> JUMP[\"Jump directly to Investigate\"]\n\n style DISC fill:#22c55e,color:#fff\n style HYPO fill:#f59e0b,color:#fff\n\u003C/pre>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Path\u003C/th>\u003Cth>Starting Point\u003C/th>\u003Cth>Duration\u003C/th>\u003Cth>Best For\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Discovery\u003C/strong>\u003C/td>\u003Ctd>No prior knowledge\u003C/td>\u003Ctd>15-30 min\u003C/td>\u003Ctd>New datasets, exploratory analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Hypothesis-driven\u003C/strong>\u003C/td>\u003Ctd>CoScout suggestion or prior knowledge\u003C/td>\u003Ctd>5-10 min\u003C/td>\u003Ctd>Known issues, repeat monitoring\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-drill-down-loop\">The Drill-Down Loop\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-drill-down-loop\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Drill-Down Loop”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The drill-down loop is the core interaction pattern within the Scout phase. Each iteration narrows the data scope and increases the percentage of variation explained.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n ALL[\"All Data\"] --> READ[\"Read eta-squared\\n(ANOVA under Boxplot)\"]\n READ --> CLICK[\"Click highest-eta factor\"]\n CLICK --> FILTER[\"Filter applied\\n(chip shows contribution %)\"]\n FILTER --> UPDATE[\"Charts update\\nfor filtered subset\"]\n UPDATE --> CHECK{Enough variation\\nisolated?}\n CHECK -- \"Yes (>50%)\" --> PIN[\"Pin finding\"]\n CHECK -- \"No\" --> READ\n\n style ALL fill:#3b82f6,color:#fff\n style PIN fill:#22c55e,color:#fff\n\u003C/pre>\n\u003Cp>Each filter chip displays the cumulative contribution percentage (Total SS scope), giving the analyst a running measure of how much variation has been explained by the current drill path. See \u003Ca href=\"drill-down-workflow.md\">drill-down-workflow.md\u003C/a> for the detailed protocol.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision-point-map\">Decision Point Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision-point-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision Point Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Twelve key decision points shape the analysis journey. Each has a clear question, evidence source, and branching outcome.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Decision Point\u003C/th>\u003Cth>Phase\u003C/th>\u003Cth>Evidence\u003C/th>\u003Cth>Yes Path\u003C/th>\u003Cth>No Path\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Stable?\u003C/td>\u003Ctd>Scout\u003C/td>\u003Ctd>I-Chart (control limits, Nelson rules)\u003C/td>\u003Ctd>Proceed to Boxplot\u003C/td>\u003Ctd>Investigate special causes first\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Which factor drives variation?\u003C/td>\u003Ctd>Scout\u003C/td>\u003Ctd>Boxplot eta-squared\u003C/td>\u003Ctd>Drill into highest eta-squared\u003C/td>\u003Ctd>Check interactions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Enough variation isolated?\u003C/td>\u003Ctd>Scout\u003C/td>\u003Ctd>Cumulative Total SS > 50%\u003C/td>\u003Ctd>Pin finding, move to Investigate\u003C/td>\u003Ctd>Continue drilling\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Capable?\u003C/td>\u003Ctd>Scout\u003C/td>\u003Ctd>Cpk vs target (1.33 default)\u003C/td>\u003Ctd>Process acceptable\u003C/td>\u003Ctd>Needs improvement\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Quick Check or Deep Dive?\u003C/td>\u003Ctd>Scout\u003C/td>\u003Ctd>Time available, severity\u003C/td>\u003Ctd>Quick Check (~5 min)\u003C/td>\u003Ctd>Deep Dive (~30 min)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Discovery or Hypothesis-driven?\u003C/td>\u003Ctd>Scout\u003C/td>\u003Ctd>Prior knowledge, CoScout input\u003C/td>\u003Ctd>Discovery (scan all lenses)\u003C/td>\u003Ctd>Hypothesis-driven (confirm and jump)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>Key Driver or Low Impact?\u003C/td>\u003Ctd>Investigate\u003C/td>\u003Ctd>eta-squared magnitude, Pareto rank\u003C/td>\u003Ctd>Tag as key-driver\u003C/td>\u003Ctd>Tag as low-impact\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>Single or multiple hypotheses?\u003C/td>\u003Ctd>Investigate\u003C/td>\u003Ctd>Complexity of problem\u003C/td>\u003Ctd>Test single hypothesis\u003C/td>\u003Ctd>Diverge into sub-hypotheses\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>Data, gemba, or expert validation?\u003C/td>\u003Ctd>Investigate\u003C/td>\u003Ctd>Available evidence\u003C/td>\u003Ctd>Statistical test (ANOVA)\u003C/td>\u003Ctd>Physical observation or consultation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>Converged on root cause?\u003C/td>\u003Ctd>Investigate\u003C/td>\u003Ctd>Hypothesis validation status\u003C/td>\u003Ctd>Enter Improve phase\u003C/td>\u003Ctd>Generate more hypotheses\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>What-If projection effective?\u003C/td>\u003Ctd>Improve\u003C/td>\u003Ctd>Projected Cpk meets target\u003C/td>\u003Ctd>Define corrective actions\u003C/td>\u003Ctd>Revise approach\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>Verification passed?\u003C/td>\u003Ctd>Improve\u003C/td>\u003Ctd>Staged analysis (before vs after)\u003C/td>\u003Ctd>Resolve finding, close\u003C/td>\u003Ctd>PDCA loop back to Frame\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"all-loops-visualized\">All Loops Visualized\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#all-loops-visualized\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “All Loops Visualized”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Five feedback loops keep the analysis iterative and self-correcting:\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n FRAME[\"FRAME\"] --> SCOUT[\"SCOUT\"]\n SCOUT --> INVESTIGATE[\"INVESTIGATE\"]\n INVESTIGATE --> IMPROVE[\"IMPROVE\"]\n\n %% Drill-down loop (Scout)\n SCOUT -- \"Drill-down loop\\n(filter, read, repeat)\" --> SCOUT\n\n %% Hypothesis validation loop (Investigate)\n INVESTIGATE -- \"Hypothesis loop\\n(diverge, validate, converge)\" --> INVESTIGATE\n\n %% What-If iteration loop (Improve)\n IMPROVE -- \"What-If loop\\n(project, adjust, re-project)\" --> IMPROVE\n\n %% PDCA re-entry loop\n IMPROVE -- \"PDCA loop\\n(verify failed or new cycle)\" --> FRAME\n\n %% Add Data loop\n SCOUT -- \"Add Data loop\\n(incomplete dataset)\" --> FRAME\n\n style FRAME fill:#3b82f6,color:#fff\n style SCOUT fill:#22c55e,color:#fff\n style INVESTIGATE fill:#f59e0b,color:#fff\n style IMPROVE fill:#8b5cf6,color:#fff\n\u003C/pre>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Loop\u003C/th>\u003Cth>Phase\u003C/th>\u003Cth>Trigger\u003C/th>\u003Cth>Exit Condition\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Drill-down\u003C/td>\u003Ctd>Scout\u003C/td>\u003Ctd>eta-squared suggests deeper factor\u003C/td>\u003Ctd>>50% variation explained or no more factors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hypothesis validation\u003C/td>\u003Ctd>Investigate\u003C/td>\u003Ctd>Hypothesis not yet confirmed\u003C/td>\u003Ctd>Root cause validated with evidence\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>What-If iteration\u003C/td>\u003Ctd>Improve\u003C/td>\u003Ctd>Projected Cpk below target\u003C/td>\u003Ctd>Projection meets target or approach revised\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PDCA re-entry\u003C/td>\u003Ctd>Improve to Frame\u003C/td>\u003Ctd>Staged verification fails or new improvement cycle\u003C/td>\u003Ctd>Verification passes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Add Data\u003C/td>\u003Ctd>Scout to Frame\u003C/td>\u003Ctd>Dataset missing factors or insufficient samples\u003C/td>\u003Ctd>Data reloaded with additional columns/rows\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"four-lenses-workflow.md\">Four Lenses Workflow\u003C/a> — detailed CHANGE / FLOW / FAILURE / VALUE methodology\u003C/li>\n\u003Cli>\u003Ca href=\"drill-down-workflow.md\">Drill-Down Workflow\u003C/a> — progressive stratification using filter chips\u003C/li>\n\u003Cli>\u003Ca href=\"quick-check.md\">Quick Check\u003C/a> — 5-minute monitoring protocol\u003C/li>\n\u003Cli>\u003Ca href=\"deep-dive.md\">Deep Dive\u003C/a> — 30-minute investigation protocol\u003C/li>\n\u003Cli>\u003Ca href=\"investigation-to-action.md\">Investigation to Action\u003C/a> — findings and What-If workflow\u003C/li>\n\u003Cli>\u003Ca href=\"investigation-lifecycle-map.md\">Investigation Lifecycle Map\u003C/a> — IDEOI state machine detail\u003C/li>\n\u003Cli>\u003Ca href=\"decision-trees.md\">Decision Trees\u003C/a> — branching logic for analysis decisions\u003C/li>\n\u003C/ul>", + { + "headings": 338, + "localImagePaths": 424, + "remoteImagePaths": 425, + "frontmatter": 426, + "imagePaths": 428 + }, + [ + 339, 341, 344, 347, 350, 353, 356, 359, 362, 365, 367, 370, 373, 375, 378, 380, 383, 386, 388, + 390, 392, 395, 397, 400, 402, 404, 406, 409, 411, 414, 417, 418, 421 + ], + { "depth": 30, "slug": 340, "text": 327 }, + "analysis-journey-map", + { "depth": 33, "slug": 342, "text": 343 }, + "journey-overview", + "Journey Overview", + { "depth": 33, "slug": 345, "text": 346 }, + "phase-1-frame", + "Phase 1: FRAME", + { "depth": 79, "slug": 348, "text": 349 }, + "steps", + "Steps", + { "depth": 79, "slug": 351, "text": 352 }, + "data-shapes-at-boundary", + "Data Shapes at Boundary", + { "depth": 79, "slug": 354, "text": 355 }, + "tier-differences", + "Tier Differences", + { "depth": 79, "slug": 357, "text": 358 }, + "coscout-in-frame", + "CoScout in Frame", + { "depth": 79, "slug": 360, "text": 361 }, + "key-code-references", + "Key Code References", + { "depth": 33, "slug": 363, "text": 364 }, + "phase-2-scout", + "Phase 2: SCOUT", + { "depth": 79, "slug": 366, "text": 349 }, + "steps-1", + { "depth": 79, "slug": 368, "text": 369 }, + "two-speeds", + "Two Speeds", + { "depth": 79, "slug": 371, "text": 372 }, + "data-shapes", + "Data Shapes", + { "depth": 79, "slug": 374, "text": 355 }, + "tier-differences-1", + { "depth": 79, "slug": 376, "text": 377 }, + "coscout-in-scout", + "CoScout in Scout", + { "depth": 79, "slug": 379, "text": 361 }, + "key-code-references-1", + { "depth": 33, "slug": 381, "text": 382 }, + "phase-3-investigate", + "Phase 3: INVESTIGATE", + { "depth": 79, "slug": 384, "text": 385 }, + "ideoi-phases", + "IDEOI Phases", + { "depth": 79, "slug": 387, "text": 349 }, + "steps-2", + { "depth": 79, "slug": 389, "text": 372 }, + "data-shapes-1", + { "depth": 79, "slug": 391, "text": 355 }, + "tier-differences-2", + { "depth": 79, "slug": 393, "text": 394 }, + "coscout-in-investigate", + "CoScout in Investigate", + { "depth": 79, "slug": 396, "text": 361 }, + "key-code-references-2", + { "depth": 33, "slug": 398, "text": 399 }, + "phase-4-improve", + "Phase 4: IMPROVE", + { "depth": 79, "slug": 401, "text": 349 }, + "steps-3", + { "depth": 79, "slug": 403, "text": 372 }, + "data-shapes-2", + { "depth": 79, "slug": 405, "text": 355 }, + "tier-differences-3", + { "depth": 79, "slug": 407, "text": 408 }, + "coscout-in-improve", + "CoScout in Improve", + { "depth": 79, "slug": 410, "text": 361 }, + "key-code-references-3", + { "depth": 33, "slug": 412, "text": 413 }, + "two-entry-paths-into-scout", + "Two Entry Paths into Scout", + { "depth": 33, "slug": 415, "text": 416 }, + "the-drill-down-loop", + "The Drill-Down Loop", + { "depth": 33, "slug": 95, "text": 96 }, + { "depth": 33, "slug": 419, "text": 420 }, + "all-loops-visualized", + "All Loops Visualized", + { "depth": 33, "slug": 422, "text": 423 }, + "related-documentation", + "Related Documentation", + [], + [], + { "title": 327, "description": 328, "journey-phase": 427 }, + [155], + [], + "03-features/workflows/investigation-lifecycle-map", + { "id": 429, "data": 431, "body": 437, "filePath": 438, "digest": 439, "rendered": 440 }, + { + "title": 432, + "description": 433, + "editUrl": 16, + "head": 434, + "template": 18, + "sidebar": 435, + "pagefind": 16, + "draft": 20 + }, + "Investigation Lifecycle Map", + "State diagrams for IDEOI investigation phases and Finding status lifecycle with transition triggers and CoScout behavior", + [], + { "hidden": 20, "attrs": 436 }, + {}, + "# Investigation Lifecycle Map\n\nState diagrams for IDEOI investigation phases, Finding status transitions, and hypothesis validation — showing how CoScout adapts its behavior at each stage.\n\n## Overview\n\nThe IDEOI framework (Initial, Diverging, Evaluating, Organizing, Implementing) maps the investigation lifecycle from first data scan through verified improvement. Each phase changes CoScout's behavior, UI presentation, and suggested questions.\n\nThe framework connects three moving parts:\n\n1. **IDEOI phases** — the analyst's cognitive stage in the investigation\n2. **Finding statuses** — the lifecycle of individual observations\n3. **Hypothesis validation** — the evidence-gathering sub-flow within Diverging/Validating\n\n## IDEOI State Diagram\n\n```mermaid\nstateDiagram-v2\n [*] --> Initial\n Initial --> Diverging : First hypothesis created\n Diverging --> Validating : Hypothesis selected for testing\n Validating --> Diverging : Need more hypotheses\n Validating --> Converging : Evidence supports/refutes\n Converging --> Diverging : Insufficient evidence, explore more\n Converging --> Acting : Root cause confirmed\n Acting --> [*] : Outcome recorded\n\n state Initial {\n [*] --> ScanningData\n ScanningData --> PinningFindings\n PinningFindings --> ScanningData\n }\n\n state Diverging {\n [*] --> GeneratingHypotheses\n GeneratingHypotheses --> AddingSubHypotheses\n }\n\n state Validating {\n [*] --> DataValidation\n DataValidation --> GembaValidation\n GembaValidation --> ExpertValidation\n }\n\n state Converging {\n [*] --> ReviewingEvidence\n ReviewingEvidence --> IdentifyingRootCause\n }\n\n state Acting {\n [*] --> PlanningActions\n PlanningActions --> VerifyingImprovement\n }\n```\n\n## Phase Behavior Table\n\nEach IDEOI phase triggers distinct CoScout behavior and UI changes.\n\n| Phase | Trigger In | CoScout Behavior | UI Changes | Suggested Questions |\n|-------|-----------|-----------------|------------|-------------------|\n| **Initial** | Data loaded, scanning charts | Suggests patterns in data | Dashboard with Four Lenses | \"What patterns do you see in the I-Chart?\" |\n| **Diverging** | First finding pinned | Suggests possible hypotheses | Findings panel opens, hypothesis form | \"Could [factor] be driving this?\" |\n| **Validating** | Hypothesis selected | Provides data evidence for/against | Validation checklist, ANOVA highlights | \"eta-squared for [factor] is X% — significant?\" |\n| **Converging** | Evidence collected | Summarizes evidence, suggests root cause | Finding cards show validation status | \"Evidence points to [factor] as root cause\" |\n| **Acting** | Root cause confirmed | Suggests corrective actions | What-If simulator, action items | \"What if you reduced [factor] variation by X%?\" |\n\n## Finding Status Lifecycle\n\nIndividual findings move through a status lifecycle that maps onto the broader IDEOI phases. PWA supports the first three statuses; Azure supports all five.\n\n```mermaid\nstateDiagram-v2\n [*] --> observed\n observed --> investigating : Start investigating\n investigating --> analyzed : Analysis complete\n analyzed --> improving : Action planned (Azure only)\n improving --> resolved : Verification passed (Azure only)\n resolved --> [*]\n\n observed --> observed : Add comment\n investigating --> investigating : Add comment, link hypothesis\n analyzed --> analyzed : Classify tag (key-driver / low-impact)\n improving --> improving : Update action progress\n```\n\n## Finding Status Properties\n\n| Status | Badge Color | Meaning | Available In |\n|--------|------------|---------|-------------|\n| `observed` | Amber | Pattern spotted, not yet investigated | PWA, Azure |\n| `investigating` | Blue | Actively drilling into this finding | PWA, Azure |\n| `analyzed` | Purple | Analysis completed, classified | PWA, Azure |\n| `improving` | Teal | Action planned, in progress | Azure only |\n| `resolved` | Green | Verification passed, closed | Azure only |\n\n## Hypothesis Validation Sub-flow\n\nWithin the Validating phase, each hypothesis goes through an evidence-gathering loop with three validation paths.\n\n```mermaid\nflowchart TD\n A[Hypothesis created] --> B{Choose validation path}\n B --> C[Data validation]\n B --> D[Gemba validation]\n B --> E[Expert validation]\n C --> F[Check ANOVA eta-squared, filter and compare]\n D --> G[Go to the process, observe]\n E --> H[Consult domain expert]\n F --> I[Record evidence]\n G --> I\n H --> I\n I --> J{Evidence outcome}\n J -->|Supports| K[Mark hypothesis supported]\n J -->|Refutes| L[Mark hypothesis refuted]\n J -->|Inconclusive| M[Gather more evidence]\n M --> B\n K --> N[Update hypothesis status]\n L --> N\n```\n\n**Auto-validation thresholds** (based on ANOVA eta-squared):\n\n| eta-squared | Strength | Interpretation |\n|-------------|----------|---------------|\n| > 0.14 | Strong | Factor likely driving variation |\n| 0.06 - 0.14 | Moderate | Factor contributes, investigate further |\n| \u003C 0.06 | Weak | Factor unlikely to be root cause |\n\n## Hooks and Components\n\nEach IDEOI concept maps to a specific hook or component in the codebase.\n\n| Concept | Hook / Component | Package |\n|---------|-----------------|---------|\n| Finding CRUD | `useFindings` | `@variscout/hooks` |\n| Hypothesis CRUD | `useHypotheses` | `@variscout/hooks` |\n| IDEOI phase detection | `detectInvestigationPhase()` | `@variscout/core` |\n| CoScout phase context | `getCoScoutPhase()` | `@variscout/core` |\n| Finding cards | `FindingCard` | `@variscout/ui` |\n| Board view | `FindingBoardView` | `@variscout/ui` |\n| What-If simulator | `WhatIfSimulator` | `@variscout/ui` |\n\n## Related Documentation\n\n- [Investigation to Action Workflow](investigation-to-action.md) — end-to-end analyst workflow from data load to projection\n- [Decision Trees](decision-trees.md) — branching logic for analysis decisions\n- [Drill-Down Workflow](drill-down-workflow.md) — factor drill-down navigation\n- [Four Lenses Workflow](four-lenses-workflow.md) — the four analytical perspectives (Change, Failure, Flow, Value)", + "src/content/docs/03-features/workflows/investigation-lifecycle-map.md", + "046f1e8a9c89f3bd", + { "html": 441, "metadata": 442 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"investigation-lifecycle-map\">Investigation Lifecycle Map\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-lifecycle-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation Lifecycle Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>State diagrams for IDEOI investigation phases, Finding status transitions, and hypothesis validation — showing how CoScout adapts its behavior at each stage.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The IDEOI framework (Initial, Diverging, Evaluating, Organizing, Implementing) maps the investigation lifecycle from first data scan through verified improvement. Each phase changes CoScout’s behavior, UI presentation, and suggested questions.\u003C/p>\n\u003Cp>The framework connects three moving parts:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>IDEOI phases\u003C/strong> — the analyst’s cognitive stage in the investigation\u003C/li>\n\u003Cli>\u003Cstrong>Finding statuses\u003C/strong> — the lifecycle of individual observations\u003C/li>\n\u003Cli>\u003Cstrong>Hypothesis validation\u003C/strong> — the evidence-gathering sub-flow within Diverging/Validating\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ideoi-state-diagram\">IDEOI State Diagram\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ideoi-state-diagram\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “IDEOI State Diagram”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">stateDiagram-v2\n [*] --> Initial\n Initial --> Diverging : First hypothesis created\n Diverging --> Validating : Hypothesis selected for testing\n Validating --> Diverging : Need more hypotheses\n Validating --> Converging : Evidence supports/refutes\n Converging --> Diverging : Insufficient evidence, explore more\n Converging --> Acting : Root cause confirmed\n Acting --> [*] : Outcome recorded\n\n state Initial {\n [*] --> ScanningData\n ScanningData --> PinningFindings\n PinningFindings --> ScanningData\n }\n\n state Diverging {\n [*] --> GeneratingHypotheses\n GeneratingHypotheses --> AddingSubHypotheses\n }\n\n state Validating {\n [*] --> DataValidation\n DataValidation --> GembaValidation\n GembaValidation --> ExpertValidation\n }\n\n state Converging {\n [*] --> ReviewingEvidence\n ReviewingEvidence --> IdentifyingRootCause\n }\n\n state Acting {\n [*] --> PlanningActions\n PlanningActions --> VerifyingImprovement\n }\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-behavior-table\">Phase Behavior Table\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-behavior-table\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase Behavior Table”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each IDEOI phase triggers distinct CoScout behavior and UI changes.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Phase\u003C/th>\u003Cth>Trigger In\u003C/th>\u003Cth>CoScout Behavior\u003C/th>\u003Cth>UI Changes\u003C/th>\u003Cth>Suggested Questions\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Initial\u003C/strong>\u003C/td>\u003Ctd>Data loaded, scanning charts\u003C/td>\u003Ctd>Suggests patterns in data\u003C/td>\u003Ctd>Dashboard with Four Lenses\u003C/td>\u003Ctd>”What patterns do you see in the I-Chart?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Diverging\u003C/strong>\u003C/td>\u003Ctd>First finding pinned\u003C/td>\u003Ctd>Suggests possible hypotheses\u003C/td>\u003Ctd>Findings panel opens, hypothesis form\u003C/td>\u003Ctd>”Could [factor] be driving this?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Validating\u003C/strong>\u003C/td>\u003Ctd>Hypothesis selected\u003C/td>\u003Ctd>Provides data evidence for/against\u003C/td>\u003Ctd>Validation checklist, ANOVA highlights\u003C/td>\u003Ctd>”eta-squared for [factor] is X% — significant?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Converging\u003C/strong>\u003C/td>\u003Ctd>Evidence collected\u003C/td>\u003Ctd>Summarizes evidence, suggests root cause\u003C/td>\u003Ctd>Finding cards show validation status\u003C/td>\u003Ctd>”Evidence points to [factor] as root cause”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Acting\u003C/strong>\u003C/td>\u003Ctd>Root cause confirmed\u003C/td>\u003Ctd>Suggests corrective actions\u003C/td>\u003Ctd>What-If simulator, action items\u003C/td>\u003Ctd>”What if you reduced [factor] variation by X%?”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"finding-status-lifecycle\">Finding Status Lifecycle\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#finding-status-lifecycle\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Finding Status Lifecycle”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Individual findings move through a status lifecycle that maps onto the broader IDEOI phases. PWA supports the first three statuses; Azure supports all five.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">stateDiagram-v2\n [*] --> observed\n observed --> investigating : Start investigating\n investigating --> analyzed : Analysis complete\n analyzed --> improving : Action planned (Azure only)\n improving --> resolved : Verification passed (Azure only)\n resolved --> [*]\n\n observed --> observed : Add comment\n investigating --> investigating : Add comment, link hypothesis\n analyzed --> analyzed : Classify tag (key-driver / low-impact)\n improving --> improving : Update action progress\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"finding-status-properties\">Finding Status Properties\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#finding-status-properties\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Finding Status Properties”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Status\u003C/th>\u003Cth>Badge Color\u003C/th>\u003Cth>Meaning\u003C/th>\u003Cth>Available In\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">observed\u003C/code>\u003C/td>\u003Ctd>Amber\u003C/td>\u003Ctd>Pattern spotted, not yet investigated\u003C/td>\u003Ctd>PWA, Azure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">investigating\u003C/code>\u003C/td>\u003Ctd>Blue\u003C/td>\u003Ctd>Actively drilling into this finding\u003C/td>\u003Ctd>PWA, Azure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">analyzed\u003C/code>\u003C/td>\u003Ctd>Purple\u003C/td>\u003Ctd>Analysis completed, classified\u003C/td>\u003Ctd>PWA, Azure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">improving\u003C/code>\u003C/td>\u003Ctd>Teal\u003C/td>\u003Ctd>Action planned, in progress\u003C/td>\u003Ctd>Azure only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">resolved\u003C/code>\u003C/td>\u003Ctd>Green\u003C/td>\u003Ctd>Verification passed, closed\u003C/td>\u003Ctd>Azure only\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"hypothesis-validation-sub-flow\">Hypothesis Validation Sub-flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#hypothesis-validation-sub-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hypothesis Validation Sub-flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Within the Validating phase, each hypothesis goes through an evidence-gathering loop with three validation paths.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Hypothesis created] --> B{Choose validation path}\n B --> C[Data validation]\n B --> D[Gemba validation]\n B --> E[Expert validation]\n C --> F[Check ANOVA eta-squared, filter and compare]\n D --> G[Go to the process, observe]\n E --> H[Consult domain expert]\n F --> I[Record evidence]\n G --> I\n H --> I\n I --> J{Evidence outcome}\n J -->|Supports| K[Mark hypothesis supported]\n J -->|Refutes| L[Mark hypothesis refuted]\n J -->|Inconclusive| M[Gather more evidence]\n M --> B\n K --> N[Update hypothesis status]\n L --> N\n\u003C/pre>\n\u003Cp>\u003Cstrong>Auto-validation thresholds\u003C/strong> (based on ANOVA eta-squared):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>eta-squared\u003C/th>\u003Cth>Strength\u003C/th>\u003Cth>Interpretation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>> 0.14\u003C/td>\u003Ctd>Strong\u003C/td>\u003Ctd>Factor likely driving variation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>0.06 - 0.14\u003C/td>\u003Ctd>Moderate\u003C/td>\u003Ctd>Factor contributes, investigate further\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>< 0.06\u003C/td>\u003Ctd>Weak\u003C/td>\u003Ctd>Factor unlikely to be root cause\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"hooks-and-components\">Hooks and Components\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#hooks-and-components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hooks and Components”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each IDEOI concept maps to a specific hook or component in the codebase.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Concept\u003C/th>\u003Cth>Hook / Component\u003C/th>\u003Cth>Package\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Finding CRUD\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useFindings\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hypothesis CRUD\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useHypotheses\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>IDEOI phase detection\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">detectInvestigationPhase()\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CoScout phase context\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getCoScoutPhase()\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Finding cards\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FindingCard\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Board view\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FindingBoardView\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>What-If simulator\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">WhatIfSimulator\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"investigation-to-action.md\">Investigation to Action Workflow\u003C/a> — end-to-end analyst workflow from data load to projection\u003C/li>\n\u003Cli>\u003Ca href=\"decision-trees.md\">Decision Trees\u003C/a> — branching logic for analysis decisions\u003C/li>\n\u003Cli>\u003Ca href=\"drill-down-workflow.md\">Drill-Down Workflow\u003C/a> — factor drill-down navigation\u003C/li>\n\u003Cli>\u003Ca href=\"four-lenses-workflow.md\">Four Lenses Workflow\u003C/a> — the four analytical perspectives (Change, Failure, Flow, Value)\u003C/li>\n\u003C/ul>", + { + "headings": 443, + "localImagePaths": 468, + "remoteImagePaths": 469, + "frontmatter": 470, + "imagePaths": 472 + }, + [444, 446, 449, 452, 455, 458, 461, 464, 467], + { "depth": 30, "slug": 445, "text": 432 }, + "investigation-lifecycle-map", + { "depth": 33, "slug": 447, "text": 448 }, + "overview", + "Overview", + { "depth": 33, "slug": 450, "text": 451 }, + "ideoi-state-diagram", + "IDEOI State Diagram", + { "depth": 33, "slug": 453, "text": 454 }, + "phase-behavior-table", + "Phase Behavior Table", + { "depth": 33, "slug": 456, "text": 457 }, + "finding-status-lifecycle", + "Finding Status Lifecycle", + { "depth": 33, "slug": 459, "text": 460 }, + "finding-status-properties", + "Finding Status Properties", + { "depth": 33, "slug": 462, "text": 463 }, + "hypothesis-validation-sub-flow", + "Hypothesis Validation Sub-flow", + { "depth": 33, "slug": 465, "text": 466 }, + "hooks-and-components", + "Hooks and Components", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 432, "description": 433, "journey-phase": 471 }, + "investigate", + [], + "glossary", + { "id": 473, "data": 475, "body": 480, "filePath": 481, "digest": 482, "rendered": 483 }, + { + "title": 476, + "editUrl": 16, + "head": 477, + "template": 18, + "sidebar": 478, + "pagefind": 16, + "draft": 20 + }, + "Glossary", + [], + { "hidden": 20, "attrs": 479 }, + {}, + "# Glossary\n\nStatistical and quality terms used across VariScout.\n\n---\n\n## Control Limits\n\n### UCL (Upper Control Limit)\n\nUpper Control Limit. Statistical boundary showing process behavior, set at mean + 3 standard deviations.\n\nUCL represents the upper natural boundary of process variation. Points above UCL indicate special cause variation requiring investigation. Different from USL which is a customer requirement.\n\n**Related:** [LCL](#lcl-lower-control-limit), [Mean](#mean), [Std Dev](#std-dev)\n\n### LCL (Lower Control Limit)\n\nLower Control Limit. Statistical boundary showing process behavior, set at mean - 3 standard deviations.\n\nLCL represents the lower natural boundary of process variation. Points below LCL indicate special cause variation requiring investigation. Different from LSL which is a customer requirement.\n\n**Related:** [UCL](#ucl-upper-control-limit), [Mean](#mean), [Std Dev](#std-dev)\n\n### USL (Upper Specification Limit)\n\nUpper Specification Limit. Customer-defined maximum acceptable value for the product.\n\nUSL is the customer's voice - the maximum value they will accept. Products above USL are out of spec and rejected. Set by customer requirements, not process data.\n\n**Related:** [LSL](#lsl-lower-specification-limit), [Target](#target), [Cp](#cp), [Cpk](#cpk)\n\n### LSL (Lower Specification Limit)\n\nLower Specification Limit. Customer-defined minimum acceptable value for the product.\n\nLSL is the customer's voice - the minimum value they will accept. Products below LSL are out of spec and rejected. Set by customer requirements, not process data.\n\n**Related:** [USL](#usl-upper-specification-limit), [Target](#target), [Cp](#cp), [Cpk](#cpk)\n\n### Target\n\nThe ideal or nominal value for the measurement, typically the midpoint between LSL and USL.\n\nTarget represents the ideal value customers want. Process centering is assessed by comparing the mean to the target.\n\n**Related:** [USL](#usl-upper-specification-limit), [LSL](#lsl-lower-specification-limit), [Cpk](#cpk)\n\n---\n\n## Capability Metrics\n\n### Cp\n\nProcess Capability. Measures how well your process fits within spec limits.\n\nCp compares the width of specification limits to 6σ_within of the process. Cp = (USL - LSL) / (6σ_within), where σ_within is estimated from the moving range (MR̄/d2). Higher values mean the process has room to spare within specs. Does not account for centering.\n\n**Related:** [Cpk](#cpk), [USL](#usl-upper-specification-limit), [LSL](#lsl-lower-specification-limit), [Std Dev](#std-dev)\n\n### Cpk\n\nProcess Capability Index. Like Cp, but accounts for how well centered the process is.\n\nCpk = min(CPU, CPL), where CPU = (USL - Mean) / 3σ_within and CPL = (Mean - LSL) / 3σ_within. σ_within is estimated from the moving range (MR̄/d2). A Cpk much lower than Cp indicates the process mean is shifted toward one spec limit.\n\n**Related:** [Cp](#cp), [USL](#usl-upper-specification-limit), [LSL](#lsl-lower-specification-limit), [Mean](#mean)\n\n### Pass Rate\n\nPercentage of measurements within specification limits (between LSL and USL).\n\nPass Rate shows what proportion of products meet customer requirements. 100% means all products are in spec. Also known as yield or conformance rate.\n\n**Related:** [USL](#usl-upper-specification-limit), [LSL](#lsl-lower-specification-limit), [Rejected](#rejected)\n\n### Rejected\n\nPercentage of measurements outside specification limits (above USL or below LSL).\n\nRejected rate is the inverse of pass rate. These are products that fail to meet customer requirements and must be scrapped, reworked, or conceded.\n\n**Related:** [Pass Rate](#pass-rate), [USL](#usl-upper-specification-limit), [LSL](#lsl-lower-specification-limit)\n\n---\n\n## Basic Statistics\n\n### Mean\n\nAverage value. Sum of all measurements divided by the count.\n\nThe arithmetic mean represents the center of the data distribution. Compare to target to assess centering. Also called X-bar in control charts.\n\n**Related:** [Std Dev](#std-dev), [UCL](#ucl-upper-control-limit), [LCL](#lcl-lower-control-limit)\n\n### Std Dev\n\nStandard Deviation. Measures the spread or variability of measurements around the mean.\n\nStandard deviation (σ) quantifies how much values vary from the average. Smaller values indicate more consistent processes. Used to calculate control limits and capability indices.\n\n**Related:** [Mean](#mean), [Cp](#cp), [UCL](#ucl-upper-control-limit), [LCL](#lcl-lower-control-limit)\n\n---\n\n## ANOVA Statistics\n\n### F-Statistic\n\nMeasures the ratio of between-group variance to within-group variance in ANOVA.\n\nF-statistic compares variation between groups to variation within groups. Higher F values indicate larger differences between group means relative to variation within groups.\n\n**Related:** [p-value](#p-value), [η² (Eta-squared)](#2-eta-squared)\n\n### p-value\n\nProbability the observed difference happened by chance. p \u003C 0.05 = statistically significant.\n\nThe p-value tests the null hypothesis that all group means are equal. Small p-values (typically \u003C 0.05) provide evidence that at least one group mean differs from the others.\n\n**Related:** [F-Statistic](#f-statistic), [η² (Eta-squared)](#2-eta-squared)\n\n### η² (Eta-squared)\n\nEffect size showing how much variation is explained by the factor. Small \u003C 0.06, medium 0.06-0.14, large > 0.14.\n\nEta-squared (η²) represents the proportion of total variance explained by the grouping factor. Unlike p-value, it indicates practical significance - how much the factor matters. In VariScout, η² is shown in the ANOVA results panel and used internally to suggest the next drill-down factor.\n\n**Note:** The user-facing variation metric in filter chips, breadcrumbs, and the progress bar is **Total SS Contribution** (see below), not η².\n\n**Related:** [F-Statistic](#f-statistic), [p-value](#p-value), [Total SS Contribution](#total-ss-contribution)\n\n### Total SS Contribution\n\nThe percentage of total variation (Sum of Squares) that a specific category or filter selection accounts for. Unlike η² (which only captures between-group variation), Total SS Contribution captures both mean shift and within-group spread.\n\nThis is the primary user-facing metric in VariScout's drill-down workflow. Filter chips show each selection's Total SS Contribution, and the progress bar shows the cumulative scope — the product of contributions across drill levels.\n\n**Related:** [η² (Eta-squared)](#2-eta-squared)\n\n---\n\n## Regression Statistics\n\n### R²\n\nCoefficient of determination. Shows how much of Y's variation is explained by X. Closer to 1 = stronger.\n\nR-squared ranges from 0 to 1. An R² of 0.80 means 80% of the variation in Y can be explained by the relationship with X. The remaining 20% is due to other factors or random variation.\n\n**Related:** [Slope](#slope), [p-value](#p-value)\n\n### Adjusted R²\n\nA modified R² that adjusts for the number of predictors. Only increases if a new predictor improves the model more than expected by chance.\n\nUnlike regular R², adjusted R² penalizes adding predictors that do not meaningfully improve the model. Use it to compare models with different numbers of predictors.\n\n**Related:** [R²](#r2), [VIF](#vif)\n\n### Slope\n\nHow much Y changes for each unit increase in X. Positive = Y increases with X.\n\nThe slope quantifies the rate of change in the relationship. A slope of 2.5 means Y increases by 2.5 units for every 1 unit increase in X.\n\n**Related:** [R²](#r2), [Intercept](#intercept)\n\n### Intercept\n\nThe predicted value of Y when X equals zero.\n\nThe y-intercept is where the regression line crosses the Y-axis. May not have practical meaning if X=0 is outside the range of observed data.\n\n**Related:** [Slope](#slope), [R²](#r2)\n\n### VIF\n\nVariance Inflation Factor. Measures how much a coefficient variance is inflated due to correlation with other predictors.\n\nVIF = 1 means no correlation with other predictors. VIF 1-5 is acceptable. VIF 5-10 indicates moderate multicollinearity. VIF > 10 suggests serious multicollinearity requiring action.\n\n**Related:** [Adjusted R²](#adjusted-r2)\n\n---\n\n## Methodology\n\n### Staged Analysis\n\nAnalysis approach that calculates separate control limits for distinct process phases (e.g., before/after improvement).\n\nStaged analysis reveals improvements that combined data hides. Each stage gets its own mean and control limits calculated independently, letting you see shifts in both center and variation.\n\n**Related:** [UCL](#ucl-upper-control-limit), [LCL](#lcl-lower-control-limit), [Mean](#mean), [Std Dev](#std-dev)\n\n### Total SS Contribution\n\nA category's share of total sum of squares. Captures both mean shift AND spread (within-group variation).\n\nUnlike between-group SS which only measures mean differences, Total SS contribution shows a category's full impact on variation. A category with mean near overall mean but high spread now shows non-zero impact. Sum of all category contributions equals 100%.\n\n**Related:** [η² (Eta-squared)](#2-eta-squared), [Std Dev](#std-dev)\n\n### Nelson Rules\n\nEight statistical tests for detecting non-random patterns (special causes) on control charts. Rule 1: any point beyond 3σ. Rule 2: nine consecutive points on the same side of the mean. Rules 3-8 detect trends, oscillations, and stratification patterns. Violations indicate special cause variation that should be investigated.\n\n**Related:** [UCL](#ucl-upper-control-limit), [LCL](#lcl-lower-control-limit), [Mean](#mean)\n\n### Special Cause\n\nVariation from identifiable, assignable sources — as opposed to common cause variation which is inherent in the process. Special causes create non-random patterns detectable by control charts and Nelson Rules. Examples: tool wear, operator error, raw material batch change. Special causes should be investigated and eliminated.\n\n**Related:** [Nelson Rules](#nelson-rules), [UCL](#ucl-upper-control-limit), [LCL](#lcl-lower-control-limit)\n\n### Characteristic Type\n\nQuality characteristic classification that affects how specification limits are interpreted.\n\n**Nominal-is-best:** Target value exists, deviation in either direction is loss (e.g., fill weight). Both USL and LSL are defined.\n\n**Smaller-is-better:** Zero is ideal, any positive value is undesirable (e.g., defects, cycle time). Only USL is defined.\n\n**Larger-is-better:** Higher is always better (e.g., yield, strength). Only LSL is defined.\n\nVariScout automatically infers the characteristic type from which specs are defined, but it can be overridden manually.\n\n**Related:** [USL](#usl-upper-specification-limit), [LSL](#lsl-lower-specification-limit), [Target](#target)\n\n### Probability Plot\n\nNormal probability plot showing data points against expected normal percentiles. Points on the line indicate normal distribution.\n\nA graphical method for assessing whether data follows a normal distribution. Uses Benard's Median Rank formula to calculate expected percentiles. If data is normal, points fall close to the fitted line.\n\n**Related:** [Mean](#mean), [Std Dev](#std-dev), [Cp](#cp), [Cpk](#cpk)\n\n---\n\n_Generated from `packages/core/src/glossary/terms.ts`_", + "src/content/docs/glossary.md", + "ef414c97f91d7355", + { "html": 484, "metadata": 485 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"glossary\">Glossary\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#glossary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Glossary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Statistical and quality terms used across VariScout.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"control-limits\">Control Limits\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#control-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Control Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ucl-upper-control-limit\">UCL (Upper Control Limit)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ucl-upper-control-limit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “UCL (Upper Control Limit)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Upper Control Limit. Statistical boundary showing process behavior, set at mean + 3 standard deviations.\u003C/p>\n\u003Cp>UCL represents the upper natural boundary of process variation. Points above UCL indicate special cause variation requiring investigation. Different from USL which is a customer requirement.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#lcl-lower-control-limit\">LCL\u003C/a>, \u003Ca href=\"#mean\">Mean\u003C/a>, \u003Ca href=\"#std-dev\">Std Dev\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"lcl-lower-control-limit\">LCL (Lower Control Limit)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#lcl-lower-control-limit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “LCL (Lower Control Limit)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Lower Control Limit. Statistical boundary showing process behavior, set at mean - 3 standard deviations.\u003C/p>\n\u003Cp>LCL represents the lower natural boundary of process variation. Points below LCL indicate special cause variation requiring investigation. Different from LSL which is a customer requirement.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#ucl-upper-control-limit\">UCL\u003C/a>, \u003Ca href=\"#mean\">Mean\u003C/a>, \u003Ca href=\"#std-dev\">Std Dev\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usl-upper-specification-limit\">USL (Upper Specification Limit)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usl-upper-specification-limit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “USL (Upper Specification Limit)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Upper Specification Limit. Customer-defined maximum acceptable value for the product.\u003C/p>\n\u003Cp>USL is the customer’s voice - the maximum value they will accept. Products above USL are out of spec and rejected. Set by customer requirements, not process data.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#lsl-lower-specification-limit\">LSL\u003C/a>, \u003Ca href=\"#target\">Target\u003C/a>, \u003Ca href=\"#cp\">Cp\u003C/a>, \u003Ca href=\"#cpk\">Cpk\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"lsl-lower-specification-limit\">LSL (Lower Specification Limit)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#lsl-lower-specification-limit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “LSL (Lower Specification Limit)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Lower Specification Limit. Customer-defined minimum acceptable value for the product.\u003C/p>\n\u003Cp>LSL is the customer’s voice - the minimum value they will accept. Products below LSL are out of spec and rejected. Set by customer requirements, not process data.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#usl-upper-specification-limit\">USL\u003C/a>, \u003Ca href=\"#target\">Target\u003C/a>, \u003Ca href=\"#cp\">Cp\u003C/a>, \u003Ca href=\"#cpk\">Cpk\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"target\">Target\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#target\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The ideal or nominal value for the measurement, typically the midpoint between LSL and USL.\u003C/p>\n\u003Cp>Target represents the ideal value customers want. Process centering is assessed by comparing the mean to the target.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#usl-upper-specification-limit\">USL\u003C/a>, \u003Ca href=\"#lsl-lower-specification-limit\">LSL\u003C/a>, \u003Ca href=\"#cpk\">Cpk\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"capability-metrics\">Capability Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#capability-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability Metrics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cp\">Cp\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cp\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cp”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Process Capability. Measures how well your process fits within spec limits.\u003C/p>\n\u003Cp>Cp compares the width of specification limits to 6σ_within of the process. Cp = (USL - LSL) / (6σ_within), where σ_within is estimated from the moving range (MR̄/d2). Higher values mean the process has room to spare within specs. Does not account for centering.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#cpk\">Cpk\u003C/a>, \u003Ca href=\"#usl-upper-specification-limit\">USL\u003C/a>, \u003Ca href=\"#lsl-lower-specification-limit\">LSL\u003C/a>, \u003Ca href=\"#std-dev\">Std Dev\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cpk\">Cpk\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cpk\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cpk”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Process Capability Index. Like Cp, but accounts for how well centered the process is.\u003C/p>\n\u003Cp>Cpk = min(CPU, CPL), where CPU = (USL - Mean) / 3σ_within and CPL = (Mean - LSL) / 3σ_within. σ_within is estimated from the moving range (MR̄/d2). A Cpk much lower than Cp indicates the process mean is shifted toward one spec limit.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#cp\">Cp\u003C/a>, \u003Ca href=\"#usl-upper-specification-limit\">USL\u003C/a>, \u003Ca href=\"#lsl-lower-specification-limit\">LSL\u003C/a>, \u003Ca href=\"#mean\">Mean\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pass-rate\">Pass Rate\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pass-rate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pass Rate”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Percentage of measurements within specification limits (between LSL and USL).\u003C/p>\n\u003Cp>Pass Rate shows what proportion of products meet customer requirements. 100% means all products are in spec. Also known as yield or conformance rate.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#usl-upper-specification-limit\">USL\u003C/a>, \u003Ca href=\"#lsl-lower-specification-limit\">LSL\u003C/a>, \u003Ca href=\"#rejected\">Rejected\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"rejected\">Rejected\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#rejected\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Rejected”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Percentage of measurements outside specification limits (above USL or below LSL).\u003C/p>\n\u003Cp>Rejected rate is the inverse of pass rate. These are products that fail to meet customer requirements and must be scrapped, reworked, or conceded.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#pass-rate\">Pass Rate\u003C/a>, \u003Ca href=\"#usl-upper-specification-limit\">USL\u003C/a>, \u003Ca href=\"#lsl-lower-specification-limit\">LSL\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"basic-statistics\">Basic Statistics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#basic-statistics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Basic Statistics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mean\">Mean\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mean\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mean”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Average value. Sum of all measurements divided by the count.\u003C/p>\n\u003Cp>The arithmetic mean represents the center of the data distribution. Compare to target to assess centering. Also called X-bar in control charts.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#std-dev\">Std Dev\u003C/a>, \u003Ca href=\"#ucl-upper-control-limit\">UCL\u003C/a>, \u003Ca href=\"#lcl-lower-control-limit\">LCL\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"std-dev\">Std Dev\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#std-dev\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Std Dev”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standard Deviation. Measures the spread or variability of measurements around the mean.\u003C/p>\n\u003Cp>Standard deviation (σ) quantifies how much values vary from the average. Smaller values indicate more consistent processes. Used to calculate control limits and capability indices.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#mean\">Mean\u003C/a>, \u003Ca href=\"#cp\">Cp\u003C/a>, \u003Ca href=\"#ucl-upper-control-limit\">UCL\u003C/a>, \u003Ca href=\"#lcl-lower-control-limit\">LCL\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"anova-statistics\">ANOVA Statistics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#anova-statistics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ANOVA Statistics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"f-statistic\">F-Statistic\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#f-statistic\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “F-Statistic”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Measures the ratio of between-group variance to within-group variance in ANOVA.\u003C/p>\n\u003Cp>F-statistic compares variation between groups to variation within groups. Higher F values indicate larger differences between group means relative to variation within groups.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#p-value\">p-value\u003C/a>, \u003Ca href=\"#2-eta-squared\">η² (Eta-squared)\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"p-value\">p-value\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#p-value\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “p-value”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Probability the observed difference happened by chance. p < 0.05 = statistically significant.\u003C/p>\n\u003Cp>The p-value tests the null hypothesis that all group means are equal. Small p-values (typically < 0.05) provide evidence that at least one group mean differs from the others.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#f-statistic\">F-Statistic\u003C/a>, \u003Ca href=\"#2-eta-squared\">η² (Eta-squared)\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"η-eta-squared\">η² (Eta-squared)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#η-eta-squared\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “η² (Eta-squared)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Effect size showing how much variation is explained by the factor. Small < 0.06, medium 0.06-0.14, large > 0.14.\u003C/p>\n\u003Cp>Eta-squared (η²) represents the proportion of total variance explained by the grouping factor. Unlike p-value, it indicates practical significance - how much the factor matters. In VariScout, η² is shown in the ANOVA results panel and used internally to suggest the next drill-down factor.\u003C/p>\n\u003Cp>\u003Cstrong>Note:\u003C/strong> The user-facing variation metric in filter chips, breadcrumbs, and the progress bar is \u003Cstrong>Total SS Contribution\u003C/strong> (see below), not η².\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#f-statistic\">F-Statistic\u003C/a>, \u003Ca href=\"#p-value\">p-value\u003C/a>, \u003Ca href=\"#total-ss-contribution\">Total SS Contribution\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"total-ss-contribution\">Total SS Contribution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#total-ss-contribution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Total SS Contribution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The percentage of total variation (Sum of Squares) that a specific category or filter selection accounts for. Unlike η² (which only captures between-group variation), Total SS Contribution captures both mean shift and within-group spread.\u003C/p>\n\u003Cp>This is the primary user-facing metric in VariScout’s drill-down workflow. Filter chips show each selection’s Total SS Contribution, and the progress bar shows the cumulative scope — the product of contributions across drill levels.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#2-eta-squared\">η² (Eta-squared)\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"regression-statistics\">Regression Statistics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#regression-statistics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Regression Statistics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"r\">R²\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#r\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “R²”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Coefficient of determination. Shows how much of Y’s variation is explained by X. Closer to 1 = stronger.\u003C/p>\n\u003Cp>R-squared ranges from 0 to 1. An R² of 0.80 means 80% of the variation in Y can be explained by the relationship with X. The remaining 20% is due to other factors or random variation.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#slope\">Slope\u003C/a>, \u003Ca href=\"#p-value\">p-value\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"adjusted-r\">Adjusted R²\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#adjusted-r\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Adjusted R²”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A modified R² that adjusts for the number of predictors. Only increases if a new predictor improves the model more than expected by chance.\u003C/p>\n\u003Cp>Unlike regular R², adjusted R² penalizes adding predictors that do not meaningfully improve the model. Use it to compare models with different numbers of predictors.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#r2\">R²\u003C/a>, \u003Ca href=\"#vif\">VIF\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"slope\">Slope\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#slope\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Slope”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How much Y changes for each unit increase in X. Positive = Y increases with X.\u003C/p>\n\u003Cp>The slope quantifies the rate of change in the relationship. A slope of 2.5 means Y increases by 2.5 units for every 1 unit increase in X.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#r2\">R²\u003C/a>, \u003Ca href=\"#intercept\">Intercept\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"intercept\">Intercept\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#intercept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Intercept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The predicted value of Y when X equals zero.\u003C/p>\n\u003Cp>The y-intercept is where the regression line crosses the Y-axis. May not have practical meaning if X=0 is outside the range of observed data.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#slope\">Slope\u003C/a>, \u003Ca href=\"#r2\">R²\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"vif\">VIF\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#vif\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VIF”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Variance Inflation Factor. Measures how much a coefficient variance is inflated due to correlation with other predictors.\u003C/p>\n\u003Cp>VIF = 1 means no correlation with other predictors. VIF 1-5 is acceptable. VIF 5-10 indicates moderate multicollinearity. VIF > 10 suggests serious multicollinearity requiring action.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#adjusted-r2\">Adjusted R²\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"methodology\">Methodology\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#methodology\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Methodology”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"staged-analysis\">Staged Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#staged-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Staged Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Analysis approach that calculates separate control limits for distinct process phases (e.g., before/after improvement).\u003C/p>\n\u003Cp>Staged analysis reveals improvements that combined data hides. Each stage gets its own mean and control limits calculated independently, letting you see shifts in both center and variation.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#ucl-upper-control-limit\">UCL\u003C/a>, \u003Ca href=\"#lcl-lower-control-limit\">LCL\u003C/a>, \u003Ca href=\"#mean\">Mean\u003C/a>, \u003Ca href=\"#std-dev\">Std Dev\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"total-ss-contribution-1\">Total SS Contribution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#total-ss-contribution-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Total SS Contribution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A category’s share of total sum of squares. Captures both mean shift AND spread (within-group variation).\u003C/p>\n\u003Cp>Unlike between-group SS which only measures mean differences, Total SS contribution shows a category’s full impact on variation. A category with mean near overall mean but high spread now shows non-zero impact. Sum of all category contributions equals 100%.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#2-eta-squared\">η² (Eta-squared)\u003C/a>, \u003Ca href=\"#std-dev\">Std Dev\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"nelson-rules\">Nelson Rules\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#nelson-rules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Nelson Rules”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Eight statistical tests for detecting non-random patterns (special causes) on control charts. Rule 1: any point beyond 3σ. Rule 2: nine consecutive points on the same side of the mean. Rules 3-8 detect trends, oscillations, and stratification patterns. Violations indicate special cause variation that should be investigated.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#ucl-upper-control-limit\">UCL\u003C/a>, \u003Ca href=\"#lcl-lower-control-limit\">LCL\u003C/a>, \u003Ca href=\"#mean\">Mean\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"special-cause\">Special Cause\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#special-cause\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Special Cause”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Variation from identifiable, assignable sources — as opposed to common cause variation which is inherent in the process. Special causes create non-random patterns detectable by control charts and Nelson Rules. Examples: tool wear, operator error, raw material batch change. Special causes should be investigated and eliminated.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#nelson-rules\">Nelson Rules\u003C/a>, \u003Ca href=\"#ucl-upper-control-limit\">UCL\u003C/a>, \u003Ca href=\"#lcl-lower-control-limit\">LCL\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"characteristic-type\">Characteristic Type\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#characteristic-type\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Characteristic Type”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Quality characteristic classification that affects how specification limits are interpreted.\u003C/p>\n\u003Cp>\u003Cstrong>Nominal-is-best:\u003C/strong> Target value exists, deviation in either direction is loss (e.g., fill weight). Both USL and LSL are defined.\u003C/p>\n\u003Cp>\u003Cstrong>Smaller-is-better:\u003C/strong> Zero is ideal, any positive value is undesirable (e.g., defects, cycle time). Only USL is defined.\u003C/p>\n\u003Cp>\u003Cstrong>Larger-is-better:\u003C/strong> Higher is always better (e.g., yield, strength). Only LSL is defined.\u003C/p>\n\u003Cp>VariScout automatically infers the characteristic type from which specs are defined, but it can be overridden manually.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#usl-upper-specification-limit\">USL\u003C/a>, \u003Ca href=\"#lsl-lower-specification-limit\">LSL\u003C/a>, \u003Ca href=\"#target\">Target\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"probability-plot\">Probability Plot\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#probability-plot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Probability Plot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Normal probability plot showing data points against expected normal percentiles. Points on the line indicate normal distribution.\u003C/p>\n\u003Cp>A graphical method for assessing whether data follows a normal distribution. Uses Benard’s Median Rank formula to calculate expected percentiles. If data is normal, points fall close to the fitted line.\u003C/p>\n\u003Cp>\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"#mean\">Mean\u003C/a>, \u003Ca href=\"#std-dev\">Std Dev\u003C/a>, \u003Ca href=\"#cp\">Cp\u003C/a>, \u003Ca href=\"#cpk\">Cpk\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cp>\u003Cem>Generated from \u003Ccode dir=\"auto\">packages/core/src/glossary/terms.ts\u003C/code>\u003C/em>\u003C/p>", + { + "headings": 486, + "localImagePaths": 582, + "remoteImagePaths": 583, + "frontmatter": 584, + "imagePaths": 585 + }, + [ + 487, 488, 491, 494, 497, 500, 503, 506, 509, 512, 515, 518, 521, 524, 527, 530, 533, 536, 538, + 541, 544, 547, 550, 553, 556, 559, 562, 565, 568, 570, 573, 576, 579 + ], + { "depth": 30, "slug": 473, "text": 476 }, + { "depth": 33, "slug": 489, "text": 490 }, + "control-limits", + "Control Limits", + { "depth": 79, "slug": 492, "text": 493 }, + "ucl-upper-control-limit", + "UCL (Upper Control Limit)", + { "depth": 79, "slug": 495, "text": 496 }, + "lcl-lower-control-limit", + "LCL (Lower Control Limit)", + { "depth": 79, "slug": 498, "text": 499 }, + "usl-upper-specification-limit", + "USL (Upper Specification Limit)", + { "depth": 79, "slug": 501, "text": 502 }, + "lsl-lower-specification-limit", + "LSL (Lower Specification Limit)", + { "depth": 79, "slug": 504, "text": 505 }, + "target", + "Target", + { "depth": 33, "slug": 507, "text": 508 }, + "capability-metrics", + "Capability Metrics", + { "depth": 79, "slug": 510, "text": 511 }, + "cp", + "Cp", + { "depth": 79, "slug": 513, "text": 514 }, + "cpk", + "Cpk", + { "depth": 79, "slug": 516, "text": 517 }, + "pass-rate", + "Pass Rate", + { "depth": 79, "slug": 519, "text": 520 }, + "rejected", + "Rejected", + { "depth": 33, "slug": 522, "text": 523 }, + "basic-statistics", + "Basic Statistics", + { "depth": 79, "slug": 525, "text": 526 }, + "mean", + "Mean", + { "depth": 79, "slug": 528, "text": 529 }, + "std-dev", + "Std Dev", + { "depth": 33, "slug": 531, "text": 532 }, + "anova-statistics", + "ANOVA Statistics", + { "depth": 79, "slug": 534, "text": 535 }, + "f-statistic", + "F-Statistic", + { "depth": 79, "slug": 537, "text": 537 }, + "p-value", + { "depth": 79, "slug": 539, "text": 540 }, + "η-eta-squared", + "η² (Eta-squared)", + { "depth": 79, "slug": 542, "text": 543 }, + "total-ss-contribution", + "Total SS Contribution", + { "depth": 33, "slug": 545, "text": 546 }, + "regression-statistics", + "Regression Statistics", + { "depth": 79, "slug": 548, "text": 549 }, + "r", + "R²", + { "depth": 79, "slug": 551, "text": 552 }, + "adjusted-r", + "Adjusted R²", + { "depth": 79, "slug": 554, "text": 555 }, + "slope", + "Slope", + { "depth": 79, "slug": 557, "text": 558 }, + "intercept", + "Intercept", + { "depth": 79, "slug": 560, "text": 561 }, + "vif", + "VIF", + { "depth": 33, "slug": 563, "text": 564 }, + "methodology", + "Methodology", + { "depth": 79, "slug": 566, "text": 567 }, + "staged-analysis", + "Staged Analysis", + { "depth": 79, "slug": 569, "text": 543 }, + "total-ss-contribution-1", + { "depth": 79, "slug": 571, "text": 572 }, + "nelson-rules", + "Nelson Rules", + { "depth": 79, "slug": 574, "text": 575 }, + "special-cause", + "Special Cause", + { "depth": 79, "slug": 577, "text": 578 }, + "characteristic-type", + "Characteristic Type", + { "depth": 79, "slug": 580, "text": 581 }, + "probability-plot", + "Probability Plot", + [], + [], + { "title": 476 }, + [], + "02-journeys/ux-research", + { "id": 586, "data": 588, "body": 593, "filePath": 594, "digest": 595, "rendered": 596 }, + { + "title": 589, + "editUrl": 16, + "head": 590, + "template": 18, + "sidebar": 591, + "pagefind": 16, + "draft": 20 + }, + "UX Research: VariScout Lite", + [], + { "hidden": 20, "attrs": 592 }, + {}, + "# UX Research: VariScout Lite\n\n## Design Thinking & JTBD Framework for Quality Professionals in Developing Countries\n\n---\n\n## Part 1: Simulated User Interview\n\n### Interview Context\n\n**Interviewer**: UX Researcher / Design Thinker\n**Interviewee**: Grace Mwangi, Quality Assurance Manager\n**Location**: Nairobi, Kenya (Remote Video Call)\n**Organization**: East Africa Fresh Exports Ltd. (Agri-food export company)\n**Date**: December 2024\n\n---\n\n### Interview Transcript\n\n**Researcher**: Grace, thank you for joining us. Can you tell me about your role and what a typical day looks like for you?\n\n**Grace**: I'm the QA Manager at East Africa Fresh. We export fresh produce - mangoes, avocados, passion fruit - mainly to Europe and the Middle East. My day starts early. I visit our collection centers where smallholder farmers bring their harvests. I check sample weights, inspect for defects, and make grading decisions. Then I'm back at the office analyzing data, preparing compliance reports for export certifications.\n\n**Researcher**: What tools do you currently use for quality analysis?\n\n**Grace**: Honestly? Excel. Lots and lots of Excel. I have templates I've built over years. I calculate averages, standard deviations, make charts for my reports. Sometimes I use pen and paper at the field sites because internet is not reliable there. Later I type everything into spreadsheets.\n\n**Researcher**: What frustrates you most about your current process?\n\n**Grace**: _sighs_ Where do I start?\n\nFirst, the **time**. I spend maybe 3-4 hours every week just formatting charts and doing repetitive calculations. My management wants to see trends, but creating comparison charts in Excel takes forever.\n\nSecond, **internet dependency**. We tried cloud tools before - a quality management platform from Europe. Beautiful software, but useless when the connection drops at our upcountry collection centers. And the subscription? $200 per month? Our entire QA budget is maybe $500.\n\nThird, **understanding variation**. I know there's something happening with our Farm C supplies - the rejection rate is higher. But proving it with data, showing the pattern clearly to management and to the farmers themselves... that's hard with static charts.\n\n**Researcher**: Tell me about a recent situation where you struggled with your current tools.\n\n**Grace**: Two weeks ago. We had a shipment rejected at Dubai port - 15% of mangoes were underweight. My manager wanted answers: Which farms? Which collection dates? What's the pattern?\n\nI had the data in Excel, but linking it all together... I spent an entire day making pivot tables, creating separate charts, trying to show the connection between farm source and weight distribution. When I presented, my charts were confusing even to me. I knew the answer was in the data, but I couldn't make it _visible_.\n\n**Researcher**: What would your ideal tool look like?\n\n**Grace**: Something simple that just works. I upload my data, and immediately I can see: here are your control limits, here's which group is causing problems, here's your capability score for the export report.\n\nIt needs to work **offline** - at least let me do the analysis without internet, save it, and maybe sync later.\n\nIt should be **visual** - when I click on a problem area, show me everything connected to it. Like if I click on \"Farm C\" in a chart, highlight all the data points from Farm C across all my charts.\n\nAnd **affordable**. We're not a big company. We can't pay enterprise software prices.\n\n**Researcher**: What about data privacy? Does that matter to you?\n\n**Grace**: Very much! Our farm yield data, our supplier quality scores... that's sensitive. Some of our European buyers have asked about our data handling. I'm not comfortable uploading everything to some American cloud server. If the tool keeps data on my computer, that's actually better.\n\n**Researcher**: Have you heard of capability metrics like Cp and Cpk?\n\n**Grace**: Yes, I learned about them in my food science degree. Cpk especially - it tells you if your process is centered. But calculating it manually? Too tedious. And explaining it to farmers? Forget it. But if I could show them a simple visual - \"your Cpk is 0.8, it should be above 1.33, see this chart shows why\" - that would help.\n\n**Researcher**: What would success look like for you with a new tool?\n\n**Grace**: I want to finish my weekly analysis in **one hour**, not four. I want to show my manager a single dashboard that answers: \"Are we meeting specs? Which suppliers need support? Is it getting better or worse?\" And I want farmers to see their own performance visualized - so they understand why we grade the way we grade.\n\n**Researcher**: Last question - how do you feel about software that uses AI to make recommendations?\n\n**Grace**: _hesitates_ I'm cautious. I've seen AI tools that give suggestions but don't show their work. In quality, I need to defend my decisions to auditors, to certification bodies. I need to see the math, see the logic. A tool that helps me analyze faster - yes. A tool that makes decisions for me - I'm not sure I can trust that in my reports.\n\n---\n\n## Part 2: User Personas\n\n### Primary Persona: \"The Export Quality Champion\"\n\n| Attribute | Details |\n| ---------------- | -------------------------------------------------------------------- |\n| **Name** | Grace Mwangi |\n| **Role** | Quality Assurance Manager |\n| **Location** | Nairobi, Kenya |\n| **Organization** | Mid-size agri-food export company (50-200 employees) |\n| **Education** | BSc Food Science, trained in basic statistics |\n| **Tech Comfort** | Intermediate - proficient with Excel, smartphones, basic cloud tools |\n| **Age** | 32-45 |\n\n#### Goals\n\n- Ensure export shipments meet buyer specifications\n- Identify and address quality issues with specific suppliers\n- Produce clear reports for management and certification bodies\n- Support smallholder farmers in improving their quality\n\n#### Frustrations\n\n- Too much time spent on manual Excel work\n- Unreliable internet at field locations\n- Difficulty visualizing complex patterns in data\n- Expensive software with features she doesn't need\n- Showing farmers their performance in understandable ways\n\n#### Context\n\n- Works across multiple locations (office + field sites)\n- Budget-constrained organization\n- Data privacy important for competitive and compliance reasons\n- Needs audit-ready outputs (must show methodology, not black-box)\n\n#### Quote\n\n> \"I know the answers are in my data. I just need a faster way to make them visible.\"\n\n---\n\n### Secondary Persona: \"The Factory Floor Analyst\"\n\n| Attribute | Details |\n| ---------------- | -------------------------------------------- |\n| **Name** | Raj Sharma |\n| **Role** | Quality Engineer |\n| **Location** | Coimbatore, India |\n| **Organization** | Textile manufacturing unit |\n| **Education** | B.Tech Textile Engineering |\n| **Tech Comfort** | High - comfortable with statistical concepts |\n\n#### Context\n\n- Works on shop floor with tablets\n- Needs real-time variation monitoring\n- Reports to plant manager on shift performance\n- Compares performance across looms and operators\n\n---\n\n### Tertiary Persona: \"The Cooperative Trainer\"\n\n| Attribute | Details |\n| ---------------- | --------------------------------- |\n| **Name** | Carlos Mendez |\n| **Role** | Quality Training Coordinator |\n| **Location** | Guatemala |\n| **Organization** | Coffee cooperative network |\n| **Education** | Agricultural extension background |\n\n#### Context\n\n- Trains farmer groups on quality improvement\n- Needs educational tool with predictable behavior\n- Uses projected dashboard in group training sessions\n- Works in areas with limited connectivity\n\n---\n\n## Part 3: Jobs-to-be-Done (JTBD) Framework\n\n### Core Functional Jobs\n\n#### Job 1: Assess Batch Conformance\n\n> **When I** receive a batch of products from suppliers,\n> **I want to** quickly determine what percentage meets specifications,\n> **So I can** make accept/reject decisions and provide feedback to suppliers.\n\n**Success Metrics:**\n\n- Time to analyze batch: \u003C 5 minutes\n- Clear pass/fail visualization\n- Breakdown by grade tier visible\n\n**Current Alternatives:**\n\n- Manual Excel calculations\n- Visual inspection only\n- Sampling-based judgment\n\n---\n\n#### Job 2: Identify Variation Sources\n\n> **When I** observe quality problems in my process,\n> **I want to** see which factors (suppliers, machines, shifts) correlate with poor performance,\n> **So I can** take targeted corrective action.\n\n**Success Metrics:**\n\n- Ability to filter by any factor\n- Cross-chart highlighting of related data\n- Clear factor-to-outcome visualization\n\n**Current Alternatives:**\n\n- Multiple Excel pivot tables\n- Manual chart creation\n- Intuition-based investigation\n\n---\n\n#### Job 3: Monitor Process Capability\n\n> **When I** need to demonstrate our quality capability to buyers or certifiers,\n> **I want to** show statistical metrics (Cpk, pass rate, control limits) in a professional format,\n> **So I can** prove we meet standards and build trust.\n\n**Success Metrics:**\n\n- Industry-standard metrics (Cp, Cpk) calculated automatically\n- Exportable charts for reports\n- Spec limits clearly visualized\n\n**Current Alternatives:**\n\n- Manual Cpk calculation in Excel\n- Third-party SPC software (expensive)\n- Verbal assurances without data\n\n---\n\n#### Job 4: Communicate Quality Issues\n\n> **When I** need to explain quality problems to farmers, operators, or management,\n> **I want to** show clear, visual comparisons of performance across groups,\n> **So I can** drive understanding and motivate improvement.\n\n**Success Metrics:**\n\n- Intuitive visualizations (boxplots, Pareto)\n- Exportable as images for presentations\n- Simple enough for non-statisticians to understand\n\n**Current Alternatives:**\n\n- PowerPoint with static charts\n- Verbal explanations\n- Written reports\n\n---\n\n#### Job 5: Work Without Internet\n\n> **When I** am at field sites or factory floors with unreliable connectivity,\n> **I want to** perform full analysis locally on my device,\n> **So I can** do my work regardless of network conditions.\n\n**Success Metrics:**\n\n- 100% functionality offline\n- Data persisted locally\n- Analysis resumable after reconnection\n\n**Current Alternatives:**\n\n- Paper-based field notes\n- Delayed analysis at office\n- Mobile hotspot (unreliable/expensive)\n\n---\n\n#### Job 6: Protect Sensitive Data\n\n> **When I** analyze supplier quality or production data,\n> **I want to** keep that data on my own device (not sent to cloud servers),\n> **So I can** maintain competitive confidentiality and comply with data requirements.\n\n**Success Metrics:**\n\n- Zero data transmission to external servers\n- Local storage only\n- Clear privacy assurance\n\n**Current Alternatives:**\n\n- Air-gapped Excel files\n- Avoid digital tools entirely\n- Trust cloud providers (reluctantly)\n\n---\n\n### Emotional Jobs\n\n#### Job 7: Feel Confident in Analysis\n\n> **When I** present quality data to stakeholders,\n> **I want to** understand exactly how calculations were done,\n> **So I can** confidently answer questions and defend my conclusions.\n\n**Anxieties:**\n\n- \"What if the AI made an error I can't explain?\"\n- \"Can I trust this metric for an audit?\"\n- \"What if someone asks how I calculated this?\"\n\n---\n\n#### Job 8: Feel Efficient and Professional\n\n> **When I** spend less time on tedious data manipulation,\n> **I want to** feel like a strategic professional, not a spreadsheet operator,\n> **So I can** focus on insights and actions rather than mechanics.\n\n**Desired Outcome:**\n\n- Reduce analysis time by 75%+\n- Professional-looking outputs\n- Modern tool that reflects professional standards\n\n---\n\n### Social Jobs\n\n#### Job 9: Demonstrate Value to Organization\n\n> **When I** show management clear quality insights,\n> **I want to** be seen as a data-driven professional who adds measurable value,\n> **So I can** strengthen my role and advance my career.\n\n---\n\n#### Job 10: Empower Suppliers/Farmers\n\n> **When I** share performance data with suppliers,\n> **I want to** help them understand their quality standing without judgment,\n> **So I can** build collaborative improvement rather than adversarial relationships.\n\n---\n\n## Part 4: Use Cases\n\n### Use Case 1: Daily Incoming Inspection\n\n**Actor**: Quality Champion (Grace)\n**Trigger**: New batch arrives at collection center\n**Precondition**: Tablet with VariScout Lite installed (PWA)\n\n**Flow**:\n\n1. Open VariScout Lite (works offline)\n2. Enter measurements manually or upload CSV from digital scale\n3. System auto-detects weight as outcome, farm as factor\n4. View I-chart showing individual measurements against spec limits\n5. View boxplot comparing farms in this batch\n6. View stats panel: 94% pass rate, Cpk = 1.1\n7. Identify Farm C as underperforming (red highlighting)\n8. Save analysis with batch ID\n9. Export PNG for batch record\n\n**Outcome**: Batch accepted with documented analysis; Farm C flagged for follow-up\n\n---\n\n### Use Case 2: Weekly Performance Review\n\n**Actor**: Quality Champion (Grace)\n**Trigger**: End of week, management meeting tomorrow\n**Precondition**: Week's data collected in CSV\n\n**Flow**:\n\n1. Upload week's data (500 rows)\n2. Configure: Weight as outcome; Farm, Variety as factors\n3. Set spec limits: LSL=300g, USL=350g\n4. View I-chart trending over the week\n5. Click Pareto bar for \"Farm C\" → filters all charts to Farm C data\n6. Stats update: Farm C Cpk = 0.7 vs overall 1.1\n7. See boxplot confirms Farm C lower and more variable\n8. Export dashboard as PNG for presentation\n9. Save analysis as \"Week 48 Review\"\n\n**Outcome**: Clear visualization showing Farm C needs intervention; data-backed recommendation to management\n\n---\n\n### Use Case 3: Export Certification Report\n\n**Actor**: Quality Champion (Grace)\n**Trigger**: Buyer requests capability evidence for certification\n**Precondition**: 3 months of data available\n\n**Flow**:\n\n1. Load historical data (2000 rows)\n2. Set outcome and factors\n3. Configure buyer's specs (USL/LSL/Target)\n4. View Cpk = 1.45 (above 1.33 threshold - green)\n5. View pass rate = 98.2%\n6. Export dashboard as PNG\n7. Download .vrs file as data backup\n\n**Outcome**: Professional capability evidence for certification; data archived for audit trail\n\n---\n\n### Use Case 4: Farmer Training Session\n\n**Actor**: Training Coordinator (Carlos)\n**Trigger**: Monthly cooperative quality meeting\n**Precondition**: Month's defect data collected\n\n**Flow**:\n\n1. Load cooperative's coffee defect data\n2. Configure multi-tier grades: Specialty (≤5), Premium (6-8), Exchange (9-23), Off-Grade (>23)\n3. Project dashboard to group\n4. Show I-chart with colored bands for each grade\n5. Click each cooperative in Pareto → show their grade distribution\n6. Farmers see: \"Coop North = 84% Specialty; Coop South = 52% Specialty\"\n7. Discuss visible patterns (processing method correlation)\n8. Save analysis for follow-up\n\n**Outcome**: Farmers understand grading visually; discussion grounded in data not opinion\n\n---\n\n### Use Case 5: Root Cause Investigation\n\n**Actor**: Quality Engineer (Raj)\n**Trigger**: Sudden increase in fabric defects\n**Precondition**: Production data from last 2 weeks\n\n**Flow**:\n\n1. Upload production data\n2. Set tensile strength as outcome; Loom ID, Operator, Shift as factors\n3. View I-chart: see jump in variation starting 5 days ago\n4. Click that time period → filters to those dates\n5. View Pareto: Loom 7 accounts for 60% of failures\n6. View boxplot: Loom 7 dramatically lower than others\n7. Cross-reference: Loom 7 had maintenance 6 days ago\n8. Save analysis as \"Loom 7 Investigation\"\n\n**Outcome**: Root cause identified (Loom 7 post-maintenance issue); maintenance team notified\n\n---\n\n### Use Case 6: Offline Field Analysis\n\n**Actor**: Quality Champion (Grace)\n**Trigger**: At remote collection center, no internet\n**Precondition**: VariScout Lite installed as PWA\n\n**Flow**:\n\n1. Open app (loads from cache, no network needed)\n2. Enter measurements via manual entry grid\n3. Paste data from clipboard (copied from scale readout)\n4. Full analysis available offline\n5. Save analysis to browser storage\n6. Later at office: open saved project, export as needed\n\n**Outcome**: Complete analysis capability regardless of connectivity\n\n---\n\n## Part 5: Feature Priority Matrix\n\nBased on JTBD and use cases, prioritized features:\n\n### Must Have (Core JTBD)\n\n| Feature | Job Served |\n| ------------------------------------ | ------------ |\n| CSV/Excel import with auto-detection | All jobs |\n| I-Chart with control limits | Jobs 1, 2, 3 |\n| Boxplot factor comparison | Jobs 2, 4 |\n| Pareto frequency analysis | Jobs 2, 4 |\n| Linked cross-filtering | Job 2 |\n| Spec limits (USL/LSL) | Jobs 1, 3 |\n| Cpk/Cp calculation | Job 3 |\n| Offline PWA operation | Job 5 |\n| Local-only data storage | Job 6 |\n| PNG export | Jobs 3, 4 |\n\n### Should Have (Enhanced Value)\n\n| Feature | Job Served |\n| ------------------------- | ------------------------------------------ |\n| Multi-tier grading system | Jobs 1, 4 (coffee/agriculture) |\n| Project save/load | Job 7 (confidence through reproducibility) |\n| .vrs file export/import | Job 6 (backup, transfer) |\n| Manual data entry | Job 5 (field use) |\n| Sample datasets | Job 7 (learning, demo) |\n\n### Nice to Have (Future)\n\n| Feature | Job Served |\n| --------------------------- | ------------------------------------- |\n| Multi-language support | Accessibility in developing countries |\n| Trend analysis over time | Job 2 (pattern detection) |\n| Comparative period analysis | Job 2 (before/after) |\n| Report templates | Job 3 (certification reports) |\n\n---\n\n## Part 6: Key Insights Summary\n\n### What We Learned\n\n1. **Offline-first is non-negotiable** - Field work in developing countries means unreliable internet. The tool must work fully offline.\n\n2. **Privacy = competitive advantage** - Unlike enterprise tools pushing cloud storage, local-only data is a feature, not a limitation.\n\n3. **Time savings is the primary value** - Reducing 4-hour Excel work to 1 hour is transformative for busy QA professionals.\n\n4. **Linked visualization is the \"magic\"** - The ability to click one chart and filter all others is the key differentiator from Excel.\n\n5. **Transparency over AI** - Users need to defend their analysis to auditors. \"The algorithm decided\" is not acceptable. Transparent statistics are preferred.\n\n6. **Multi-tier grading matters** - For agriculture exports (coffee, produce), grade-based classification is as important as simple pass/fail.\n\n7. **Visual communication to non-experts** - Charts must be clear enough to show farmers/operators without statistical training.\n\n8. **Cost sensitivity is extreme** - $200/month is unacceptable for SMEs in developing countries. Free or very low cost is essential.\n\n---\n\n## Part 7: Design Principles for VariScout Lite\n\nBased on this research, the following design principles should guide development:\n\n1. **Offline by default** - Every feature must work without network connectivity\n2. **Data stays local** - Zero external data transmission\n3. **Transparent math** - Show formulas, explain metrics, no black boxes\n4. **Linked exploration** - Charts talk to each other through filtering\n5. **Fast to first insight** - Under 30 seconds from upload to visualization\n6. **Export-ready outputs** - Professional charts suitable for reports\n7. **Progressive complexity** - Simple defaults, optional advanced settings\n8. **Domain-aware** - Sample data and terminology that matches user contexts\n\n---\n\n_Document prepared as UX research artifact for VariScout Lite product development_", + "src/content/docs/02-journeys/ux-research.md", + "33918725f0103ac7", + { "html": 597, "metadata": 598 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"ux-research-variscout-lite\">UX Research: VariScout Lite\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#ux-research-variscout-lite\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “UX Research: VariScout Lite”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"design-thinking--jtbd-framework-for-quality-professionals-in-developing-countries\">Design Thinking & JTBD Framework for Quality Professionals in Developing Countries\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#design-thinking--jtbd-framework-for-quality-professionals-in-developing-countries\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Thinking & JTBD Framework for Quality Professionals in Developing Countries”\u003C/span>\u003C/a>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-1-simulated-user-interview\">Part 1: Simulated User Interview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-1-simulated-user-interview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 1: Simulated User Interview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interview-context\">Interview Context\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interview-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interview Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Interviewer\u003C/strong>: UX Researcher / Design Thinker\n\u003Cstrong>Interviewee\u003C/strong>: Grace Mwangi, Quality Assurance Manager\n\u003Cstrong>Location\u003C/strong>: Nairobi, Kenya (Remote Video Call)\n\u003Cstrong>Organization\u003C/strong>: East Africa Fresh Exports Ltd. (Agri-food export company)\n\u003Cstrong>Date\u003C/strong>: December 2024\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interview-transcript\">Interview Transcript\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interview-transcript\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interview Transcript”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Researcher\u003C/strong>: Grace, thank you for joining us. Can you tell me about your role and what a typical day looks like for you?\u003C/p>\n\u003Cp>\u003Cstrong>Grace\u003C/strong>: I’m the QA Manager at East Africa Fresh. We export fresh produce - mangoes, avocados, passion fruit - mainly to Europe and the Middle East. My day starts early. I visit our collection centers where smallholder farmers bring their harvests. I check sample weights, inspect for defects, and make grading decisions. Then I’m back at the office analyzing data, preparing compliance reports for export certifications.\u003C/p>\n\u003Cp>\u003Cstrong>Researcher\u003C/strong>: What tools do you currently use for quality analysis?\u003C/p>\n\u003Cp>\u003Cstrong>Grace\u003C/strong>: Honestly? Excel. Lots and lots of Excel. I have templates I’ve built over years. I calculate averages, standard deviations, make charts for my reports. Sometimes I use pen and paper at the field sites because internet is not reliable there. Later I type everything into spreadsheets.\u003C/p>\n\u003Cp>\u003Cstrong>Researcher\u003C/strong>: What frustrates you most about your current process?\u003C/p>\n\u003Cp>\u003Cstrong>Grace\u003C/strong>: \u003Cem>sighs\u003C/em> Where do I start?\u003C/p>\n\u003Cp>First, the \u003Cstrong>time\u003C/strong>. I spend maybe 3-4 hours every week just formatting charts and doing repetitive calculations. My management wants to see trends, but creating comparison charts in Excel takes forever.\u003C/p>\n\u003Cp>Second, \u003Cstrong>internet dependency\u003C/strong>. We tried cloud tools before - a quality management platform from Europe. Beautiful software, but useless when the connection drops at our upcountry collection centers. And the subscription? $200 per month? Our entire QA budget is maybe $500.\u003C/p>\n\u003Cp>Third, \u003Cstrong>understanding variation\u003C/strong>. I know there’s something happening with our Farm C supplies - the rejection rate is higher. But proving it with data, showing the pattern clearly to management and to the farmers themselves… that’s hard with static charts.\u003C/p>\n\u003Cp>\u003Cstrong>Researcher\u003C/strong>: Tell me about a recent situation where you struggled with your current tools.\u003C/p>\n\u003Cp>\u003Cstrong>Grace\u003C/strong>: Two weeks ago. We had a shipment rejected at Dubai port - 15% of mangoes were underweight. My manager wanted answers: Which farms? Which collection dates? What’s the pattern?\u003C/p>\n\u003Cp>I had the data in Excel, but linking it all together… I spent an entire day making pivot tables, creating separate charts, trying to show the connection between farm source and weight distribution. When I presented, my charts were confusing even to me. I knew the answer was in the data, but I couldn’t make it \u003Cem>visible\u003C/em>.\u003C/p>\n\u003Cp>\u003Cstrong>Researcher\u003C/strong>: What would your ideal tool look like?\u003C/p>\n\u003Cp>\u003Cstrong>Grace\u003C/strong>: Something simple that just works. I upload my data, and immediately I can see: here are your control limits, here’s which group is causing problems, here’s your capability score for the export report.\u003C/p>\n\u003Cp>It needs to work \u003Cstrong>offline\u003C/strong> - at least let me do the analysis without internet, save it, and maybe sync later.\u003C/p>\n\u003Cp>It should be \u003Cstrong>visual\u003C/strong> - when I click on a problem area, show me everything connected to it. Like if I click on “Farm C” in a chart, highlight all the data points from Farm C across all my charts.\u003C/p>\n\u003Cp>And \u003Cstrong>affordable\u003C/strong>. We’re not a big company. We can’t pay enterprise software prices.\u003C/p>\n\u003Cp>\u003Cstrong>Researcher\u003C/strong>: What about data privacy? Does that matter to you?\u003C/p>\n\u003Cp>\u003Cstrong>Grace\u003C/strong>: Very much! Our farm yield data, our supplier quality scores… that’s sensitive. Some of our European buyers have asked about our data handling. I’m not comfortable uploading everything to some American cloud server. If the tool keeps data on my computer, that’s actually better.\u003C/p>\n\u003Cp>\u003Cstrong>Researcher\u003C/strong>: Have you heard of capability metrics like Cp and Cpk?\u003C/p>\n\u003Cp>\u003Cstrong>Grace\u003C/strong>: Yes, I learned about them in my food science degree. Cpk especially - it tells you if your process is centered. But calculating it manually? Too tedious. And explaining it to farmers? Forget it. But if I could show them a simple visual - “your Cpk is 0.8, it should be above 1.33, see this chart shows why” - that would help.\u003C/p>\n\u003Cp>\u003Cstrong>Researcher\u003C/strong>: What would success look like for you with a new tool?\u003C/p>\n\u003Cp>\u003Cstrong>Grace\u003C/strong>: I want to finish my weekly analysis in \u003Cstrong>one hour\u003C/strong>, not four. I want to show my manager a single dashboard that answers: “Are we meeting specs? Which suppliers need support? Is it getting better or worse?” And I want farmers to see their own performance visualized - so they understand why we grade the way we grade.\u003C/p>\n\u003Cp>\u003Cstrong>Researcher\u003C/strong>: Last question - how do you feel about software that uses AI to make recommendations?\u003C/p>\n\u003Cp>\u003Cstrong>Grace\u003C/strong>: \u003Cem>hesitates\u003C/em> I’m cautious. I’ve seen AI tools that give suggestions but don’t show their work. In quality, I need to defend my decisions to auditors, to certification bodies. I need to see the math, see the logic. A tool that helps me analyze faster - yes. A tool that makes decisions for me - I’m not sure I can trust that in my reports.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-2-user-personas\">Part 2: User Personas\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-2-user-personas\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 2: User Personas”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"primary-persona-the-export-quality-champion\">Primary Persona: “The Export Quality Champion”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#primary-persona-the-export-quality-champion\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Primary Persona: “The Export Quality Champion””\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Details\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Name\u003C/strong>\u003C/td>\u003Ctd>Grace Mwangi\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Quality Assurance Manager\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Location\u003C/strong>\u003C/td>\u003Ctd>Nairobi, Kenya\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Organization\u003C/strong>\u003C/td>\u003Ctd>Mid-size agri-food export company (50-200 employees)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Education\u003C/strong>\u003C/td>\u003Ctd>BSc Food Science, trained in basic statistics\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Tech Comfort\u003C/strong>\u003C/td>\u003Ctd>Intermediate - proficient with Excel, smartphones, basic cloud tools\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Age\u003C/strong>\u003C/td>\u003Ctd>32-45\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"goals\">Goals\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#goals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Goals”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Ensure export shipments meet buyer specifications\u003C/li>\n\u003Cli>Identify and address quality issues with specific suppliers\u003C/li>\n\u003Cli>Produce clear reports for management and certification bodies\u003C/li>\n\u003Cli>Support smallholder farmers in improving their quality\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"frustrations\">Frustrations\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#frustrations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Frustrations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Too much time spent on manual Excel work\u003C/li>\n\u003Cli>Unreliable internet at field locations\u003C/li>\n\u003Cli>Difficulty visualizing complex patterns in data\u003C/li>\n\u003Cli>Expensive software with features she doesn’t need\u003C/li>\n\u003Cli>Showing farmers their performance in understandable ways\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"context\">Context\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Works across multiple locations (office + field sites)\u003C/li>\n\u003Cli>Budget-constrained organization\u003C/li>\n\u003Cli>Data privacy important for competitive and compliance reasons\u003C/li>\n\u003Cli>Needs audit-ready outputs (must show methodology, not black-box)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"quote\">Quote\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#quote\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quote”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“I know the answers are in my data. I just need a faster way to make them visible.”\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"secondary-persona-the-factory-floor-analyst\">Secondary Persona: “The Factory Floor Analyst”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#secondary-persona-the-factory-floor-analyst\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Secondary Persona: “The Factory Floor Analyst””\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Details\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Name\u003C/strong>\u003C/td>\u003Ctd>Raj Sharma\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Quality Engineer\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Location\u003C/strong>\u003C/td>\u003Ctd>Coimbatore, India\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Organization\u003C/strong>\u003C/td>\u003Ctd>Textile manufacturing unit\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Education\u003C/strong>\u003C/td>\u003Ctd>B.Tech Textile Engineering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Tech Comfort\u003C/strong>\u003C/td>\u003Ctd>High - comfortable with statistical concepts\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"context-1\">Context\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#context-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Works on shop floor with tablets\u003C/li>\n\u003Cli>Needs real-time variation monitoring\u003C/li>\n\u003Cli>Reports to plant manager on shift performance\u003C/li>\n\u003Cli>Compares performance across looms and operators\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tertiary-persona-the-cooperative-trainer\">Tertiary Persona: “The Cooperative Trainer”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tertiary-persona-the-cooperative-trainer\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tertiary Persona: “The Cooperative Trainer””\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Details\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Name\u003C/strong>\u003C/td>\u003Ctd>Carlos Mendez\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Quality Training Coordinator\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Location\u003C/strong>\u003C/td>\u003Ctd>Guatemala\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Organization\u003C/strong>\u003C/td>\u003Ctd>Coffee cooperative network\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Education\u003C/strong>\u003C/td>\u003Ctd>Agricultural extension background\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"context-2\">Context\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#context-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Trains farmer groups on quality improvement\u003C/li>\n\u003Cli>Needs educational tool with predictable behavior\u003C/li>\n\u003Cli>Uses projected dashboard in group training sessions\u003C/li>\n\u003Cli>Works in areas with limited connectivity\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-3-jobs-to-be-done-jtbd-framework\">Part 3: Jobs-to-be-Done (JTBD) Framework\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-3-jobs-to-be-done-jtbd-framework\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 3: Jobs-to-be-Done (JTBD) Framework”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-functional-jobs\">Core Functional Jobs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-functional-jobs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Functional Jobs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"job-1-assess-batch-conformance\">Job 1: Assess Batch Conformance\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#job-1-assess-batch-conformance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Job 1: Assess Batch Conformance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>When I\u003C/strong> receive a batch of products from suppliers,\n\u003Cstrong>I want to\u003C/strong> quickly determine what percentage meets specifications,\n\u003Cstrong>So I can\u003C/strong> make accept/reject decisions and provide feedback to suppliers.\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Metrics:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Time to analyze batch: < 5 minutes\u003C/li>\n\u003Cli>Clear pass/fail visualization\u003C/li>\n\u003Cli>Breakdown by grade tier visible\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Current Alternatives:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Manual Excel calculations\u003C/li>\n\u003Cli>Visual inspection only\u003C/li>\n\u003Cli>Sampling-based judgment\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"job-2-identify-variation-sources\">Job 2: Identify Variation Sources\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#job-2-identify-variation-sources\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Job 2: Identify Variation Sources”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>When I\u003C/strong> observe quality problems in my process,\n\u003Cstrong>I want to\u003C/strong> see which factors (suppliers, machines, shifts) correlate with poor performance,\n\u003Cstrong>So I can\u003C/strong> take targeted corrective action.\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Metrics:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Ability to filter by any factor\u003C/li>\n\u003Cli>Cross-chart highlighting of related data\u003C/li>\n\u003Cli>Clear factor-to-outcome visualization\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Current Alternatives:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Multiple Excel pivot tables\u003C/li>\n\u003Cli>Manual chart creation\u003C/li>\n\u003Cli>Intuition-based investigation\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"job-3-monitor-process-capability\">Job 3: Monitor Process Capability\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#job-3-monitor-process-capability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Job 3: Monitor Process Capability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>When I\u003C/strong> need to demonstrate our quality capability to buyers or certifiers,\n\u003Cstrong>I want to\u003C/strong> show statistical metrics (Cpk, pass rate, control limits) in a professional format,\n\u003Cstrong>So I can\u003C/strong> prove we meet standards and build trust.\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Metrics:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Industry-standard metrics (Cp, Cpk) calculated automatically\u003C/li>\n\u003Cli>Exportable charts for reports\u003C/li>\n\u003Cli>Spec limits clearly visualized\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Current Alternatives:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Manual Cpk calculation in Excel\u003C/li>\n\u003Cli>Third-party SPC software (expensive)\u003C/li>\n\u003Cli>Verbal assurances without data\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"job-4-communicate-quality-issues\">Job 4: Communicate Quality Issues\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#job-4-communicate-quality-issues\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Job 4: Communicate Quality Issues”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>When I\u003C/strong> need to explain quality problems to farmers, operators, or management,\n\u003Cstrong>I want to\u003C/strong> show clear, visual comparisons of performance across groups,\n\u003Cstrong>So I can\u003C/strong> drive understanding and motivate improvement.\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Metrics:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Intuitive visualizations (boxplots, Pareto)\u003C/li>\n\u003Cli>Exportable as images for presentations\u003C/li>\n\u003Cli>Simple enough for non-statisticians to understand\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Current Alternatives:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>PowerPoint with static charts\u003C/li>\n\u003Cli>Verbal explanations\u003C/li>\n\u003Cli>Written reports\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"job-5-work-without-internet\">Job 5: Work Without Internet\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#job-5-work-without-internet\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Job 5: Work Without Internet”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>When I\u003C/strong> am at field sites or factory floors with unreliable connectivity,\n\u003Cstrong>I want to\u003C/strong> perform full analysis locally on my device,\n\u003Cstrong>So I can\u003C/strong> do my work regardless of network conditions.\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Metrics:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>100% functionality offline\u003C/li>\n\u003Cli>Data persisted locally\u003C/li>\n\u003Cli>Analysis resumable after reconnection\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Current Alternatives:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Paper-based field notes\u003C/li>\n\u003Cli>Delayed analysis at office\u003C/li>\n\u003Cli>Mobile hotspot (unreliable/expensive)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"job-6-protect-sensitive-data\">Job 6: Protect Sensitive Data\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#job-6-protect-sensitive-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Job 6: Protect Sensitive Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>When I\u003C/strong> analyze supplier quality or production data,\n\u003Cstrong>I want to\u003C/strong> keep that data on my own device (not sent to cloud servers),\n\u003Cstrong>So I can\u003C/strong> maintain competitive confidentiality and comply with data requirements.\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Metrics:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Zero data transmission to external servers\u003C/li>\n\u003Cli>Local storage only\u003C/li>\n\u003Cli>Clear privacy assurance\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Current Alternatives:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Air-gapped Excel files\u003C/li>\n\u003Cli>Avoid digital tools entirely\u003C/li>\n\u003Cli>Trust cloud providers (reluctantly)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"emotional-jobs\">Emotional Jobs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#emotional-jobs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Emotional Jobs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"job-7-feel-confident-in-analysis\">Job 7: Feel Confident in Analysis\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#job-7-feel-confident-in-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Job 7: Feel Confident in Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>When I\u003C/strong> present quality data to stakeholders,\n\u003Cstrong>I want to\u003C/strong> understand exactly how calculations were done,\n\u003Cstrong>So I can\u003C/strong> confidently answer questions and defend my conclusions.\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Anxieties:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“What if the AI made an error I can’t explain?”\u003C/li>\n\u003Cli>“Can I trust this metric for an audit?”\u003C/li>\n\u003Cli>“What if someone asks how I calculated this?”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"job-8-feel-efficient-and-professional\">Job 8: Feel Efficient and Professional\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#job-8-feel-efficient-and-professional\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Job 8: Feel Efficient and Professional”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>When I\u003C/strong> spend less time on tedious data manipulation,\n\u003Cstrong>I want to\u003C/strong> feel like a strategic professional, not a spreadsheet operator,\n\u003Cstrong>So I can\u003C/strong> focus on insights and actions rather than mechanics.\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Desired Outcome:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Reduce analysis time by 75%+\u003C/li>\n\u003Cli>Professional-looking outputs\u003C/li>\n\u003Cli>Modern tool that reflects professional standards\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"social-jobs\">Social Jobs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#social-jobs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Social Jobs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"job-9-demonstrate-value-to-organization\">Job 9: Demonstrate Value to Organization\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#job-9-demonstrate-value-to-organization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Job 9: Demonstrate Value to Organization”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>When I\u003C/strong> show management clear quality insights,\n\u003Cstrong>I want to\u003C/strong> be seen as a data-driven professional who adds measurable value,\n\u003Cstrong>So I can\u003C/strong> strengthen my role and advance my career.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"job-10-empower-suppliersfarmers\">Job 10: Empower Suppliers/Farmers\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#job-10-empower-suppliersfarmers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Job 10: Empower Suppliers/Farmers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>When I\u003C/strong> share performance data with suppliers,\n\u003Cstrong>I want to\u003C/strong> help them understand their quality standing without judgment,\n\u003Cstrong>So I can\u003C/strong> build collaborative improvement rather than adversarial relationships.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-4-use-cases\">Part 4: Use Cases\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-4-use-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 4: Use Cases”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"use-case-1-daily-incoming-inspection\">Use Case 1: Daily Incoming Inspection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#use-case-1-daily-incoming-inspection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Case 1: Daily Incoming Inspection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Actor\u003C/strong>: Quality Champion (Grace)\n\u003Cstrong>Trigger\u003C/strong>: New batch arrives at collection center\n\u003Cstrong>Precondition\u003C/strong>: Tablet with VariScout Lite installed (PWA)\u003C/p>\n\u003Cp>\u003Cstrong>Flow\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Open VariScout Lite (works offline)\u003C/li>\n\u003Cli>Enter measurements manually or upload CSV from digital scale\u003C/li>\n\u003Cli>System auto-detects weight as outcome, farm as factor\u003C/li>\n\u003Cli>View I-chart showing individual measurements against spec limits\u003C/li>\n\u003Cli>View boxplot comparing farms in this batch\u003C/li>\n\u003Cli>View stats panel: 94% pass rate, Cpk = 1.1\u003C/li>\n\u003Cli>Identify Farm C as underperforming (red highlighting)\u003C/li>\n\u003Cli>Save analysis with batch ID\u003C/li>\n\u003Cli>Export PNG for batch record\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Outcome\u003C/strong>: Batch accepted with documented analysis; Farm C flagged for follow-up\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"use-case-2-weekly-performance-review\">Use Case 2: Weekly Performance Review\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#use-case-2-weekly-performance-review\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Case 2: Weekly Performance Review”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Actor\u003C/strong>: Quality Champion (Grace)\n\u003Cstrong>Trigger\u003C/strong>: End of week, management meeting tomorrow\n\u003Cstrong>Precondition\u003C/strong>: Week’s data collected in CSV\u003C/p>\n\u003Cp>\u003Cstrong>Flow\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Upload week’s data (500 rows)\u003C/li>\n\u003Cli>Configure: Weight as outcome; Farm, Variety as factors\u003C/li>\n\u003Cli>Set spec limits: LSL=300g, USL=350g\u003C/li>\n\u003Cli>View I-chart trending over the week\u003C/li>\n\u003Cli>Click Pareto bar for “Farm C” → filters all charts to Farm C data\u003C/li>\n\u003Cli>Stats update: Farm C Cpk = 0.7 vs overall 1.1\u003C/li>\n\u003Cli>See boxplot confirms Farm C lower and more variable\u003C/li>\n\u003Cli>Export dashboard as PNG for presentation\u003C/li>\n\u003Cli>Save analysis as “Week 48 Review”\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Outcome\u003C/strong>: Clear visualization showing Farm C needs intervention; data-backed recommendation to management\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"use-case-3-export-certification-report\">Use Case 3: Export Certification Report\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#use-case-3-export-certification-report\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Case 3: Export Certification Report”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Actor\u003C/strong>: Quality Champion (Grace)\n\u003Cstrong>Trigger\u003C/strong>: Buyer requests capability evidence for certification\n\u003Cstrong>Precondition\u003C/strong>: 3 months of data available\u003C/p>\n\u003Cp>\u003Cstrong>Flow\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Load historical data (2000 rows)\u003C/li>\n\u003Cli>Set outcome and factors\u003C/li>\n\u003Cli>Configure buyer’s specs (USL/LSL/Target)\u003C/li>\n\u003Cli>View Cpk = 1.45 (above 1.33 threshold - green)\u003C/li>\n\u003Cli>View pass rate = 98.2%\u003C/li>\n\u003Cli>Export dashboard as PNG\u003C/li>\n\u003Cli>Download .vrs file as data backup\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Outcome\u003C/strong>: Professional capability evidence for certification; data archived for audit trail\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"use-case-4-farmer-training-session\">Use Case 4: Farmer Training Session\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#use-case-4-farmer-training-session\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Case 4: Farmer Training Session”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Actor\u003C/strong>: Training Coordinator (Carlos)\n\u003Cstrong>Trigger\u003C/strong>: Monthly cooperative quality meeting\n\u003Cstrong>Precondition\u003C/strong>: Month’s defect data collected\u003C/p>\n\u003Cp>\u003Cstrong>Flow\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Load cooperative’s coffee defect data\u003C/li>\n\u003Cli>Configure multi-tier grades: Specialty (≤5), Premium (6-8), Exchange (9-23), Off-Grade (>23)\u003C/li>\n\u003Cli>Project dashboard to group\u003C/li>\n\u003Cli>Show I-chart with colored bands for each grade\u003C/li>\n\u003Cli>Click each cooperative in Pareto → show their grade distribution\u003C/li>\n\u003Cli>Farmers see: “Coop North = 84% Specialty; Coop South = 52% Specialty”\u003C/li>\n\u003Cli>Discuss visible patterns (processing method correlation)\u003C/li>\n\u003Cli>Save analysis for follow-up\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Outcome\u003C/strong>: Farmers understand grading visually; discussion grounded in data not opinion\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"use-case-5-root-cause-investigation\">Use Case 5: Root Cause Investigation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#use-case-5-root-cause-investigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Case 5: Root Cause Investigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Actor\u003C/strong>: Quality Engineer (Raj)\n\u003Cstrong>Trigger\u003C/strong>: Sudden increase in fabric defects\n\u003Cstrong>Precondition\u003C/strong>: Production data from last 2 weeks\u003C/p>\n\u003Cp>\u003Cstrong>Flow\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Upload production data\u003C/li>\n\u003Cli>Set tensile strength as outcome; Loom ID, Operator, Shift as factors\u003C/li>\n\u003Cli>View I-chart: see jump in variation starting 5 days ago\u003C/li>\n\u003Cli>Click that time period → filters to those dates\u003C/li>\n\u003Cli>View Pareto: Loom 7 accounts for 60% of failures\u003C/li>\n\u003Cli>View boxplot: Loom 7 dramatically lower than others\u003C/li>\n\u003Cli>Cross-reference: Loom 7 had maintenance 6 days ago\u003C/li>\n\u003Cli>Save analysis as “Loom 7 Investigation”\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Outcome\u003C/strong>: Root cause identified (Loom 7 post-maintenance issue); maintenance team notified\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"use-case-6-offline-field-analysis\">Use Case 6: Offline Field Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#use-case-6-offline-field-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Case 6: Offline Field Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Actor\u003C/strong>: Quality Champion (Grace)\n\u003Cstrong>Trigger\u003C/strong>: At remote collection center, no internet\n\u003Cstrong>Precondition\u003C/strong>: VariScout Lite installed as PWA\u003C/p>\n\u003Cp>\u003Cstrong>Flow\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Open app (loads from cache, no network needed)\u003C/li>\n\u003Cli>Enter measurements via manual entry grid\u003C/li>\n\u003Cli>Paste data from clipboard (copied from scale readout)\u003C/li>\n\u003Cli>Full analysis available offline\u003C/li>\n\u003Cli>Save analysis to browser storage\u003C/li>\n\u003Cli>Later at office: open saved project, export as needed\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Outcome\u003C/strong>: Complete analysis capability regardless of connectivity\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-5-feature-priority-matrix\">Part 5: Feature Priority Matrix\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-5-feature-priority-matrix\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 5: Feature Priority Matrix”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Based on JTBD and use cases, prioritized features:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"must-have-core-jtbd\">Must Have (Core JTBD)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#must-have-core-jtbd\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Must Have (Core JTBD)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Job Served\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>CSV/Excel import with auto-detection\u003C/td>\u003Ctd>All jobs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>I-Chart with control limits\u003C/td>\u003Ctd>Jobs 1, 2, 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot factor comparison\u003C/td>\u003Ctd>Jobs 2, 4\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto frequency analysis\u003C/td>\u003Ctd>Jobs 2, 4\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Linked cross-filtering\u003C/td>\u003Ctd>Job 2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Spec limits (USL/LSL)\u003C/td>\u003Ctd>Jobs 1, 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cpk/Cp calculation\u003C/td>\u003Ctd>Job 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Offline PWA operation\u003C/td>\u003Ctd>Job 5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Local-only data storage\u003C/td>\u003Ctd>Job 6\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PNG export\u003C/td>\u003Ctd>Jobs 3, 4\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"should-have-enhanced-value\">Should Have (Enhanced Value)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#should-have-enhanced-value\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Should Have (Enhanced Value)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Job Served\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Multi-tier grading system\u003C/td>\u003Ctd>Jobs 1, 4 (coffee/agriculture)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Project save/load\u003C/td>\u003Ctd>Job 7 (confidence through reproducibility)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>.vrs file export/import\u003C/td>\u003Ctd>Job 6 (backup, transfer)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Manual data entry\u003C/td>\u003Ctd>Job 5 (field use)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sample datasets\u003C/td>\u003Ctd>Job 7 (learning, demo)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"nice-to-have-future\">Nice to Have (Future)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#nice-to-have-future\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Nice to Have (Future)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Job Served\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Multi-language support\u003C/td>\u003Ctd>Accessibility in developing countries\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trend analysis over time\u003C/td>\u003Ctd>Job 2 (pattern detection)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Comparative period analysis\u003C/td>\u003Ctd>Job 2 (before/after)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Report templates\u003C/td>\u003Ctd>Job 3 (certification reports)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-6-key-insights-summary\">Part 6: Key Insights Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-6-key-insights-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 6: Key Insights Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-we-learned\">What We Learned\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-we-learned\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What We Learned”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Offline-first is non-negotiable\u003C/strong> - Field work in developing countries means unreliable internet. The tool must work fully offline.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Privacy = competitive advantage\u003C/strong> - Unlike enterprise tools pushing cloud storage, local-only data is a feature, not a limitation.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Time savings is the primary value\u003C/strong> - Reducing 4-hour Excel work to 1 hour is transformative for busy QA professionals.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Linked visualization is the “magic”\u003C/strong> - The ability to click one chart and filter all others is the key differentiator from Excel.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Transparency over AI\u003C/strong> - Users need to defend their analysis to auditors. “The algorithm decided” is not acceptable. Transparent statistics are preferred.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Multi-tier grading matters\u003C/strong> - For agriculture exports (coffee, produce), grade-based classification is as important as simple pass/fail.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Visual communication to non-experts\u003C/strong> - Charts must be clear enough to show farmers/operators without statistical training.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Cost sensitivity is extreme\u003C/strong> - $200/month is unacceptable for SMEs in developing countries. Free or very low cost is essential.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-7-design-principles-for-variscout-lite\">Part 7: Design Principles for VariScout Lite\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-7-design-principles-for-variscout-lite\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 7: Design Principles for VariScout Lite”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Based on this research, the following design principles should guide development:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Offline by default\u003C/strong> - Every feature must work without network connectivity\u003C/li>\n\u003Cli>\u003Cstrong>Data stays local\u003C/strong> - Zero external data transmission\u003C/li>\n\u003Cli>\u003Cstrong>Transparent math\u003C/strong> - Show formulas, explain metrics, no black boxes\u003C/li>\n\u003Cli>\u003Cstrong>Linked exploration\u003C/strong> - Charts talk to each other through filtering\u003C/li>\n\u003Cli>\u003Cstrong>Fast to first insight\u003C/strong> - Under 30 seconds from upload to visualization\u003C/li>\n\u003Cli>\u003Cstrong>Export-ready outputs\u003C/strong> - Professional charts suitable for reports\u003C/li>\n\u003Cli>\u003Cstrong>Progressive complexity\u003C/strong> - Simple defaults, optional advanced settings\u003C/li>\n\u003Cli>\u003Cstrong>Domain-aware\u003C/strong> - Sample data and terminology that matches user contexts\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cp>\u003Cem>Document prepared as UX research artifact for VariScout Lite product development\u003C/em>\u003C/p>", + { + "headings": 599, + "localImagePaths": 727, + "remoteImagePaths": 728, + "frontmatter": 729, + "imagePaths": 730 + }, + [ + 600, 602, 605, 608, 611, 614, 617, 620, 624, 627, 630, 633, 636, 638, 641, 643, 646, 649, 652, + 655, 658, 661, 664, 667, 670, 673, 676, 679, 682, 685, 688, 691, 694, 697, 700, 703, 706, 709, + 712, 715, 718, 721, 724 + ], + { "depth": 30, "slug": 601, "text": 589 }, + "ux-research-variscout-lite", + { "depth": 33, "slug": 603, "text": 604 }, + "design-thinking--jtbd-framework-for-quality-professionals-in-developing-countries", + "Design Thinking & JTBD Framework for Quality Professionals in Developing Countries", + { "depth": 33, "slug": 606, "text": 607 }, + "part-1-simulated-user-interview", + "Part 1: Simulated User Interview", + { "depth": 79, "slug": 609, "text": 610 }, + "interview-context", + "Interview Context", + { "depth": 79, "slug": 612, "text": 613 }, + "interview-transcript", + "Interview Transcript", + { "depth": 33, "slug": 615, "text": 616 }, + "part-2-user-personas", + "Part 2: User Personas", + { "depth": 79, "slug": 618, "text": 619 }, + "primary-persona-the-export-quality-champion", + "Primary Persona: “The Export Quality Champion”", + { "depth": 621, "slug": 622, "text": 623 }, + 4, + "goals", + "Goals", + { "depth": 621, "slug": 625, "text": 626 }, + "frustrations", + "Frustrations", + { "depth": 621, "slug": 628, "text": 629 }, + "context", + "Context", + { "depth": 621, "slug": 631, "text": 632 }, + "quote", + "Quote", + { "depth": 79, "slug": 634, "text": 635 }, + "secondary-persona-the-factory-floor-analyst", + "Secondary Persona: “The Factory Floor Analyst”", + { "depth": 621, "slug": 637, "text": 629 }, + "context-1", + { "depth": 79, "slug": 639, "text": 640 }, + "tertiary-persona-the-cooperative-trainer", + "Tertiary Persona: “The Cooperative Trainer”", + { "depth": 621, "slug": 642, "text": 629 }, + "context-2", + { "depth": 33, "slug": 644, "text": 645 }, + "part-3-jobs-to-be-done-jtbd-framework", + "Part 3: Jobs-to-be-Done (JTBD) Framework", + { "depth": 79, "slug": 647, "text": 648 }, + "core-functional-jobs", + "Core Functional Jobs", + { "depth": 621, "slug": 650, "text": 651 }, + "job-1-assess-batch-conformance", + "Job 1: Assess Batch Conformance", + { "depth": 621, "slug": 653, "text": 654 }, + "job-2-identify-variation-sources", + "Job 2: Identify Variation Sources", + { "depth": 621, "slug": 656, "text": 657 }, + "job-3-monitor-process-capability", + "Job 3: Monitor Process Capability", + { "depth": 621, "slug": 659, "text": 660 }, + "job-4-communicate-quality-issues", + "Job 4: Communicate Quality Issues", + { "depth": 621, "slug": 662, "text": 663 }, + "job-5-work-without-internet", + "Job 5: Work Without Internet", + { "depth": 621, "slug": 665, "text": 666 }, + "job-6-protect-sensitive-data", + "Job 6: Protect Sensitive Data", + { "depth": 79, "slug": 668, "text": 669 }, + "emotional-jobs", + "Emotional Jobs", + { "depth": 621, "slug": 671, "text": 672 }, + "job-7-feel-confident-in-analysis", + "Job 7: Feel Confident in Analysis", + { "depth": 621, "slug": 674, "text": 675 }, + "job-8-feel-efficient-and-professional", + "Job 8: Feel Efficient and Professional", + { "depth": 79, "slug": 677, "text": 678 }, + "social-jobs", + "Social Jobs", + { "depth": 621, "slug": 680, "text": 681 }, + "job-9-demonstrate-value-to-organization", + "Job 9: Demonstrate Value to Organization", + { "depth": 621, "slug": 683, "text": 684 }, + "job-10-empower-suppliersfarmers", + "Job 10: Empower Suppliers/Farmers", + { "depth": 33, "slug": 686, "text": 687 }, + "part-4-use-cases", + "Part 4: Use Cases", + { "depth": 79, "slug": 689, "text": 690 }, + "use-case-1-daily-incoming-inspection", + "Use Case 1: Daily Incoming Inspection", + { "depth": 79, "slug": 692, "text": 693 }, + "use-case-2-weekly-performance-review", + "Use Case 2: Weekly Performance Review", + { "depth": 79, "slug": 695, "text": 696 }, + "use-case-3-export-certification-report", + "Use Case 3: Export Certification Report", + { "depth": 79, "slug": 698, "text": 699 }, + "use-case-4-farmer-training-session", + "Use Case 4: Farmer Training Session", + { "depth": 79, "slug": 701, "text": 702 }, + "use-case-5-root-cause-investigation", + "Use Case 5: Root Cause Investigation", + { "depth": 79, "slug": 704, "text": 705 }, + "use-case-6-offline-field-analysis", + "Use Case 6: Offline Field Analysis", + { "depth": 33, "slug": 707, "text": 708 }, + "part-5-feature-priority-matrix", + "Part 5: Feature Priority Matrix", + { "depth": 79, "slug": 710, "text": 711 }, + "must-have-core-jtbd", + "Must Have (Core JTBD)", + { "depth": 79, "slug": 713, "text": 714 }, + "should-have-enhanced-value", + "Should Have (Enhanced Value)", + { "depth": 79, "slug": 716, "text": 717 }, + "nice-to-have-future", + "Nice to Have (Future)", + { "depth": 33, "slug": 719, "text": 720 }, + "part-6-key-insights-summary", + "Part 6: Key Insights Summary", + { "depth": 79, "slug": 722, "text": 723 }, + "what-we-learned", + "What We Learned", + { "depth": 33, "slug": 725, "text": 726 }, + "part-7-design-principles-for-variscout-lite", + "Part 7: Design Principles for VariScout Lite", + [], + [], + { "title": 589 }, + [], + "01-vision/philosophy", + { "id": 731, "data": 733, "body": 738, "filePath": 739, "digest": 740, "rendered": 741 }, + { + "title": 734, + "editUrl": 16, + "head": 735, + "template": 18, + "sidebar": 736, + "pagefind": 16, + "draft": 20 + }, + "EDA for Process Improvement", + [], + { "hidden": 20, "attrs": 737 }, + {}, + "# EDA for Process Improvement\n\nVariScout is **Exploratory Data Analysis (EDA) for process improvement** — not statistical verification.\n\n---\n\n## Two Mindsets\n\n| Academic Statistician | Process Improvement Practitioner |\n| -------------------------------- | -------------------------------- |\n| \"Is this significant at p\u003C0.05?\" | \"Where should I focus?\" |\n| Hypothesis testing | Pattern finding |\n| Prove with math | See with eyes |\n| Statistical correctness | Directional guidance |\n| Analysis as end goal | Analysis as starting point |\n\n---\n\n## The Goal\n\n- **Find where to focus** — which factor, which machine, which shift?\n- **See where to apply Lean thinking** — visual patterns reveal opportunities\n- **Guide improvement effort** — prioritize by impact, not guesswork\n- **Move fast, iterate, improve** — 30-second answers, not 30-minute reports\n\n---\n\n## The Key Insight\n\n> VaRiScout finds WHERE to focus. Apply Lean thinking to find WHY — and what to do about it.\n\nVariScout identifies **factors driving variation**, not \"root causes.\" EDA shows _which_ factors explain variation — the _why_ requires further investigation (5 Whys, experimentation, Gemba walks).\n\nThis distinction matters: we quantify contribution, not causation.\n\n---\n\n## The Promise\n\n> **46% of your variation may be hiding in one place. Find it. Fix it. Check it. Continue.**\n\nThis isn't a marketing claim — it's what the drill-down methodology routinely reveals. By applying filter chips to the highest-impact factors, practitioners typically isolate a significant portion of total variation to specific, actionable conditions.\n\n---\n\n## The Process Detective's Toolkit: Four Lenses\n\nVariScout's four core charts are **four lenses** — parallel ways to examine the same data. Like a detective switching between UV light, a magnifying glass, and a timeline reconstruction, each lens reveals something different:\n\n| Lens | Detective Question |\n| ---------------------- | -------------------------------------------------------------------------- |\n| **I-Chart (CHANGE)** | \"What changed between yesterday's shift and today's shift?\" |\n| **Boxplot (FLOW)** | \"Retrace the footprints upstream. Where did this come from?\" |\n| **Pareto (FAILURE)** | \"Where is the 'blood spatter'? The chaotic, mixed data?\" |\n| **Capability (VALUE)** | \"Am I looking at a clue (customer issue) or just noise (irrelevant spec)?\" |\n\nThe first three lenses (CHANGE, FLOW, FAILURE) analyze internal process behavior. The VALUE lens is a different type of question — it brings in an external reference (customer specifications) to ask \"does it actually matter?\"\n\n**Add-on:**\n\n| Tool | Detective Question |\n| ---------------------------- | ------------------------------------------------ |\n| **Regression (CORRELATION)** | \"Is there a connection between these two clues?\" |\n\n---\n\n## The Guided Frustration Pedagogy\n\nThe Sock Mystery teaches through \"guided frustration\":\n\n1. **Phase 1: Immersion in Chaos** — Let them fail so they ask why\n2. **Phase 2: Physical Stratification** — Peel back layers with questions\n3. **Phase 3: System Understanding** — Connect statistics to the real system\n\nVariScout enables this same journey with real data:\n\n1. Upload data → see chaotic I-Chart (frustration)\n2. Click through factors → discover subgroups (stratification)\n3. Drill down → find the actual variation source (understanding)\n\n---\n\n## Not What VariScout Does\n\nVariScout is intentionally **not**:\n\n- A hypothesis testing tool (use Minitab or R for that)\n- A predictive modeling platform (use Python/ML tools)\n- A DOE analysis system (use JMP or specialized software)\n- A statistical verification engine (use academic tools)\n\nVariScout is **the first step** — finding where to focus before investing in deeper analysis.\n\n---\n\n## See Also\n\n- [Four Lenses](four-lenses/index.md) — The methodology framework\n- [Two Voices](two-voices/index.md) — Control limits vs specification limits\n- [Drill-Down](four-lenses/drilldown.md) — Progressive analysis methodology\n- [Progressive Stratification](progressive-stratification.md) — Why this UI design is the right answer for variation analysis", + "src/content/docs/01-vision/philosophy.md", + "0aef0a991139af65", + { "html": 742, "metadata": 743 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"eda-for-process-improvement\">EDA for Process Improvement\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#eda-for-process-improvement\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “EDA for Process Improvement”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is \u003Cstrong>Exploratory Data Analysis (EDA) for process improvement\u003C/strong> — not statistical verification.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"two-mindsets\">Two Mindsets\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#two-mindsets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two Mindsets”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Academic Statistician\u003C/th>\u003Cth>Process Improvement Practitioner\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Is this significant at p<0.05?\"\u003C/td>\u003Ctd>\"Where should I focus?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hypothesis testing\u003C/td>\u003Ctd>Pattern finding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Prove with math\u003C/td>\u003Ctd>See with eyes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Statistical correctness\u003C/td>\u003Ctd>Directional guidance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analysis as end goal\u003C/td>\u003Ctd>Analysis as starting point\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-goal\">The Goal\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-goal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Goal”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Find where to focus\u003C/strong> — which factor, which machine, which shift?\u003C/li>\n\u003Cli>\u003Cstrong>See where to apply Lean thinking\u003C/strong> — visual patterns reveal opportunities\u003C/li>\n\u003Cli>\u003Cstrong>Guide improvement effort\u003C/strong> — prioritize by impact, not guesswork\u003C/li>\n\u003Cli>\u003Cstrong>Move fast, iterate, improve\u003C/strong> — 30-second answers, not 30-minute reports\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-key-insight\">The Key Insight\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-key-insight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Key Insight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>VaRiScout finds WHERE to focus. Apply Lean thinking to find WHY — and what to do about it.\u003C/p>\n\u003C/blockquote>\n\u003Cp>VariScout identifies \u003Cstrong>factors driving variation\u003C/strong>, not “root causes.” EDA shows \u003Cem>which\u003C/em> factors explain variation — the \u003Cem>why\u003C/em> requires further investigation (5 Whys, experimentation, Gemba walks).\u003C/p>\n\u003Cp>This distinction matters: we quantify contribution, not causation.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-promise\">The Promise\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-promise\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Promise”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>46% of your variation may be hiding in one place. Find it. Fix it. Check it. Continue.\u003C/strong>\u003C/p>\n\u003C/blockquote>\n\u003Cp>This isn’t a marketing claim — it’s what the drill-down methodology routinely reveals. By applying filter chips to the highest-impact factors, practitioners typically isolate a significant portion of total variation to specific, actionable conditions.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-process-detectives-toolkit-four-lenses\">The Process Detective’s Toolkit: Four Lenses\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-process-detectives-toolkit-four-lenses\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Process Detective’s Toolkit: Four Lenses”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s four core charts are \u003Cstrong>four lenses\u003C/strong> — parallel ways to examine the same data. Like a detective switching between UV light, a magnifying glass, and a timeline reconstruction, each lens reveals something different:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Lens\u003C/th>\u003Cth>Detective Question\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>I-Chart (CHANGE)\u003C/strong>\u003C/td>\u003Ctd>“What changed between yesterday’s shift and today’s shift?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Boxplot (FLOW)\u003C/strong>\u003C/td>\u003Ctd>“Retrace the footprints upstream. Where did this come from?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pareto (FAILURE)\u003C/strong>\u003C/td>\u003Ctd>“Where is the ‘blood spatter’? The chaotic, mixed data?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Capability (VALUE)\u003C/strong>\u003C/td>\u003Ctd>“Am I looking at a clue (customer issue) or just noise (irrelevant spec)?”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The first three lenses (CHANGE, FLOW, FAILURE) analyze internal process behavior. The VALUE lens is a different type of question — it brings in an external reference (customer specifications) to ask “does it actually matter?”\u003C/p>\n\u003Cp>\u003Cstrong>Add-on:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tool\u003C/th>\u003Cth>Detective Question\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Regression (CORRELATION)\u003C/strong>\u003C/td>\u003Ctd>“Is there a connection between these two clues?”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-guided-frustration-pedagogy\">The Guided Frustration Pedagogy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-guided-frustration-pedagogy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Guided Frustration Pedagogy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Sock Mystery teaches through “guided frustration”:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Phase 1: Immersion in Chaos\u003C/strong> — Let them fail so they ask why\u003C/li>\n\u003Cli>\u003Cstrong>Phase 2: Physical Stratification\u003C/strong> — Peel back layers with questions\u003C/li>\n\u003Cli>\u003Cstrong>Phase 3: System Understanding\u003C/strong> — Connect statistics to the real system\u003C/li>\n\u003C/ol>\n\u003Cp>VariScout enables this same journey with real data:\u003C/p>\n\u003Col>\n\u003Cli>Upload data → see chaotic I-Chart (frustration)\u003C/li>\n\u003Cli>Click through factors → discover subgroups (stratification)\u003C/li>\n\u003Cli>Drill down → find the actual variation source (understanding)\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"not-what-variscout-does\">Not What VariScout Does\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#not-what-variscout-does\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Not What VariScout Does”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is intentionally \u003Cstrong>not\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>A hypothesis testing tool (use Minitab or R for that)\u003C/li>\n\u003Cli>A predictive modeling platform (use Python/ML tools)\u003C/li>\n\u003Cli>A DOE analysis system (use JMP or specialized software)\u003C/li>\n\u003Cli>A statistical verification engine (use academic tools)\u003C/li>\n\u003C/ul>\n\u003Cp>VariScout is \u003Cstrong>the first step\u003C/strong> — finding where to focus before investing in deeper analysis.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"four-lenses/index.md\">Four Lenses\u003C/a> — The methodology framework\u003C/li>\n\u003Cli>\u003Ca href=\"two-voices/index.md\">Two Voices\u003C/a> — Control limits vs specification limits\u003C/li>\n\u003Cli>\u003Ca href=\"four-lenses/drilldown.md\">Drill-Down\u003C/a> — Progressive analysis methodology\u003C/li>\n\u003Cli>\u003Ca href=\"progressive-stratification.md\">Progressive Stratification\u003C/a> — Why this UI design is the right answer for variation analysis\u003C/li>\n\u003C/ul>", + { + "headings": 744, + "localImagePaths": 767, + "remoteImagePaths": 768, + "frontmatter": 769, + "imagePaths": 770 + }, + [745, 747, 750, 753, 756, 757, 760, 763, 766], + { "depth": 30, "slug": 746, "text": 734 }, + "eda-for-process-improvement", + { "depth": 33, "slug": 748, "text": 749 }, + "two-mindsets", + "Two Mindsets", + { "depth": 33, "slug": 751, "text": 752 }, + "the-goal", + "The Goal", + { "depth": 33, "slug": 754, "text": 755 }, + "the-key-insight", + "The Key Insight", + { "depth": 33, "slug": 40, "text": 41 }, + { "depth": 33, "slug": 758, "text": 759 }, + "the-process-detectives-toolkit-four-lenses", + "The Process Detective’s Toolkit: Four Lenses", + { "depth": 33, "slug": 761, "text": 762 }, + "the-guided-frustration-pedagogy", + "The Guided Frustration Pedagogy", + { "depth": 33, "slug": 764, "text": 765 }, + "not-what-variscout-does", + "Not What VariScout Does", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 734 }, + [], + "01-vision/market-analysis", + { "id": 771, "data": 773, "body": 778, "filePath": 779, "digest": 780, "rendered": 781 }, + { + "title": 774, + "editUrl": 16, + "head": 775, + "template": 18, + "sidebar": 776, + "pagefind": 16, + "draft": 20 + }, + "Market Analysis & TAM Estimate", + [], + { "hidden": 20, "attrs": 777 }, + {}, + "# Market Analysis & TAM Estimate\n\n_Last updated: February 2026_\n\nVariScout plays in the intersection of **quality analytics software**, **Lean Six Sigma training tools**, and **process improvement workflows**.\n\n---\n\n## Market Context\n\n| Market | Size (2025) | CAGR | Source |\n| --------------------------- | ----------- | ----- | ------------------------ |\n| SPC Software (global) | ~$1.05B | ~12% | Verified Market Research |\n| Quality Management Software | ~$12B | ~10% | Grand View Research |\n| Lean Six Sigma Services | ~$6.8B | ~8.7% | VMR |\n\n---\n\n## TAM: Three Addressable Layers\n\n### Layer 1 — Lightweight Quality Analytics (Primary)\n\n**Who:** Manufacturing companies currently using Minitab, InfinityQS, PQ Systems, or Excel for variation analysis.\n\nVariScout doesn't compete with the full Minitab suite (DOE, hypothesis testing, predictive). It competes for the **\"I just need to see my variation\"** segment — quality engineers who use 20% of Minitab's features but pay 100% of the price. The reference market is \"SPC Software\" (~$1.05B) in industry reports, but VariScout targets the variation investigation slice, not the full SPC category.\n\n| Assumption | Value | Rationale |\n| ----------------------------- | ------------------ | ---------------------------------- |\n| Global SPC software market | $1.05B | Market reports 2025 |\n| VariScout's addressable slice | ~10–15% | Lightweight/EDA segment only |\n| Estimated deployment sites | ~50K–100K | Manufacturing plants, food, pharma |\n| **TAM (Layer 1)** | **~€90–160M/year** | At €1,800/year per site |\n\n### Layer 2 — LSS Training Funnel (Secondary)\n\n**Who:** Lean Six Sigma training providers, universities, and corporate training programs needing a free/cheap Minitab alternative for Green Belt courses.\n\n| Assumption | Value | Rationale |\n| ------------------------------- | ---------------- | --------------------------------- |\n| LSS certified professionals | ~3–5M worldwide | MSI estimates |\n| New Green Belts trained/year | ~200K–500K | Based on training market growth |\n| Training programs needing tools | ~5,000–10,000 | Universities + corporate programs |\n| Convert to paid after training | ~10–20% | Most use the free PWA |\n| **TAM (Layer 2)** | **~€5–15M/year** | Corporate upgrades to Azure App |\n\n:::note\nMost training revenue comes from the **free PWA** driving awareness, not direct sales. The TAM here flows from corporate training departments that upgrade to Azure App for internal use after discovering VariScout through training.\n:::\n\n### Layer 3 — Excel-Native Quality Analytics (Tertiary)\n\n**Who:** Quality professionals who live in Excel and want variation analysis without leaving it. [Shelved — Excel Add-in removed Feb 2026]\n\n| Assumption | Value | Rationale |\n| --------------------------------- | ----------------- | ---------------------------- |\n| Microsoft 365 business users | ~400M | Microsoft reports |\n| Users doing quality work in Excel | ~2–5M | Rough estimate |\n| Install a free Add-in | ~5–10% | AppSource discovery rate |\n| Convert Add-in → Azure App | ~1–3% | Typical free-to-paid funnel |\n| **TAM (Layer 3)** | **~€10–25M/year** | Via Excel → Azure App funnel |\n\n---\n\n## TAM Summary\n\n```\n┌────────────────────────────────────────────────────────┐\n│ TOTAL ADDRESSABLE MARKET │\n│ │\n│ Layer 1: Quality Analytics €90–160M/year │\n│ Layer 2: LSS Training Funnel €5–15M/year │\n│ Layer 3: Excel Funnel €10–25M/year │\n│ ───────────────────────────────────── │\n│ TOTAL TAM €105–200M/year │\n│ │\n│ SAM (Serviceable) €10–30M/year │\n│ SOM (Obtainable, Year 1-3) €0.1–1M/year │\n└────────────────────────────────────────────────────────┘\n```\n\n---\n\n## SAM → SOM Narrowing\n\n### SAM (Serviceable Addressable Market): €10–30M/year\n\nNarrowed by:\n\n- **Microsoft ecosystem only** — Azure Marketplace + AppSource\n- **English/EU markets first** — initial language and compliance reach\n- **SMBs with 5–200 employees** — sweet spot for from-€99/month flat pricing\n- **Manufacturing, food, pharma** — core verticals with variation analysis need\n\n### SOM (Serviceable Obtainable Market): €100K–1M/year\n\nNear-term realistic capture (solo founder, no sales team):\n\n| Milestone | Customers | ARR | Timeline |\n| ----------------- | --------- | ----- | -------- |\n| Ramen profitable | 50 | €90K | Year 1 |\n| Sustainable indie | 200 | €360K | Year 2 |\n| Growth mode | 500 | €900K | Year 3 |\n\n---\n\n## Competitive Positioning\n\n| Segment | Incumbent | VariScout Advantage | VariScout Weakness |\n| ----------------------- | ---------------------------- | -------------------------------------- | ----------------------- |\n| Full-suite SPC tools | Minitab (~$1,800/user/yr) | 10× cheaper for teams, zero install | Fewer statistical tests |\n| Enterprise QMS | InfinityQS ($50–100/user/mo) | No implementation cost, instant deploy | No MES/ERP integration |\n| Excel quality analytics | PQ Systems ($595 perpetual) | Free Add-in, modern UX | Less mature |\n| Free tools | R, Python, Sheets | No coding required, guided workflows | Less flexible |\n| Training tools | Minitab academic licenses | Free PWA, browser-based | Less brand recognition |\n\n### Pricing Comparison\n\n| Product | Model | Price | VariScout Equivalent |\n| ---------- | ---------------------- | -------------------- | ------------------------------- |\n| Minitab | Per-user, annual | ~€135–155/user/month | From €99/month unlimited users |\n| InfinityQS | Per-user, subscription | €50–100/user/month | From €99/month unlimited users |\n| PQ Systems | Perpetual license | ~€595 one-time | Free PWA + from €99/month Azure |\n| VariScout | Per-deployment | €99–299/month | — |\n\n> **Key insight:** VariScout is Minitab-priced per seat, but unlimited users. A team of 3+ saves money vs Minitab immediately. For a team of 10, it's 10× cheaper.\n\n---\n\n## Key Risks\n\n| Risk | Impact | Mitigation |\n| ------------------------------------- | ------------------------- | ----------------------------------- |\n| Azure Marketplace low discoverability | SOM shrinks significantly | Content marketing, direct outreach |\n| Minitab launches lightweight tier | TAM Layer 1 compresses | Speed to market, UX differentiation |\n| Buyers expect per-user pricing | Lose enterprise deals | Consider metered add-on later |\n| Free tools (R/Python) good enough | Training TAM shrinks | Focus on non-technical users |\n\n---\n\n## Bottom Line\n\n> VariScout's TAM is **real but niche** (~€100–200M). The product sits in a genuine gap between expensive SPC suites (used at 20% capacity) and DIY spreadsheet approaches. The from-€99/month flat pricing (two plans: Standard €99, Team €299) keeps the barrier low for individuals while capturing collaboration value from teams.\n>\n> The biggest variable isn't market size — it's **distribution**. Azure Marketplace reach and the free-to-paid funnel (PWA → Azure App) will determine whether VariScout captures 50 or 5,000 customers.\n\n---\n\n## See Also\n\n- [Product Overview](product-overview.md) — What we built and why\n- [Philosophy](philosophy.md) — EDA for process improvement\n- [Products & Pricing](../08-products/index.md) — Distribution strategy\n- [ADR-007](../07-decisions/adr-007-azure-marketplace-distribution.md) — Azure Marketplace decision", + "src/content/docs/01-vision/market-analysis.md", + "1a23a6d01b853388", + { "html": 782, "metadata": 783 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"market-analysis--tam-estimate\">Market Analysis & TAM Estimate\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#market-analysis--tam-estimate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Market Analysis & TAM Estimate”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>Last updated: February 2026\u003C/em>\u003C/p>\n\u003Cp>VariScout plays in the intersection of \u003Cstrong>quality analytics software\u003C/strong>, \u003Cstrong>Lean Six Sigma training tools\u003C/strong>, and \u003Cstrong>process improvement workflows\u003C/strong>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"market-context\">Market Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#market-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Market Context”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Market\u003C/th>\u003Cth>Size (2025)\u003C/th>\u003Cth>CAGR\u003C/th>\u003Cth>Source\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>SPC Software (global)\u003C/td>\u003Ctd>~$1.05B\u003C/td>\u003Ctd>~12%\u003C/td>\u003Ctd>Verified Market Research\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quality Management Software\u003C/td>\u003Ctd>~$12B\u003C/td>\u003Ctd>~10%\u003C/td>\u003Ctd>Grand View Research\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Lean Six Sigma Services\u003C/td>\u003Ctd>~$6.8B\u003C/td>\u003Ctd>~8.7%\u003C/td>\u003Ctd>VMR\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tam-three-addressable-layers\">TAM: Three Addressable Layers\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tam-three-addressable-layers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “TAM: Three Addressable Layers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layer-1--lightweight-quality-analytics-primary\">Layer 1 — Lightweight Quality Analytics (Primary)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layer-1--lightweight-quality-analytics-primary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layer 1 — Lightweight Quality Analytics (Primary)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Who:\u003C/strong> Manufacturing companies currently using Minitab, InfinityQS, PQ Systems, or Excel for variation analysis.\u003C/p>\n\u003Cp>VariScout doesn’t compete with the full Minitab suite (DOE, hypothesis testing, predictive). It competes for the \u003Cstrong>“I just need to see my variation”\u003C/strong> segment — quality engineers who use 20% of Minitab’s features but pay 100% of the price. The reference market is “SPC Software” (~$1.05B) in industry reports, but VariScout targets the variation investigation slice, not the full SPC category.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Assumption\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>Rationale\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Global SPC software market\u003C/td>\u003Ctd>$1.05B\u003C/td>\u003Ctd>Market reports 2025\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>VariScout’s addressable slice\u003C/td>\u003Ctd>~10–15%\u003C/td>\u003Ctd>Lightweight/EDA segment only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Estimated deployment sites\u003C/td>\u003Ctd>~50K–100K\u003C/td>\u003Ctd>Manufacturing plants, food, pharma\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>TAM (Layer 1)\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>~€90–160M/year\u003C/strong>\u003C/td>\u003Ctd>At €1,800/year per site\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layer-2--lss-training-funnel-secondary\">Layer 2 — LSS Training Funnel (Secondary)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layer-2--lss-training-funnel-secondary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layer 2 — LSS Training Funnel (Secondary)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Who:\u003C/strong> Lean Six Sigma training providers, universities, and corporate training programs needing a free/cheap Minitab alternative for Green Belt courses.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Assumption\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>Rationale\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>LSS certified professionals\u003C/td>\u003Ctd>~3–5M worldwide\u003C/td>\u003Ctd>MSI estimates\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>New Green Belts trained/year\u003C/td>\u003Ctd>~200K–500K\u003C/td>\u003Ctd>Based on training market growth\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Training programs needing tools\u003C/td>\u003Ctd>~5,000–10,000\u003C/td>\u003Ctd>Universities + corporate programs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Convert to paid after training\u003C/td>\u003Ctd>~10–20%\u003C/td>\u003Ctd>Most use the free PWA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>TAM (Layer 2)\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>~€5–15M/year\u003C/strong>\u003C/td>\u003Ctd>Corporate upgrades to Azure App\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Caside aria-label=\"Note\" class=\"starlight-aside starlight-aside--note\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath d=\"M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z\">\u003C/path>\u003C/svg>Note\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>Most training revenue comes from the \u003Cstrong>free PWA\u003C/strong> driving awareness, not direct sales. The TAM here flows from corporate training departments that upgrade to Azure App for internal use after discovering VariScout through training.\u003C/p>\u003C/div>\u003C/aside>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layer-3--excel-native-quality-analytics-tertiary\">Layer 3 — Excel-Native Quality Analytics (Tertiary)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layer-3--excel-native-quality-analytics-tertiary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layer 3 — Excel-Native Quality Analytics (Tertiary)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Who:\u003C/strong> Quality professionals who live in Excel and want variation analysis without leaving it. [Shelved — Excel Add-in removed Feb 2026]\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Assumption\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>Rationale\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Microsoft 365 business users\u003C/td>\u003Ctd>~400M\u003C/td>\u003Ctd>Microsoft reports\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Users doing quality work in Excel\u003C/td>\u003Ctd>~2–5M\u003C/td>\u003Ctd>Rough estimate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Install a free Add-in\u003C/td>\u003Ctd>~5–10%\u003C/td>\u003Ctd>AppSource discovery rate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Convert Add-in → Azure App\u003C/td>\u003Ctd>~1–3%\u003C/td>\u003Ctd>Typical free-to-paid funnel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>TAM (Layer 3)\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>~€10–25M/year\u003C/strong>\u003C/td>\u003Ctd>Via Excel → Azure App funnel\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tam-summary\">TAM Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tam-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “TAM Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ TOTAL ADDRESSABLE MARKET │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Layer 1: Quality Analytics €90–160M/year │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Layer 2: LSS Training Funnel €5–15M/year │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Layer 3: Excel Funnel €10–25M/year │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ───────────────────────────────────── │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ TOTAL TAM €105–200M/year │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ SAM (Serviceable) €10–30M/year │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ SOM (Obtainable, Year 1-3) €0.1–1M/year │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌────────────────────────────────────────────────────────┐│ TOTAL ADDRESSABLE MARKET ││ ││ Layer 1: Quality Analytics €90–160M/year ││ Layer 2: LSS Training Funnel €5–15M/year ││ Layer 3: Excel Funnel €10–25M/year ││ ───────────────────────────────────── ││ TOTAL TAM €105–200M/year ││ ││ SAM (Serviceable) €10–30M/year ││ SOM (Obtainable, Year 1-3) €0.1–1M/year │└────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sam--som-narrowing\">SAM → SOM Narrowing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sam--som-narrowing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SAM → SOM Narrowing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"sam-serviceable-addressable-market-1030myear\">SAM (Serviceable Addressable Market): €10–30M/year\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#sam-serviceable-addressable-market-1030myear\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SAM (Serviceable Addressable Market): €10–30M/year”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Narrowed by:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Microsoft ecosystem only\u003C/strong> — Azure Marketplace + AppSource\u003C/li>\n\u003Cli>\u003Cstrong>English/EU markets first\u003C/strong> — initial language and compliance reach\u003C/li>\n\u003Cli>\u003Cstrong>SMBs with 5–200 employees\u003C/strong> — sweet spot for from-€99/month flat pricing\u003C/li>\n\u003Cli>\u003Cstrong>Manufacturing, food, pharma\u003C/strong> — core verticals with variation analysis need\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"som-serviceable-obtainable-market-100k1myear\">SOM (Serviceable Obtainable Market): €100K–1M/year\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#som-serviceable-obtainable-market-100k1myear\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SOM (Serviceable Obtainable Market): €100K–1M/year”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Near-term realistic capture (solo founder, no sales team):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Milestone\u003C/th>\u003Cth>Customers\u003C/th>\u003Cth>ARR\u003C/th>\u003Cth>Timeline\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Ramen profitable\u003C/td>\u003Ctd>50\u003C/td>\u003Ctd>€90K\u003C/td>\u003Ctd>Year 1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sustainable indie\u003C/td>\u003Ctd>200\u003C/td>\u003Ctd>€360K\u003C/td>\u003Ctd>Year 2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Growth mode\u003C/td>\u003Ctd>500\u003C/td>\u003Ctd>€900K\u003C/td>\u003Ctd>Year 3\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-positioning\">Competitive Positioning\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-positioning\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Positioning”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Segment\u003C/th>\u003Cth>Incumbent\u003C/th>\u003Cth>VariScout Advantage\u003C/th>\u003Cth>VariScout Weakness\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Full-suite SPC tools\u003C/td>\u003Ctd>Minitab (~$1,800/user/yr)\u003C/td>\u003Ctd>10× cheaper for teams, zero install\u003C/td>\u003Ctd>Fewer statistical tests\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Enterprise QMS\u003C/td>\u003Ctd>InfinityQS ($50–100/user/mo)\u003C/td>\u003Ctd>No implementation cost, instant deploy\u003C/td>\u003Ctd>No MES/ERP integration\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel quality analytics\u003C/td>\u003Ctd>PQ Systems ($595 perpetual)\u003C/td>\u003Ctd>Free Add-in, modern UX\u003C/td>\u003Ctd>Less mature\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Free tools\u003C/td>\u003Ctd>R, Python, Sheets\u003C/td>\u003Ctd>No coding required, guided workflows\u003C/td>\u003Ctd>Less flexible\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Training tools\u003C/td>\u003Ctd>Minitab academic licenses\u003C/td>\u003Ctd>Free PWA, browser-based\u003C/td>\u003Ctd>Less brand recognition\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pricing-comparison\">Pricing Comparison\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pricing-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pricing Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth>Model\u003C/th>\u003Cth>Price\u003C/th>\u003Cth>VariScout Equivalent\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Minitab\u003C/td>\u003Ctd>Per-user, annual\u003C/td>\u003Ctd>~€135–155/user/month\u003C/td>\u003Ctd>From €99/month unlimited users\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>InfinityQS\u003C/td>\u003Ctd>Per-user, subscription\u003C/td>\u003Ctd>€50–100/user/month\u003C/td>\u003Ctd>From €99/month unlimited users\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PQ Systems\u003C/td>\u003Ctd>Perpetual license\u003C/td>\u003Ctd>~€595 one-time\u003C/td>\u003Ctd>Free PWA + from €99/month Azure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>VariScout\u003C/td>\u003Ctd>Per-deployment\u003C/td>\u003Ctd>€99–299/month\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Key insight:\u003C/strong> VariScout is Minitab-priced per seat, but unlimited users. A team of 3+ saves money vs Minitab immediately. For a team of 10, it’s 10× cheaper.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-risks\">Key Risks\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-risks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Risks”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Risk\u003C/th>\u003Cth>Impact\u003C/th>\u003Cth>Mitigation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Azure Marketplace low discoverability\u003C/td>\u003Ctd>SOM shrinks significantly\u003C/td>\u003Ctd>Content marketing, direct outreach\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Minitab launches lightweight tier\u003C/td>\u003Ctd>TAM Layer 1 compresses\u003C/td>\u003Ctd>Speed to market, UX differentiation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Buyers expect per-user pricing\u003C/td>\u003Ctd>Lose enterprise deals\u003C/td>\u003Ctd>Consider metered add-on later\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Free tools (R/Python) good enough\u003C/td>\u003Ctd>Training TAM shrinks\u003C/td>\u003Ctd>Focus on non-technical users\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"bottom-line\">Bottom Line\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#bottom-line\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Bottom Line”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>VariScout’s TAM is \u003Cstrong>real but niche\u003C/strong> (~€100–200M). The product sits in a genuine gap between expensive SPC suites (used at 20% capacity) and DIY spreadsheet approaches. The from-€99/month flat pricing (two plans: Standard €99, Team €299) keeps the barrier low for individuals while capturing collaboration value from teams.\u003C/p>\n\u003Cp>The biggest variable isn’t market size — it’s \u003Cstrong>distribution\u003C/strong>. Azure Marketplace reach and the free-to-paid funnel (PWA → Azure App) will determine whether VariScout captures 50 or 5,000 customers.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"product-overview.md\">Product Overview\u003C/a> — What we built and why\u003C/li>\n\u003Cli>\u003Ca href=\"philosophy.md\">Philosophy\u003C/a> — EDA for process improvement\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/index.md\">Products & Pricing\u003C/a> — Distribution strategy\u003C/li>\n\u003Cli>\u003Ca href=\"../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a> — Azure Marketplace decision\u003C/li>\n\u003C/ul>", + { + "headings": 784, + "localImagePaths": 827, + "remoteImagePaths": 828, + "frontmatter": 829, + "imagePaths": 830 + }, + [785, 787, 790, 793, 796, 799, 802, 805, 808, 811, 814, 817, 820, 823, 826], + { "depth": 30, "slug": 786, "text": 774 }, + "market-analysis--tam-estimate", + { "depth": 33, "slug": 788, "text": 789 }, + "market-context", + "Market Context", + { "depth": 33, "slug": 791, "text": 792 }, + "tam-three-addressable-layers", + "TAM: Three Addressable Layers", + { "depth": 79, "slug": 794, "text": 795 }, + "layer-1--lightweight-quality-analytics-primary", + "Layer 1 — Lightweight Quality Analytics (Primary)", + { "depth": 79, "slug": 797, "text": 798 }, + "layer-2--lss-training-funnel-secondary", + "Layer 2 — LSS Training Funnel (Secondary)", + { "depth": 79, "slug": 800, "text": 801 }, + "layer-3--excel-native-quality-analytics-tertiary", + "Layer 3 — Excel-Native Quality Analytics (Tertiary)", + { "depth": 33, "slug": 803, "text": 804 }, + "tam-summary", + "TAM Summary", + { "depth": 33, "slug": 806, "text": 807 }, + "sam--som-narrowing", + "SAM → SOM Narrowing", + { "depth": 79, "slug": 809, "text": 810 }, + "sam-serviceable-addressable-market-1030myear", + "SAM (Serviceable Addressable Market): €10–30M/year", + { "depth": 79, "slug": 812, "text": 813 }, + "som-serviceable-obtainable-market-100k1myear", + "SOM (Serviceable Obtainable Market): €100K–1M/year", + { "depth": 33, "slug": 815, "text": 816 }, + "competitive-positioning", + "Competitive Positioning", + { "depth": 79, "slug": 818, "text": 819 }, + "pricing-comparison", + "Pricing Comparison", + { "depth": 33, "slug": 821, "text": 822 }, + "key-risks", + "Key Risks", + { "depth": 33, "slug": 824, "text": 825 }, + "bottom-line", + "Bottom Line", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 774 }, + [], + "01-vision", + { "id": 831, "data": 833, "body": 838, "filePath": 839, "digest": 840, "rendered": 841 }, + { + "title": 834, + "editUrl": 16, + "head": 835, + "template": 18, + "sidebar": 836, + "pagefind": 16, + "draft": 20 + }, + "Vision & Methodology", + [], + { "hidden": 20, "attrs": 837 }, + {}, + "# Vision & Methodology\n\nVariScout is built on a philosophy of **EDA for process improvement** — not statistical verification.\n\n---\n\n## The Philosophy\n\n| Academic Statistician | Process Improvement Practitioner |\n| -------------------------------- | -------------------------------- |\n| \"Is this significant at p\u003C0.05?\" | \"Where should I focus?\" |\n| Hypothesis testing | Pattern finding |\n| Prove with math | See with eyes |\n| Statistical correctness | Directional guidance |\n| Analysis as end goal | Analysis as starting point |\n\n**The goal:**\n\n- Find where to focus\n- See where to apply Lean thinking\n- Guide improvement effort\n- Move fast, iterate, improve\n\n**The key insight:**\n\n> VaRiScout finds WHERE to focus. Apply Lean thinking to find WHY — and what to do about it.\n\n**The promise:**\n\n> 46% of your variation may be hiding in one place. Find it. Fix it. Check it. Continue.\n\n---\n\n## Deep Dives\n\n- [Philosophy](philosophy.md) — The EDA-for-process-improvement philosophy that drives VariScout\n- [Product Overview](product-overview.md) — High-level product positioning and capabilities\n\n---\n\n## Core Frameworks\n\n### Watson's Four Lenses of Variation\n\nWatson's Four Lenses give you four distinct perspectives — each revealing a different dimension of your process:\n\n| Chart | Lens | What You See Through It |\n| ------------------------ | ----------- | --------------------------------- |\n| **I-Chart** | **CHANGE** | \"What's shifting over time?\" |\n| **Boxplot** | **FLOW** | \"Where does variation come from?\" |\n| **Pareto** | **FAILURE** | \"Where do problems cluster?\" |\n| **Capability Histogram** | **VALUE** | \"Does it meet customer specs?\" |\n\nNo single lens tells the full story — you need all four to see clearly.\n\n[:octicons-arrow-right-24: Four Lenses](four-lenses/index.md)\n\n### Two Voices\n\nEvery process has two voices speaking at the same time:\n\n| Voice | What It Says | Expressed As |\n| ------------------------- | --------------------------------- | ------------------------------ |\n| **Voice of the Process** | \"This is what I actually produce\" | Control Limits (UCL/LCL) |\n| **Voice of the Customer** | \"This is what I need\" | Specification Limits (USL/LSL) |\n\nThe critical insight: These two voices are independent. The process doesn't know what the customer wants. The customer doesn't know what the process can do.\n\n[:octicons-arrow-right-24: Two Voices](two-voices/index.md)\n\n### Progressive Stratification\n\nThe conceptual bridge between VariScout's UI design and its statistical methodology. Why filter chips with contribution percentages, why one-factor-at-a-time drilling, and where the current design may be insufficient.\n\n[:octicons-arrow-right-24: Progressive Stratification](progressive-stratification.md)\n\n### Market Analysis & TAM\n\nTotal Addressable Market estimate across three segments: lightweight quality analytics, LSS training funnel, and Excel-native variation analysis.\n\n[:octicons-arrow-right-24: Market Analysis](market-analysis.md)\n\n### Design Evaluations\n\nProduct strategy evaluations for the 6 design tensions and 7 alternative patterns identified in Progressive Stratification. Each evaluation assesses fit against VariScout's philosophy, personas, and competitive positioning to inform roadmap decisions.\n\n[:octicons-arrow-right-24: Evaluations](evaluations/index.md)\n\n---\n\n## Target Audience\n\nVariScout is designed for practitioners who need to **find and act on variation sources quickly**:\n\n| Role | Primary Need | How VariScout Helps |\n| ----------------------- | ------------------------------------- | ------------------------------------- |\n| **Fresh Green Belts** | Apply LSS training to real data | Guided methodology, no Minitab needed |\n| **Operations Managers** | Quick answers, clear actions | Breadcrumb trail, cumulative % |\n| **Supervisors** | Identify which shift/machine/operator | Boxplot + linked filtering |\n| **Quality Teams** | Capability reporting, spec compliance | Cp/Cpk, pass/fail % |\n| **OpEx Teams** | Prioritize improvement projects | Pareto, variation contribution % |\n\n**What they DON'T need (initially):**\n\n- Complex predictive models\n- Response surface methodology\n- DOE analysis software\n\n**What they DO need:**\n\n- \"Where is the variation coming from?\" → Boxplot\n- \"Is it stable over time?\" → I-Chart\n- \"What defects matter most?\" → Pareto\n- \"Are we meeting specs?\" → Capability\n- \"Is there a relationship?\" → Regression (add-on)\n\n---\n\n## The System Dynamics\n\nThe four lenses don't work in isolation — they're meshed gears:\n\n```\n ┌─────────┐\n │ CHANGE │ ← Dynamic factor: wear, shifts, seasons\n │(I-Chart)│\n └────┬────┘\n │\n ▼\n┌─────────┐ ┌─────────┐\n│ FLOW │◄───►│ FAILURE │\n│(Boxplot)│ │(Pareto) │\n└────┬────┘ └────┬────┘\n │ │\n └───────┬───────┘\n │\n ▼\n ┌─────────┐\n │ VALUE │ ← Drive gear: if undefined, nothing turns correctly\n │(Capable)│\n └─────────┘\n```\n\n**Linked Filtering = Gear Meshing**\n\nWhen you click on one chart, all others respond. This isn't just a UI feature — it's how the lenses interconnect.\n\n---\n\n## References\n\nBased on:\n\n- Watson's Four Lenses of Process Knowledge\n- The Sock Mystery experiential exercise\n- ITC Quality Control principles\n- Shewhart's foundational work on control charts\n- Wheeler's \"Understanding Variation\"", + "src/content/docs/01-vision/index.md", + "efb4bff145181e1c", + { "html": 842, "metadata": 843 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"vision--methodology\">Vision & Methodology\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#vision--methodology\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Vision & Methodology”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is built on a philosophy of \u003Cstrong>EDA for process improvement\u003C/strong> — not statistical verification.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-philosophy\">The Philosophy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-philosophy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Philosophy”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Academic Statistician\u003C/th>\u003Cth>Process Improvement Practitioner\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Is this significant at p<0.05?\"\u003C/td>\u003Ctd>\"Where should I focus?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hypothesis testing\u003C/td>\u003Ctd>Pattern finding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Prove with math\u003C/td>\u003Ctd>See with eyes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Statistical correctness\u003C/td>\u003Ctd>Directional guidance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analysis as end goal\u003C/td>\u003Ctd>Analysis as starting point\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>The goal:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Find where to focus\u003C/li>\n\u003Cli>See where to apply Lean thinking\u003C/li>\n\u003Cli>Guide improvement effort\u003C/li>\n\u003Cli>Move fast, iterate, improve\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>The key insight:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>VaRiScout finds WHERE to focus. Apply Lean thinking to find WHY — and what to do about it.\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>The promise:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>46% of your variation may be hiding in one place. Find it. Fix it. Check it. Continue.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"deep-dives\">Deep Dives\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#deep-dives\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deep Dives”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"philosophy.md\">Philosophy\u003C/a> — The EDA-for-process-improvement philosophy that drives VariScout\u003C/li>\n\u003Cli>\u003Ca href=\"product-overview.md\">Product Overview\u003C/a> — High-level product positioning and capabilities\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-frameworks\">Core Frameworks\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-frameworks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Frameworks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"watsons-four-lenses-of-variation\">Watson’s Four Lenses of Variation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#watsons-four-lenses-of-variation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Watson’s Four Lenses of Variation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Watson’s Four Lenses give you four distinct perspectives — each revealing a different dimension of your process:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Lens\u003C/th>\u003Cth>What You See Through It\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>I-Chart\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>CHANGE\u003C/strong>\u003C/td>\u003Ctd>”What’s shifting over time?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Boxplot\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>FLOW\u003C/strong>\u003C/td>\u003Ctd>”Where does variation come from?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pareto\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>FAILURE\u003C/strong>\u003C/td>\u003Ctd>”Where do problems cluster?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Capability Histogram\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>VALUE\u003C/strong>\u003C/td>\u003Ctd>”Does it meet customer specs?”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>No single lens tells the full story — you need all four to see clearly.\u003C/p>\n\u003Cp>\u003Ca href=\"four-lenses/index.md\">:octicons-arrow-right-24: Four Lenses\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"two-voices\">Two Voices\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#two-voices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two Voices”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every process has two voices speaking at the same time:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Voice\u003C/th>\u003Cth>What It Says\u003C/th>\u003Cth>Expressed As\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Voice of the Process\u003C/strong>\u003C/td>\u003Ctd>”This is what I actually produce”\u003C/td>\u003Ctd>Control Limits (UCL/LCL)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Voice of the Customer\u003C/strong>\u003C/td>\u003Ctd>”This is what I need”\u003C/td>\u003Ctd>Specification Limits (USL/LSL)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The critical insight: These two voices are independent. The process doesn’t know what the customer wants. The customer doesn’t know what the process can do.\u003C/p>\n\u003Cp>\u003Ca href=\"two-voices/index.md\">:octicons-arrow-right-24: Two Voices\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"progressive-stratification\">Progressive Stratification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#progressive-stratification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Progressive Stratification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The conceptual bridge between VariScout’s UI design and its statistical methodology. Why filter chips with contribution percentages, why one-factor-at-a-time drilling, and where the current design may be insufficient.\u003C/p>\n\u003Cp>\u003Ca href=\"progressive-stratification.md\">:octicons-arrow-right-24: Progressive Stratification\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"market-analysis--tam\">Market Analysis & TAM\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#market-analysis--tam\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Market Analysis & TAM”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Total Addressable Market estimate across three segments: lightweight quality analytics, LSS training funnel, and Excel-native variation analysis.\u003C/p>\n\u003Cp>\u003Ca href=\"market-analysis.md\">:octicons-arrow-right-24: Market Analysis\u003C/a>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"design-evaluations\">Design Evaluations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#design-evaluations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Evaluations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Product strategy evaluations for the 6 design tensions and 7 alternative patterns identified in Progressive Stratification. Each evaluation assesses fit against VariScout’s philosophy, personas, and competitive positioning to inform roadmap decisions.\u003C/p>\n\u003Cp>\u003Ca href=\"evaluations/index.md\">:octicons-arrow-right-24: Evaluations\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-audience\">Target Audience\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-audience\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Audience”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is designed for practitioners who need to \u003Cstrong>find and act on variation sources quickly\u003C/strong>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Primary Need\u003C/th>\u003Cth>How VariScout Helps\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Fresh Green Belts\u003C/strong>\u003C/td>\u003Ctd>Apply LSS training to real data\u003C/td>\u003Ctd>Guided methodology, no Minitab needed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Operations Managers\u003C/strong>\u003C/td>\u003Ctd>Quick answers, clear actions\u003C/td>\u003Ctd>Breadcrumb trail, cumulative %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Supervisors\u003C/strong>\u003C/td>\u003Ctd>Identify which shift/machine/operator\u003C/td>\u003Ctd>Boxplot + linked filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Quality Teams\u003C/strong>\u003C/td>\u003Ctd>Capability reporting, spec compliance\u003C/td>\u003Ctd>Cp/Cpk, pass/fail %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>OpEx Teams\u003C/strong>\u003C/td>\u003Ctd>Prioritize improvement projects\u003C/td>\u003Ctd>Pareto, variation contribution %\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>What they DON’T need (initially):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Complex predictive models\u003C/li>\n\u003Cli>Response surface methodology\u003C/li>\n\u003Cli>DOE analysis software\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>What they DO need:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“Where is the variation coming from?” → Boxplot\u003C/li>\n\u003Cli>“Is it stable over time?” → I-Chart\u003C/li>\n\u003Cli>“What defects matter most?” → Pareto\u003C/li>\n\u003Cli>“Are we meeting specs?” → Capability\u003C/li>\n\u003Cli>“Is there a relationship?” → Regression (add-on)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-system-dynamics\">The System Dynamics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-system-dynamics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The System Dynamics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The four lenses don’t work in isolation — they’re meshed gears:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CHANGE │ ← Dynamic factor: wear, shifts, seasons\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│(I-Chart)│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────┬────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────┐ ┌─────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ FLOW │◄───►│ FAILURE │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│(Boxplot)│ │(Pareto) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────┬────┘ └────┬────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───────┬───────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ VALUE │ ← Drive gear: if undefined, nothing turns correctly\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│(Capable)│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" ┌─────────┐ │ CHANGE │ ← Dynamic factor: wear, shifts, seasons │(I-Chart)│ └────┬────┘ │ ▼┌─────────┐ ┌─────────┐│ FLOW │◄───►│ FAILURE ││(Boxplot)│ │(Pareto) │└────┬────┘ └────┬────┘ │ │ └───────┬───────┘ │ ▼ ┌─────────┐ │ VALUE │ ← Drive gear: if undefined, nothing turns correctly │(Capable)│ └─────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Linked Filtering = Gear Meshing\u003C/strong>\u003C/p>\n\u003Cp>When you click on one chart, all others respond. This isn’t just a UI feature — it’s how the lenses interconnect.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"references\">References\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Based on:\u003C/p>\n\u003Cul>\n\u003Cli>Watson’s Four Lenses of Process Knowledge\u003C/li>\n\u003Cli>The Sock Mystery experiential exercise\u003C/li>\n\u003Cli>ITC Quality Control principles\u003C/li>\n\u003Cli>Shewhart’s foundational work on control charts\u003C/li>\n\u003Cli>Wheeler’s “Understanding Variation”\u003C/li>\n\u003C/ul>", + { + "headings": 844, + "localImagePaths": 880, + "remoteImagePaths": 881, + "frontmatter": 882, + "imagePaths": 883 + }, + [845, 847, 850, 853, 856, 859, 862, 865, 868, 871, 874, 877], + { "depth": 30, "slug": 846, "text": 834 }, + "vision--methodology", + { "depth": 33, "slug": 848, "text": 849 }, + "the-philosophy", + "The Philosophy", + { "depth": 33, "slug": 851, "text": 852 }, + "deep-dives", + "Deep Dives", + { "depth": 33, "slug": 854, "text": 855 }, + "core-frameworks", + "Core Frameworks", + { "depth": 79, "slug": 857, "text": 858 }, + "watsons-four-lenses-of-variation", + "Watson’s Four Lenses of Variation", + { "depth": 79, "slug": 860, "text": 861 }, + "two-voices", + "Two Voices", + { "depth": 79, "slug": 863, "text": 864 }, + "progressive-stratification", + "Progressive Stratification", + { "depth": 79, "slug": 866, "text": 867 }, + "market-analysis--tam", + "Market Analysis & TAM", + { "depth": 79, "slug": 869, "text": 870 }, + "design-evaluations", + "Design Evaluations", + { "depth": 33, "slug": 872, "text": 873 }, + "target-audience", + "Target Audience", + { "depth": 33, "slug": 875, "text": 876 }, + "the-system-dynamics", + "The System Dynamics", + { "depth": 33, "slug": 878, "text": 879 }, + "references", + "References", + [], + [], + { "title": 834 }, + [], + "02-journeys", + { "id": 884, "data": 886, "body": 891, "filePath": 892, "digest": 893, "rendered": 894 }, + { + "title": 887, + "editUrl": 16, + "head": 888, + "template": 18, + "sidebar": 889, + "pagefind": 16, + "draft": 20 + }, + "User Journeys", + [], + { "hidden": 20, "attrs": 890 }, + {}, + "# User Journeys\n\nHow different users find, navigate, and convert on VariScout.\n\n---\n\n## Personas\n\n| Persona | Role | Goal | Entry Point |\n| -------------------------------------------------- | ------------------------------ | ---------------------------- | -------------------------- |\n| [**Green Belt Gary**](personas/green-belt-gary.md) | Quality Engineer, GB certified | Find better tools than Excel | Google, LinkedIn, YouTube |\n| [**Curious Carlos**](personas/curious-carlos.md) | Operations Supervisor | Understand variation better | YouTube, TikTok, Instagram |\n| [**OpEx Olivia**](personas/opex-olivia.md) | OpEx Manager | Find tools for team | Referral, LinkedIn |\n| [**Student Sara**](personas/student-sara.md) | LSS student / trainee | Learn methodology | Course link, Google |\n| [**Evaluator Erik**](personas/evaluator-erik.md) | IT/Procurement | Assess for organization | Direct link from colleague |\n| [**Trainer Tina**](personas/trainer-tina.md) | LSS Trainer / Consultant | Tools for courses & clients | LinkedIn, YouTube |\n| [**Field Fiona**](personas/field-fiona.md) | Field Quality Engineer | Review charts on the go | Teams mobile app |\n\n**Secondary personas:** Consultant Chris, Academic Anna, Coffee Coop Carmen\n\n---\n\n## UX Research\n\nFoundational user research informing persona development and flow design:\n\n[:octicons-arrow-right-24: UX Research](ux-research.md)\n\n---\n\n## Use Cases\n\nStrategic use cases grounded in VariScout's capabilities — the specific problems that bring searchers in.\n\n| # | Use Case | SEO Score | Industry | Theme |\n| --- | --------------------------------------------------------------- | --------- | --------------------- | ------------------- |\n| 1 | [Supplier Performance](use-cases/supplier-performance.md) | 24 | Supply Chain | Drill-down |\n| 2 | [University SPC](use-cases/university-spc.md) | 24 | Education | Education |\n| 3 | [Assembly Bottleneck](use-cases/bottleneck-analysis.md) | 22 | Manufacturing | Aggregation trap |\n| 4 | [Supplier PPAP](use-cases/supplier-ppap.md) | 22 | Automotive | Multi-channel |\n| 5 | [COPQ Drill-Down](use-cases/copq-drilldown.md) | 21 | Cross-industry | Drill-down |\n| 6 | [Customer Complaint](use-cases/complaint-investigation.md) | 21 | Cross-industry | Investigation |\n| 7 | [Patient Wait Time](use-cases/patient-wait-time.md) | 18 | Healthcare | Aggregation trap |\n| 8 | [Call Center Performance](use-cases/call-center-performance.md) | 18 | Service Ops | Drill-down |\n| 9 | [On-Time Delivery](use-cases/on-time-delivery.md) | 15 | Logistics | Capability vs SLA |\n| 10 | [Pharma OOS](use-cases/pharma-oos.md) | 19 | Pharma | MSA + Investigation |\n| 11 | [Consultant Delivery](use-cases/consultant-delivery.md) | 17 | Professional Services | Education |\n| 12 | [Batch Consistency](use-cases/batch-consistency.md) | 18 | Food / Chemical | Drill-down |\n| 13 | [Lead Time Variation](use-cases/lead-time-variation.md) | 19 | Supply Chain | Aggregation trap |\n\nSee [use-cases/index.md](use-cases/index.md) for full SEO scoring, theme groupings, and content phasing.\n\n---\n\n## Entry Points\n\n### Flow Interconnection Diagram\n\n```mermaid\nflowchart TB\n subgraph Sources[\"Traffic Sources\"]\n G[Google Search]\n L[LinkedIn]\n Y[YouTube / Social]\n R[Referral]\n D[Direct URL]\n end\n\n subgraph Landing[\"Landing Pages\"]\n T[/tools/X]\n H[/ Homepage]\n C[/cases/X]\n B[/blog/X]\n A[/app]\n end\n\n subgraph Flows[\"User Flows\"]\n F1[SEO Learner]\n F2[Social Discovery]\n F3[Content/YouTube]\n F4[Enterprise]\n F5[Return Visitor]\n end\n\n subgraph Conversion[\"Conversion\"]\n PR[/pricing]\n AZ[Azure Marketplace]\n end\n\n subgraph InApp[\"In-App Flows\"]\n F6[First Analysis]\n F7[Daily Use]\n F8[Team Collaboration]\n end\n\n G --> T\n G --> H\n L --> H\n L --> C\n Y --> B\n Y --> T\n R --> H\n D --> H\n D --> A\n\n T --> F1\n C --> F2\n B --> F3\n H --> F4\n A --> F5\n\n F1 --> PR\n F2 --> PR\n F3 --> PR\n F4 --> PR\n F5 --> A\n\n PR --> AZ\n\n AZ --> F6\n F6 --> F7\n F7 --> F8\n F5 -.->|upgrade| PR\n```\n\n### Entry Point Matrix\n\n```mermaid\nflowchart LR\n subgraph Entry[\"Entry Points\"]\n direction TB\n E1[Google → Tool Page]\n E2[LinkedIn → Case/Home]\n E3[YouTube → Blog/Tool]\n E4[Referral → Homepage]\n E5[Direct → /app]\n end\n\n subgraph First[\"First Question\"]\n direction TB\n Q1[Does this answer my question?]\n Q2[Is this relevant to me?]\n Q3[Is there more?]\n Q4[What is this?]\n Q5[Where was I?]\n end\n\n E1 --> Q1\n E2 --> Q2\n E3 --> Q3\n E4 --> Q4\n E5 --> Q5\n```\n\n### ASCII Reference\n\n```\n ┌─────────────────┐\n │ variscout.com │\n └────────┬────────┘\n │\n ┌────────────────┬───────────────────┼───────────────────┬────────────────┐\n │ │ │ │ │\n ▼ ▼ ▼ ▼ ▼\n┌───────────┐ ┌───────────┐ ┌───────────────┐ ┌───────────┐ ┌───────────┐\n│ Google │ │ LinkedIn │ │ YouTube / │ │ Referral │ │ Direct │\n│ Search │ │ │ │ Social │ │ │ │ URL │\n└─────┬─────┘ └─────┬─────┘ └───────┬───────┘ └─────┬─────┘ └─────┬─────┘\n │ │ │ │ │\n ▼ ▼ ▼ ▼ ▼\n┌───────────┐ ┌───────────┐ ┌───────────────┐ ┌───────────┐ ┌───────────┐\n│ Tool Page │ │ Homepage │ │ Blog / Tool │ │ Homepage │ │ Homepage │\n│ /tools/X │ │ / │ │ Page │ │ / │ │ or /app │\n└───────────┘ └───────────┘ └───────────────┘ └───────────┘ └───────────┘\n```\n\n### First Impression by Entry\n\n| Entry Point | Lands On | First Question | Must Answer in 5 Seconds |\n| ---------------------------- | ------------------- | ------------------------------- | ------------------------------- |\n| Google \"how to read boxplot\" | /tools/boxplot | \"Does this answer my question?\" | Yes - with visual + explanation |\n| LinkedIn post about case | /cases/bottleneck | \"Is this relevant to me?\" | Yes - industry recognition |\n| YouTube video link | /blog/X or /tools/X | \"Is there more?\" | Yes - deeper content + CTA |\n| TikTok/Instagram clip | /tools/X or / | \"What is this tool?\" | Clear value prop + demo |\n| Colleague referral | / (homepage) | \"What is this?\" | Clear value prop + demo |\n| Return visit | / or /app | \"Where was I?\" | Easy navigation to app/cases |\n\n---\n\n## User Flows\n\n\u003Cdiv class=\"grid cards\" markdown>\n\n- :material-magnify:{ .lg .middle } **SEO Learner**\n\n ***\n\n Google search → Tool page → Product\n\n [:octicons-arrow-right-24: Flow details](flows/seo-learner.md)\n\n- :material-share-variant:{ .lg .middle } **Social Discovery**\n\n ***\n\n LinkedIn → Case → Product\n\n [:octicons-arrow-right-24: Flow details](flows/social-discovery.md)\n\n- :material-youtube:{ .lg .middle } **Content & YouTube**\n\n ***\n\n YouTube/Content → Website → Product\n\n [:octicons-arrow-right-24: Flow details](flows/content-youtube.md)\n\n- :material-domain:{ .lg .middle } **Enterprise**\n\n ***\n\n Referral → Enterprise evaluation\n\n [:octicons-arrow-right-24: Flow details](flows/enterprise.md)\n\n- :material-redo:{ .lg .middle } **Return Visitor**\n\n ***\n\n Existing user → App\n\n [:octicons-arrow-right-24: Flow details](flows/return-visitor.md)\n\n- :material-rocket-launch:{ .lg .middle } **Azure First Analysis**\n\n ***\n\n First login → first saved analysis\n\n [:octicons-arrow-right-24: Flow details](flows/azure-first-analysis.md)\n\n- :material-chart-line:{ .lg .middle } **Azure Daily Use**\n\n ***\n\n Repeat analysis, Performance Mode, exports\n\n [:octicons-arrow-right-24: Flow details](flows/azure-daily-use.md)\n\n- :material-account-group:{ .lg .middle } **Azure Team Collaboration**\n\n ***\n\n Admin deployment, sharing, Teams integration\n\n [:octicons-arrow-right-24: Flow details](flows/azure-team-collaboration.md)\n\n- :material-cellphone:{ .lg .middle } **Azure Teams Mobile**\n\n ***\n\n Phone carousel, overflow menu, shop floor review\n\n [:octicons-arrow-right-24: Flow details](flows/azure-teams-mobile.md)\n\n\u003C/div>\n\n---\n\n## Flow Priorities\n\n| Priority | Flow | Why |\n| -------- | ------------------------- | ------------------------------- |\n| 1 | SEO → Tool Page → Product | Highest volume potential |\n| 2 | Social → Case → Product | Best conversion story |\n| 3 | YouTube/Content → Website | Authority + warm leads |\n| 4 | Enterprise evaluation | Self-serve, documentation-first |\n| 5 | Return user → App | Retention/activation |\n| 6 | Azure first analysis | Activation (first value moment) |\n| 7 | Azure daily use | Retention (ongoing value) |\n| 8 | Azure team collaboration | Expansion (team adoption) |\n\n---\n\n## Cross-Linking Strategy\n\n### Content Interconnections\n\n```mermaid\nflowchart TB\n subgraph Content[\"Content Sections\"]\n H[Homepage]\n J[Journey]\n C[Cases]\n T[Tools]\n L[Learn]\n end\n\n subgraph Conversion[\"Conversion Path\"]\n PR[Pricing]\n AZ[CONVERSION]\n end\n\n H --> J\n H --> C\n H --> T\n\n J \u003C-->|same methodology| C\n C \u003C-->|tool used in case| T\n T \u003C-->|deeper concepts| L\n T \u003C-->|workflow: I-Chart→Box| T\n\n J --> PR\n C --> PR\n T --> PR\n L --> PR\n\n PR --> AZ\n```\n\n### Cross-Link Rules\n\n| From | Links To | Connection Type |\n| ------------ | -------- | -------------------------- |\n| Journey | Cases | Same methodology in action |\n| Cases | Tools | Tool used in the case |\n| Tools | Learn | Deeper concept explanation |\n| Tools | Tools | Workflow progression |\n| All sections | Pricing | CTA on every page |\n\n### ASCII Reference\n\n```\n ┌─────────────┐\n │ Homepage │\n └──────┬──────┘\n │\n ┌────────────────┼────────────────┐\n │ │ │\n ▼ ▼ ▼\n┌───────────┐ ┌───────────┐ ┌───────────┐\n│ Journey │ │ Cases │ │ Tools │\n└─────┬─────┘ └─────┬─────┘ └─────┬─────┘\n │ │ │\n └────────────────┼────────────────┘\n │\n CROSS-LINKS:\n Journey ←→ Cases (same methodology)\n Cases ←→ Tools (tool used in case)\n Tools ←→ Learn (deeper concepts)\n Tools ←→ Tools (workflow: I-Chart→Box)\n All ──→ Pricing (CTA)\n │\n ▼\n ┌─────────────┐\n │ Pricing │ → CONVERSION\n └─────────────┘\n```\n\n---\n\n## Architecture Principles\n\n1. **Multiple entry points** — Every page can be a landing page\n2. **Clear paths to conversion** — CTA on every page\n3. **Cross-linking** — No dead ends, always \"what's next\"\n4. **Progressive depth** — Surface → Middle → Deep layers\n5. **Mobile-first** — Sticky CTAs, simplified navigation\n6. **No login needed** — PWA works without accounts, data stays in your browser\n\n> **The website is a collection of interconnected experiences, not a linear funnel.**\n>\n> Users can enter anywhere, explore in any order, and convert when ready.\n> Every page must stand alone AND connect to the whole.", + "src/content/docs/02-journeys/index.md", + "c0aa32dc8d31ee7e", + { "html": 895, "metadata": 896 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"user-journeys\">User Journeys\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#user-journeys\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Journeys”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How different users find, navigate, and convert on VariScout.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"personas\">Personas\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#personas\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Personas”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Role\u003C/th>\u003Cth>Goal\u003C/th>\u003Cth>Entry Point\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"personas/green-belt-gary.md\">\u003Cstrong>Green Belt Gary\u003C/strong>\u003C/a>\u003C/td>\u003Ctd>Quality Engineer, GB certified\u003C/td>\u003Ctd>Find better tools than Excel\u003C/td>\u003Ctd>Google, LinkedIn, YouTube\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"personas/curious-carlos.md\">\u003Cstrong>Curious Carlos\u003C/strong>\u003C/a>\u003C/td>\u003Ctd>Operations Supervisor\u003C/td>\u003Ctd>Understand variation better\u003C/td>\u003Ctd>YouTube, TikTok, Instagram\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"personas/opex-olivia.md\">\u003Cstrong>OpEx Olivia\u003C/strong>\u003C/a>\u003C/td>\u003Ctd>OpEx Manager\u003C/td>\u003Ctd>Find tools for team\u003C/td>\u003Ctd>Referral, LinkedIn\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"personas/student-sara.md\">\u003Cstrong>Student Sara\u003C/strong>\u003C/a>\u003C/td>\u003Ctd>LSS student / trainee\u003C/td>\u003Ctd>Learn methodology\u003C/td>\u003Ctd>Course link, Google\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"personas/evaluator-erik.md\">\u003Cstrong>Evaluator Erik\u003C/strong>\u003C/a>\u003C/td>\u003Ctd>IT/Procurement\u003C/td>\u003Ctd>Assess for organization\u003C/td>\u003Ctd>Direct link from colleague\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"personas/trainer-tina.md\">\u003Cstrong>Trainer Tina\u003C/strong>\u003C/a>\u003C/td>\u003Ctd>LSS Trainer / Consultant\u003C/td>\u003Ctd>Tools for courses & clients\u003C/td>\u003Ctd>LinkedIn, YouTube\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"personas/field-fiona.md\">\u003Cstrong>Field Fiona\u003C/strong>\u003C/a>\u003C/td>\u003Ctd>Field Quality Engineer\u003C/td>\u003Ctd>Review charts on the go\u003C/td>\u003Ctd>Teams mobile app\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Secondary personas:\u003C/strong> Consultant Chris, Academic Anna, Coffee Coop Carmen\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ux-research\">UX Research\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ux-research\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “UX Research”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Foundational user research informing persona development and flow design:\u003C/p>\n\u003Cp>\u003Ca href=\"ux-research.md\">:octicons-arrow-right-24: UX Research\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"use-cases\">Use Cases\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#use-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Cases”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Strategic use cases grounded in VariScout’s capabilities — the specific problems that bring searchers in.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Use Case\u003C/th>\u003Cth>SEO Score\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Theme\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/supplier-performance.md\">Supplier Performance\u003C/a>\u003C/td>\u003Ctd>24\u003C/td>\u003Ctd>Supply Chain\u003C/td>\u003Ctd>Drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/university-spc.md\">University SPC\u003C/a>\u003C/td>\u003Ctd>24\u003C/td>\u003Ctd>Education\u003C/td>\u003Ctd>Education\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/bottleneck-analysis.md\">Assembly Bottleneck\u003C/a>\u003C/td>\u003Ctd>22\u003C/td>\u003Ctd>Manufacturing\u003C/td>\u003Ctd>Aggregation trap\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/supplier-ppap.md\">Supplier PPAP\u003C/a>\u003C/td>\u003Ctd>22\u003C/td>\u003Ctd>Automotive\u003C/td>\u003Ctd>Multi-channel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/copq-drilldown.md\">COPQ Drill-Down\u003C/a>\u003C/td>\u003Ctd>21\u003C/td>\u003Ctd>Cross-industry\u003C/td>\u003Ctd>Drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/complaint-investigation.md\">Customer Complaint\u003C/a>\u003C/td>\u003Ctd>21\u003C/td>\u003Ctd>Cross-industry\u003C/td>\u003Ctd>Investigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/patient-wait-time.md\">Patient Wait Time\u003C/a>\u003C/td>\u003Ctd>18\u003C/td>\u003Ctd>Healthcare\u003C/td>\u003Ctd>Aggregation trap\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/call-center-performance.md\">Call Center Performance\u003C/a>\u003C/td>\u003Ctd>18\u003C/td>\u003Ctd>Service Ops\u003C/td>\u003Ctd>Drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/on-time-delivery.md\">On-Time Delivery\u003C/a>\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Logistics\u003C/td>\u003Ctd>Capability vs SLA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/pharma-oos.md\">Pharma OOS\u003C/a>\u003C/td>\u003Ctd>19\u003C/td>\u003Ctd>Pharma\u003C/td>\u003Ctd>MSA + Investigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/consultant-delivery.md\">Consultant Delivery\u003C/a>\u003C/td>\u003Ctd>17\u003C/td>\u003Ctd>Professional Services\u003C/td>\u003Ctd>Education\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/batch-consistency.md\">Batch Consistency\u003C/a>\u003C/td>\u003Ctd>18\u003C/td>\u003Ctd>Food / Chemical\u003C/td>\u003Ctd>Drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>13\u003C/td>\u003Ctd>\u003Ca href=\"use-cases/lead-time-variation.md\">Lead Time Variation\u003C/a>\u003C/td>\u003Ctd>19\u003C/td>\u003Ctd>Supply Chain\u003C/td>\u003Ctd>Aggregation trap\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"use-cases/index.md\">use-cases/index.md\u003C/a> for full SEO scoring, theme groupings, and content phasing.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"flow-interconnection-diagram\">Flow Interconnection Diagram\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#flow-interconnection-diagram\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow Interconnection Diagram”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph Sources[\"Traffic Sources\"]\n G[Google Search]\n L[LinkedIn]\n Y[YouTube / Social]\n R[Referral]\n D[Direct URL]\n end\n\n subgraph Landing[\"Landing Pages\"]\n T[/tools/X]\n H[/ Homepage]\n C[/cases/X]\n B[/blog/X]\n A[/app]\n end\n\n subgraph Flows[\"User Flows\"]\n F1[SEO Learner]\n F2[Social Discovery]\n F3[Content/YouTube]\n F4[Enterprise]\n F5[Return Visitor]\n end\n\n subgraph Conversion[\"Conversion\"]\n PR[/pricing]\n AZ[Azure Marketplace]\n end\n\n subgraph InApp[\"In-App Flows\"]\n F6[First Analysis]\n F7[Daily Use]\n F8[Team Collaboration]\n end\n\n G --> T\n G --> H\n L --> H\n L --> C\n Y --> B\n Y --> T\n R --> H\n D --> H\n D --> A\n\n T --> F1\n C --> F2\n B --> F3\n H --> F4\n A --> F5\n\n F1 --> PR\n F2 --> PR\n F3 --> PR\n F4 --> PR\n F5 --> A\n\n PR --> AZ\n\n AZ --> F6\n F6 --> F7\n F7 --> F8\n F5 -.->|upgrade| PR\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"entry-point-matrix\">Entry Point Matrix\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#entry-point-matrix\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Point Matrix”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n subgraph Entry[\"Entry Points\"]\n direction TB\n E1[Google → Tool Page]\n E2[LinkedIn → Case/Home]\n E3[YouTube → Blog/Tool]\n E4[Referral → Homepage]\n E5[Direct → /app]\n end\n\n subgraph First[\"First Question\"]\n direction TB\n Q1[Does this answer my question?]\n Q2[Is this relevant to me?]\n Q3[Is there more?]\n Q4[What is this?]\n Q5[Where was I?]\n end\n\n E1 --> Q1\n E2 --> Q2\n E3 --> Q3\n E4 --> Q4\n E5 --> Q5\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ascii-reference\">ASCII Reference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ascii-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ASCII Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ variscout.com │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────┬───────────────────┼───────────────────┬────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼ ▼ ▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌───────────┐ ┌───────────┐ ┌───────────────┐ ┌───────────┐ ┌───────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Google │ │ LinkedIn │ │ YouTube / │ │ Referral │ │ Direct │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Search │ │ │ │ Social │ │ │ │ URL │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────┬─────┘ └─────┬─────┘ └───────┬───────┘ └─────┬─────┘ └─────┬─────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼ ▼ ▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌───────────┐ ┌───────────┐ ┌───────────────┐ ┌───────────┐ ┌───────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Tool Page │ │ Homepage │ │ Blog / Tool │ │ Homepage │ │ Homepage │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /tools/X │ │ / │ │ Page │ │ / │ │ or /app │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───────────┘ └───────────┘ └───────────────┘ └───────────┘ └───────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" ┌─────────────────┐ │ variscout.com │ └────────┬────────┘ │ ┌────────────────┬───────────────────┼───────────────────┬────────────────┐ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼┌───────────┐ ┌───────────┐ ┌───────────────┐ ┌───────────┐ ┌───────────┐│ Google │ │ LinkedIn │ │ YouTube / │ │ Referral │ │ Direct ││ Search │ │ │ │ Social │ │ │ │ URL │└─────┬─────┘ └─────┬─────┘ └───────┬───────┘ └─────┬─────┘ └─────┬─────┘ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼┌───────────┐ ┌───────────┐ ┌───────────────┐ ┌───────────┐ ┌───────────┐│ Tool Page │ │ Homepage │ │ Blog / Tool │ │ Homepage │ │ Homepage ││ /tools/X │ │ / │ │ Page │ │ / │ │ or /app │└───────────┘ └───────────┘ └───────────────┘ └───────────┘ └───────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"first-impression-by-entry\">First Impression by Entry\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#first-impression-by-entry\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “First Impression by Entry”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Entry Point\u003C/th>\u003Cth>Lands On\u003C/th>\u003Cth>First Question\u003C/th>\u003Cth>Must Answer in 5 Seconds\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Google “how to read boxplot”\u003C/td>\u003Ctd>/tools/boxplot\u003C/td>\u003Ctd>”Does this answer my question?”\u003C/td>\u003Ctd>Yes - with visual + explanation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LinkedIn post about case\u003C/td>\u003Ctd>/cases/bottleneck\u003C/td>\u003Ctd>”Is this relevant to me?”\u003C/td>\u003Ctd>Yes - industry recognition\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>YouTube video link\u003C/td>\u003Ctd>/blog/X or /tools/X\u003C/td>\u003Ctd>”Is there more?”\u003C/td>\u003Ctd>Yes - deeper content + CTA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>TikTok/Instagram clip\u003C/td>\u003Ctd>/tools/X or /\u003C/td>\u003Ctd>“What is this tool?”\u003C/td>\u003Ctd>Clear value prop + demo\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Colleague referral\u003C/td>\u003Ctd>/ (homepage)\u003C/td>\u003Ctd>“What is this?”\u003C/td>\u003Ctd>Clear value prop + demo\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Return visit\u003C/td>\u003Ctd>/ or /app\u003C/td>\u003Ctd>”Where was I?”\u003C/td>\u003Ctd>Easy navigation to app/cases\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"user-flows\">User Flows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#user-flows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Flows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"grid cards\" markdown=\"\">\n\u003Cul>\n\u003Cli>\n\u003Cp>:material-magnify:{ .lg .middle } \u003Cstrong>SEO Learner\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>Google search → Tool page → Product\u003C/p>\n\u003Cp>\u003Ca href=\"flows/seo-learner.md\">:octicons-arrow-right-24: Flow details\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-share-variant:{ .lg .middle } \u003Cstrong>Social Discovery\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>LinkedIn → Case → Product\u003C/p>\n\u003Cp>\u003Ca href=\"flows/social-discovery.md\">:octicons-arrow-right-24: Flow details\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-youtube:{ .lg .middle } \u003Cstrong>Content & YouTube\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>YouTube/Content → Website → Product\u003C/p>\n\u003Cp>\u003Ca href=\"flows/content-youtube.md\">:octicons-arrow-right-24: Flow details\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-domain:{ .lg .middle } \u003Cstrong>Enterprise\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>Referral → Enterprise evaluation\u003C/p>\n\u003Cp>\u003Ca href=\"flows/enterprise.md\">:octicons-arrow-right-24: Flow details\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-redo:{ .lg .middle } \u003Cstrong>Return Visitor\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>Existing user → App\u003C/p>\n\u003Cp>\u003Ca href=\"flows/return-visitor.md\">:octicons-arrow-right-24: Flow details\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-rocket-launch:{ .lg .middle } \u003Cstrong>Azure First Analysis\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>First login → first saved analysis\u003C/p>\n\u003Cp>\u003Ca href=\"flows/azure-first-analysis.md\">:octicons-arrow-right-24: Flow details\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-chart-line:{ .lg .middle } \u003Cstrong>Azure Daily Use\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>Repeat analysis, Performance Mode, exports\u003C/p>\n\u003Cp>\u003Ca href=\"flows/azure-daily-use.md\">:octicons-arrow-right-24: Flow details\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-account-group:{ .lg .middle } \u003Cstrong>Azure Team Collaboration\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>Admin deployment, sharing, Teams integration\u003C/p>\n\u003Cp>\u003Ca href=\"flows/azure-team-collaboration.md\">:octicons-arrow-right-24: Flow details\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-cellphone:{ .lg .middle } \u003Cstrong>Azure Teams Mobile\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>Phone carousel, overflow menu, shop floor review\u003C/p>\n\u003Cp>\u003Ca href=\"flows/azure-teams-mobile.md\">:octicons-arrow-right-24: Flow details\u003C/a>\u003C/p>\n\u003C/li>\n\u003C/ul>\n\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"flow-priorities\">Flow Priorities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#flow-priorities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow Priorities”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Priority\u003C/th>\u003Cth>Flow\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>SEO → Tool Page → Product\u003C/td>\u003Ctd>Highest volume potential\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Social → Case → Product\u003C/td>\u003Ctd>Best conversion story\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>YouTube/Content → Website\u003C/td>\u003Ctd>Authority + warm leads\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Enterprise evaluation\u003C/td>\u003Ctd>Self-serve, documentation-first\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Return user → App\u003C/td>\u003Ctd>Retention/activation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Azure first analysis\u003C/td>\u003Ctd>Activation (first value moment)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>Azure daily use\u003C/td>\u003Ctd>Retention (ongoing value)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>Azure team collaboration\u003C/td>\u003Ctd>Expansion (team adoption)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-linking-strategy\">Cross-Linking Strategy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-linking-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Linking Strategy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"content-interconnections\">Content Interconnections\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#content-interconnections\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Content Interconnections”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph Content[\"Content Sections\"]\n H[Homepage]\n J[Journey]\n C[Cases]\n T[Tools]\n L[Learn]\n end\n\n subgraph Conversion[\"Conversion Path\"]\n PR[Pricing]\n AZ[CONVERSION]\n end\n\n H --> J\n H --> C\n H --> T\n\n J <-->|same methodology| C\n C <-->|tool used in case| T\n T <-->|deeper concepts| L\n T <-->|workflow: I-Chart→Box| T\n\n J --> PR\n C --> PR\n T --> PR\n L --> PR\n\n PR --> AZ\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cross-link-rules\">Cross-Link Rules\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cross-link-rules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Link Rules”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>From\u003C/th>\u003Cth>Links To\u003C/th>\u003Cth>Connection Type\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Journey\u003C/td>\u003Ctd>Cases\u003C/td>\u003Ctd>Same methodology in action\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cases\u003C/td>\u003Ctd>Tools\u003C/td>\u003Ctd>Tool used in the case\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tools\u003C/td>\u003Ctd>Learn\u003C/td>\u003Ctd>Deeper concept explanation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tools\u003C/td>\u003Ctd>Tools\u003C/td>\u003Ctd>Workflow progression\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>All sections\u003C/td>\u003Ctd>Pricing\u003C/td>\u003Ctd>CTA on every page\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ascii-reference-1\">ASCII Reference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ascii-reference-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ASCII Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Homepage │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────┬──────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────┼────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌───────────┐ ┌───────────┐ ┌───────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Journey │ │ Cases │ │ Tools │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────┬─────┘ └─────┬─────┘ └─────┬─────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────────┼────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CROSS-LINKS:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Journey ←→ Cases (same methodology)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cases ←→ Tools (tool used in case)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Tools ←→ Learn (deeper concepts)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Tools ←→ Tools (workflow: I-Chart→Box)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">All ──→ Pricing (CTA)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Pricing │ → CONVERSION\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" ┌─────────────┐ │ Homepage │ └──────┬──────┘ │ ┌────────────────┼────────────────┐ │ │ │ ▼ ▼ ▼┌───────────┐ ┌───────────┐ ┌───────────┐│ Journey │ │ Cases │ │ Tools │└─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │ │ │ └────────────────┼────────────────┘ │ CROSS-LINKS: Journey ←→ Cases (same methodology) Cases ←→ Tools (tool used in case) Tools ←→ Learn (deeper concepts) Tools ←→ Tools (workflow: I-Chart→Box) All ──→ Pricing (CTA) │ ▼ ┌─────────────┐ │ Pricing │ → CONVERSION └─────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"architecture-principles\">Architecture Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#architecture-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Multiple entry points\u003C/strong> — Every page can be a landing page\u003C/li>\n\u003Cli>\u003Cstrong>Clear paths to conversion\u003C/strong> — CTA on every page\u003C/li>\n\u003Cli>\u003Cstrong>Cross-linking\u003C/strong> — No dead ends, always “what’s next”\u003C/li>\n\u003Cli>\u003Cstrong>Progressive depth\u003C/strong> — Surface → Middle → Deep layers\u003C/li>\n\u003Cli>\u003Cstrong>Mobile-first\u003C/strong> — Sticky CTAs, simplified navigation\u003C/li>\n\u003Cli>\u003Cstrong>No login needed\u003C/strong> — PWA works without accounts, data stays in your browser\u003C/li>\n\u003C/ol>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>The website is a collection of interconnected experiences, not a linear funnel.\u003C/strong>\u003C/p>\n\u003Cp>Users can enter anywhere, explore in any order, and convert when ready.\nEvery page must stand alone AND connect to the whole.\u003C/p>\n\u003C/blockquote>", + { + "headings": 897, + "localImagePaths": 944, + "remoteImagePaths": 945, + "frontmatter": 946, + "imagePaths": 947 + }, + [898, 900, 903, 906, 909, 912, 915, 918, 921, 924, 927, 930, 933, 936, 939, 941], + { "depth": 30, "slug": 899, "text": 887 }, + "user-journeys", + { "depth": 33, "slug": 901, "text": 902 }, + "personas", + "Personas", + { "depth": 33, "slug": 904, "text": 905 }, + "ux-research", + "UX Research", + { "depth": 33, "slug": 907, "text": 908 }, + "use-cases", + "Use Cases", + { "depth": 33, "slug": 910, "text": 911 }, + "entry-points", + "Entry Points", + { "depth": 79, "slug": 913, "text": 914 }, + "flow-interconnection-diagram", + "Flow Interconnection Diagram", + { "depth": 79, "slug": 916, "text": 917 }, + "entry-point-matrix", + "Entry Point Matrix", + { "depth": 79, "slug": 919, "text": 920 }, + "ascii-reference", + "ASCII Reference", + { "depth": 79, "slug": 922, "text": 923 }, + "first-impression-by-entry", + "First Impression by Entry", + { "depth": 33, "slug": 925, "text": 926 }, + "user-flows", + "User Flows", + { "depth": 33, "slug": 928, "text": 929 }, + "flow-priorities", + "Flow Priorities", + { "depth": 33, "slug": 931, "text": 932 }, + "cross-linking-strategy", + "Cross-Linking Strategy", + { "depth": 79, "slug": 934, "text": 935 }, + "content-interconnections", + "Content Interconnections", + { "depth": 79, "slug": 937, "text": 938 }, + "cross-link-rules", + "Cross-Link Rules", + { "depth": 79, "slug": 940, "text": 920 }, + "ascii-reference-1", + { "depth": 33, "slug": 942, "text": 943 }, + "architecture-principles", + "Architecture Principles", + [], + [], + { "title": 887 }, + [], + "01-vision/product-overview", + { "id": 948, "data": 950, "body": 955, "filePath": 956, "digest": 957, "rendered": 958 }, + { + "title": 951, + "editUrl": 16, + "head": 952, + "template": 18, + "sidebar": 953, + "pagefind": 16, + "draft": 20 + }, + "VariScout: Product Overview", + [], + { "hidden": 20, "attrs": 954 }, + {}, + "# VariScout: Product Overview\n\n## Philosophy\n\n**Stay Lite.** VariScout Lite is a focused analysis tool, not a platform.\n\nWe deliberately chose simplicity over feature richness. Instead of building a complex multi-mode system with separate UIs for different use cases, we enhanced the core tool to handle the most important workflows.\n\n---\n\n## What We Built\n\n### Core Analysis Dashboard\n\n- **I-Chart**: Time series with auto-calculated control limits (UCL/LCL)\n- **Boxplot**: Factor comparison (e.g., Farm A vs Farm B)\n- **Pareto**: Frequency analysis for categorical data\n- **Linked Filtering**: Click any chart element to filter all others instantly\n- **Interactive Labels**: Rename axes and categories directly on the chart\n- **Focus Mode**: Maximize any chart for presentation or detailed analysis (Carousel navigation)\n\n### Data Input\n\n- **File Import**: Drag-and-drop CSV and Excel (.xlsx)\n- **Manual Entry**: Direct data entry with two modes:\n - **Standard Mode**: Factor-outcome analysis with running statistics\n - **Performance Mode**: Multi-channel entry with per-channel Cpk indicators\n - Keyboard navigation, spec compliance feedback (56px touch targets for tablets)\n- **Paste from Excel**: Tab-separated data supported\n\n### Export Options\n\n- **PNG Export**: Save charts as images for reports\n- **CSV Export**: Excel-compatible data export with row numbers and spec status\n- **Project Files**: Save/load as .vrs files for sharing (Azure App only)\n\n### Display Modes\n\n- **Presentation Mode**: Fullscreen view with all charts optimized for stakeholder presentations (Escape to exit)\n- **Focus Mode**: Maximize any chart for detailed analysis with carousel navigation\n- **Scrollable Layout**: Charts have comfortable minimum heights with sticky navigation\n\n### Capability Analysis\n\n- **Cp/Cpk Metrics**: Configurable process capability indices (toggle in Stats Panel)\n- **Capability Histogram**: Visual distribution analysis with spec limits overlay (tab in Stats Panel)\n- **Spec Editor**: Contextual editing of USL/LSL and Multi-Tier Grades directly in the analysis view\n\n### Data Table\n\n- **View Data**: Excel-like table view of all imported data\n- **Inline Editing**: Click any cell to edit values\n- **Keyboard Navigation**: Tab/Enter to move between cells\n- **Spec Status**: Color-coded pass/fail indicators per row\n- **Row Operations**: Add and delete rows\n\n### Persistence\n\n- **Azure App**: Named analyses saved to IndexedDB + synced to OneDrive. Download .vrs files for portability.\n- **PWA (Free)**: Session-only — data lives in React state, cleared on refresh. No save, no .vrs files.\n\n---\n\n## What We Chose NOT to Build\n\nBased on UX research, we considered a complex 4-mode architecture with:\n\n- Field Mode (touch-optimized data entry)\n- Analysis Mode (command palette, templates)\n- Presentation Mode (annotations, insight cards)\n- Certification Mode (audit trails, compliance packages)\n\n**We rejected this approach** because:\n\n1. It added complexity without proportional value\n2. The core tool already serves the main use cases\n3. Simple enhancements (Focus Mode, Presentation Mode, Manual Entry) addressed the key needs\n4. Maintaining 4 separate UIs would slow future development\n\nThe exploratory design is archived in `docs/archive/PRODUCT_CONCEPTS_v1_abandoned.md` for reference.\n\n---\n\n## Target Users\n\nBased on UX research with quality professionals in developing countries:\n\n| Persona | Role | Key Need |\n| ---------- | -------------------------------- | ------------------------------------- |\n| **Grace** | QA Manager (Kenya) | Reduce 4-hour Excel work to 1 hour |\n| **Raj** | Quality Engineer (India) | Real-time variation monitoring |\n| **Carlos** | Training Coordinator (Guatemala) | Explain quality data to farmer groups |\n\nSee [UX Research](../02-journeys/ux-research.md) for detailed personas, JTBD, and use cases.\n\n---\n\n## Design Principles\n\n1. **Offline by default** - Works without internet after first visit\n2. **Data stays local** - Zero external data transmission\n3. **Transparent math** - Show formulas, explain metrics\n4. **CSV exportable** - All data can be opened in Excel\n5. **Linked exploration** - Charts talk to each other through filtering\n6. **Fast to first insight** - Under 30 seconds from upload\n7. **Export-ready outputs** - Professional charts for reports\n8. **Simple over complete** - Do fewer things, do them well\n\n---\n\n## Technical Highlights\n\n| Aspect | Implementation |\n| --------- | ------------------------- |\n| Runtime | PWA with Service Worker |\n| Framework | React + TypeScript + Vite |\n| Styling | Tailwind CSS |\n| Charts | Visx (D3 primitives) |\n| Storage | IndexedDB + localStorage |\n| Bundle | ~700KB gzipped |\n\n---\n\n## Repository Structure\n\nVariScout is a pnpm monorepo with shared packages and multiple apps:\n\n```\nvariscout-lite/\n├── packages/\n│ ├── core/ # @variscout/core - Stats, parser, tier, glossary (pure TypeScript)\n│ ├── charts/ # @variscout/charts - Visx chart components\n│ ├── data/ # @variscout/data - Sample datasets with pre-computed chart data\n│ ├── hooks/ # @variscout/hooks - Shared React hooks\n│ └── ui/ # @variscout/ui - Shared UI components\n├── apps/\n│ ├── pwa/ # PWA website (React + Vite) — free training tool\n│ ├── azure/ # Azure Team App (EasyAuth + OneDrive sync)\n│ └── website/ # Marketing website (Astro + React Islands)\n└── docs/ # Documentation (vision, journeys, features, technical, decisions)\n```\n\n---\n\n## Strategic Direction: LSS Training Market\n\n### The Opportunity\n\nVaRiScout Lite is positioned as a lightweight alternative to Minitab for Lean Six Sigma training programs. Rather than competing on statistical test coverage (a battle Minitab wins after 30 years), we differentiate through superior UX, plain-language insights, and zero-friction deployment.\n\n### Trainer Pain Points We Solve\n\n| Minitab Pain | VaRiScout Solution |\n| --------------------------------------- | ----------------------------- |\n| Expensive per-seat licensing | Free/cheap for classroom use |\n| Students fight the UI | Clean, obvious interface |\n| \"Which menu is that test under?\" | Guided workflows |\n| Output requires interpretation training | Plain-language insights |\n| Installation headaches | Browser-based, works anywhere |\n\n### Planned Features\n\nTwo features required for complete Green Belt training coverage:\n\n| Feature | Purpose |\n| ------------------- | --------------------------------------------- |\n| ANOVA integration | Statistical confirmation of group differences |\n| Regression analysis | Multi-factor comparison with auto-fit |\n\nThese features are planned for future releases.\n\n---\n\n_See also:_\n\n- `README.md` - Quick start and installation\n- [Architecture](../05-technical/architecture.md) - Technical architecture details\n- [UX Research](../02-journeys/ux-research.md) - User research, personas, JTBD\n- [Specifications](../03-features/specifications.md) - Detailed functional specifications\n- [Product Specs](../08-products/) - Product specs (PWA, Website, Excel, Power BI, Azure)", + "src/content/docs/01-vision/product-overview.md", + "44286069dacd47ba", + { "html": 959, "metadata": 960 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"variscout-product-overview\">VariScout: Product Overview\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-product-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout: Product Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy\">Philosophy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Stay Lite.\u003C/strong> VariScout Lite is a focused analysis tool, not a platform.\u003C/p>\n\u003Cp>We deliberately chose simplicity over feature richness. Instead of building a complex multi-mode system with separate UIs for different use cases, we enhanced the core tool to handle the most important workflows.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-we-built\">What We Built\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-we-built\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What We Built”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-analysis-dashboard\">Core Analysis Dashboard\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-analysis-dashboard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Analysis Dashboard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: Time series with auto-calculated control limits (UCL/LCL)\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Factor comparison (e.g., Farm A vs Farm B)\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong>: Frequency analysis for categorical data\u003C/li>\n\u003Cli>\u003Cstrong>Linked Filtering\u003C/strong>: Click any chart element to filter all others instantly\u003C/li>\n\u003Cli>\u003Cstrong>Interactive Labels\u003C/strong>: Rename axes and categories directly on the chart\u003C/li>\n\u003Cli>\u003Cstrong>Focus Mode\u003C/strong>: Maximize any chart for presentation or detailed analysis (Carousel navigation)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-input\">Data Input\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-input\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Input”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>File Import\u003C/strong>: Drag-and-drop CSV and Excel (.xlsx)\u003C/li>\n\u003Cli>\u003Cstrong>Manual Entry\u003C/strong>: Direct data entry with two modes:\n\u003Cul>\n\u003Cli>\u003Cstrong>Standard Mode\u003C/strong>: Factor-outcome analysis with running statistics\u003C/li>\n\u003Cli>\u003Cstrong>Performance Mode\u003C/strong>: Multi-channel entry with per-channel Cpk indicators\u003C/li>\n\u003Cli>Keyboard navigation, spec compliance feedback (56px touch targets for tablets)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Paste from Excel\u003C/strong>: Tab-separated data supported\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"export-options\">Export Options\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#export-options\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Export Options”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>PNG Export\u003C/strong>: Save charts as images for reports\u003C/li>\n\u003Cli>\u003Cstrong>CSV Export\u003C/strong>: Excel-compatible data export with row numbers and spec status\u003C/li>\n\u003Cli>\u003Cstrong>Project Files\u003C/strong>: Save/load as .vrs files for sharing (Azure App only)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-modes\">Display Modes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-modes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Modes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Presentation Mode\u003C/strong>: Fullscreen view with all charts optimized for stakeholder presentations (Escape to exit)\u003C/li>\n\u003Cli>\u003Cstrong>Focus Mode\u003C/strong>: Maximize any chart for detailed analysis with carousel navigation\u003C/li>\n\u003Cli>\u003Cstrong>Scrollable Layout\u003C/strong>: Charts have comfortable minimum heights with sticky navigation\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"capability-analysis\">Capability Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#capability-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Cp/Cpk Metrics\u003C/strong>: Configurable process capability indices (toggle in Stats Panel)\u003C/li>\n\u003Cli>\u003Cstrong>Capability Histogram\u003C/strong>: Visual distribution analysis with spec limits overlay (tab in Stats Panel)\u003C/li>\n\u003Cli>\u003Cstrong>Spec Editor\u003C/strong>: Contextual editing of USL/LSL and Multi-Tier Grades directly in the analysis view\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-table\">Data Table\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-table\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Table”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>View Data\u003C/strong>: Excel-like table view of all imported data\u003C/li>\n\u003Cli>\u003Cstrong>Inline Editing\u003C/strong>: Click any cell to edit values\u003C/li>\n\u003Cli>\u003Cstrong>Keyboard Navigation\u003C/strong>: Tab/Enter to move between cells\u003C/li>\n\u003Cli>\u003Cstrong>Spec Status\u003C/strong>: Color-coded pass/fail indicators per row\u003C/li>\n\u003Cli>\u003Cstrong>Row Operations\u003C/strong>: Add and delete rows\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"persistence\">Persistence\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#persistence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persistence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Azure App\u003C/strong>: Named analyses saved to IndexedDB + synced to OneDrive. Download .vrs files for portability.\u003C/li>\n\u003Cli>\u003Cstrong>PWA (Free)\u003C/strong>: Session-only — data lives in React state, cleared on refresh. No save, no .vrs files.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-we-chose-not-to-build\">What We Chose NOT to Build\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-we-chose-not-to-build\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What We Chose NOT to Build”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Based on UX research, we considered a complex 4-mode architecture with:\u003C/p>\n\u003Cul>\n\u003Cli>Field Mode (touch-optimized data entry)\u003C/li>\n\u003Cli>Analysis Mode (command palette, templates)\u003C/li>\n\u003Cli>Presentation Mode (annotations, insight cards)\u003C/li>\n\u003Cli>Certification Mode (audit trails, compliance packages)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>We rejected this approach\u003C/strong> because:\u003C/p>\n\u003Col>\n\u003Cli>It added complexity without proportional value\u003C/li>\n\u003Cli>The core tool already serves the main use cases\u003C/li>\n\u003Cli>Simple enhancements (Focus Mode, Presentation Mode, Manual Entry) addressed the key needs\u003C/li>\n\u003Cli>Maintaining 4 separate UIs would slow future development\u003C/li>\n\u003C/ol>\n\u003Cp>The exploratory design is archived in \u003Ccode dir=\"auto\">docs/archive/PRODUCT_CONCEPTS_v1_abandoned.md\u003C/code> for reference.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-users\">Target Users\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-users\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Users”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Based on UX research with quality professionals in developing countries:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Role\u003C/th>\u003Cth>Key Need\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Grace\u003C/strong>\u003C/td>\u003Ctd>QA Manager (Kenya)\u003C/td>\u003Ctd>Reduce 4-hour Excel work to 1 hour\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Raj\u003C/strong>\u003C/td>\u003Ctd>Quality Engineer (India)\u003C/td>\u003Ctd>Real-time variation monitoring\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Carlos\u003C/strong>\u003C/td>\u003Ctd>Training Coordinator (Guatemala)\u003C/td>\u003Ctd>Explain quality data to farmer groups\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"../02-journeys/ux-research.md\">UX Research\u003C/a> for detailed personas, JTBD, and use cases.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"design-principles\">Design Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#design-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Offline by default\u003C/strong> - Works without internet after first visit\u003C/li>\n\u003Cli>\u003Cstrong>Data stays local\u003C/strong> - Zero external data transmission\u003C/li>\n\u003Cli>\u003Cstrong>Transparent math\u003C/strong> - Show formulas, explain metrics\u003C/li>\n\u003Cli>\u003Cstrong>CSV exportable\u003C/strong> - All data can be opened in Excel\u003C/li>\n\u003Cli>\u003Cstrong>Linked exploration\u003C/strong> - Charts talk to each other through filtering\u003C/li>\n\u003Cli>\u003Cstrong>Fast to first insight\u003C/strong> - Under 30 seconds from upload\u003C/li>\n\u003Cli>\u003Cstrong>Export-ready outputs\u003C/strong> - Professional charts for reports\u003C/li>\n\u003Cli>\u003Cstrong>Simple over complete\u003C/strong> - Do fewer things, do them well\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-highlights\">Technical Highlights\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-highlights\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Highlights”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Implementation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Runtime\u003C/td>\u003Ctd>PWA with Service Worker\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Framework\u003C/td>\u003Ctd>React + TypeScript + Vite\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Styling\u003C/td>\u003Ctd>Tailwind CSS\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Charts\u003C/td>\u003Ctd>Visx (D3 primitives)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Storage\u003C/td>\u003Ctd>IndexedDB + localStorage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Bundle\u003C/td>\u003Ctd>~700KB gzipped\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"repository-structure\">Repository Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#repository-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Repository Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is a pnpm monorepo with shared packages and multiple apps:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">variscout-lite/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── packages/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── core/ # @variscout/core - Stats, parser, tier, glossary (pure TypeScript)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── charts/ # @variscout/charts - Visx chart components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── data/ # @variscout/data - Sample datasets with pre-computed chart data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── hooks/ # @variscout/hooks - Shared React hooks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── ui/ # @variscout/ui - Shared UI components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── apps/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── pwa/ # PWA website (React + Vite) — free training tool\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── azure/ # Azure Team App (EasyAuth + OneDrive sync)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── website/ # Marketing website (Astro + React Islands)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── docs/ # Documentation (vision, journeys, features, technical, decisions)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"variscout-lite/├── packages/│ ├── core/ # @variscout/core - Stats, parser, tier, glossary (pure TypeScript)│ ├── charts/ # @variscout/charts - Visx chart components│ ├── data/ # @variscout/data - Sample datasets with pre-computed chart data│ ├── hooks/ # @variscout/hooks - Shared React hooks│ └── ui/ # @variscout/ui - Shared UI components├── apps/│ ├── pwa/ # PWA website (React + Vite) — free training tool│ ├── azure/ # Azure Team App (EasyAuth + OneDrive sync)│ └── website/ # Marketing website (Astro + React Islands)└── docs/ # Documentation (vision, journeys, features, technical, decisions)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-direction-lss-training-market\">Strategic Direction: LSS Training Market\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-direction-lss-training-market\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Direction: LSS Training Market”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-opportunity\">The Opportunity\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-opportunity\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Opportunity”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VaRiScout Lite is positioned as a lightweight alternative to Minitab for Lean Six Sigma training programs. Rather than competing on statistical test coverage (a battle Minitab wins after 30 years), we differentiate through superior UX, plain-language insights, and zero-friction deployment.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"trainer-pain-points-we-solve\">Trainer Pain Points We Solve\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#trainer-pain-points-we-solve\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Trainer Pain Points We Solve”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Minitab Pain\u003C/th>\u003Cth>VaRiScout Solution\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Expensive per-seat licensing\u003C/td>\u003Ctd>Free/cheap for classroom use\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Students fight the UI\u003C/td>\u003Ctd>Clean, obvious interface\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Which menu is that test under?”\u003C/td>\u003Ctd>Guided workflows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Output requires interpretation training\u003C/td>\u003Ctd>Plain-language insights\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Installation headaches\u003C/td>\u003Ctd>Browser-based, works anywhere\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"planned-features\">Planned Features\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#planned-features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Planned Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Two features required for complete Green Belt training coverage:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>ANOVA integration\u003C/td>\u003Ctd>Statistical confirmation of group differences\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regression analysis\u003C/td>\u003Ctd>Multi-factor comparison with auto-fit\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>These features are planned for future releases.\u003C/p>\n\u003Chr>\n\u003Cp>\u003Cem>See also:\u003C/em>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">README.md\u003C/code> - Quick start and installation\u003C/li>\n\u003Cli>\u003Ca href=\"../05-technical/architecture.md\">Architecture\u003C/a> - Technical architecture details\u003C/li>\n\u003Cli>\u003Ca href=\"../02-journeys/ux-research.md\">UX Research\u003C/a> - User research, personas, JTBD\u003C/li>\n\u003Cli>\u003Ca href=\"../03-features/specifications.md\">Specifications\u003C/a> - Detailed functional specifications\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/\">Product Specs\u003C/a> - Product specs (PWA, Website, Excel, Power BI, Azure)\u003C/li>\n\u003C/ul>", + { + "headings": 961, + "localImagePaths": 1018, + "remoteImagePaths": 1019, + "frontmatter": 1020, + "imagePaths": 1021 + }, + [ + 962, 964, 967, 970, 973, 976, 979, 982, 985, 988, 991, 994, 997, 1000, 1003, 1006, 1009, 1012, + 1015 + ], + { "depth": 30, "slug": 963, "text": 951 }, + "variscout-product-overview", + { "depth": 33, "slug": 965, "text": 966 }, + "philosophy", + "Philosophy", + { "depth": 33, "slug": 968, "text": 969 }, + "what-we-built", + "What We Built", + { "depth": 79, "slug": 971, "text": 972 }, + "core-analysis-dashboard", + "Core Analysis Dashboard", + { "depth": 79, "slug": 974, "text": 975 }, + "data-input", + "Data Input", + { "depth": 79, "slug": 977, "text": 978 }, + "export-options", + "Export Options", + { "depth": 79, "slug": 980, "text": 981 }, + "display-modes", + "Display Modes", + { "depth": 79, "slug": 983, "text": 984 }, + "capability-analysis", + "Capability Analysis", + { "depth": 79, "slug": 986, "text": 987 }, + "data-table", + "Data Table", + { "depth": 79, "slug": 989, "text": 990 }, + "persistence", + "Persistence", + { "depth": 33, "slug": 992, "text": 993 }, + "what-we-chose-not-to-build", + "What We Chose NOT to Build", + { "depth": 33, "slug": 995, "text": 996 }, + "target-users", + "Target Users", + { "depth": 33, "slug": 998, "text": 999 }, + "design-principles", + "Design Principles", + { "depth": 33, "slug": 1001, "text": 1002 }, + "technical-highlights", + "Technical Highlights", + { "depth": 33, "slug": 1004, "text": 1005 }, + "repository-structure", + "Repository Structure", + { "depth": 33, "slug": 1007, "text": 1008 }, + "strategic-direction-lss-training-market", + "Strategic Direction: LSS Training Market", + { "depth": 79, "slug": 1010, "text": 1011 }, + "the-opportunity", + "The Opportunity", + { "depth": 79, "slug": 1013, "text": 1014 }, + "trainer-pain-points-we-solve", + "Trainer Pain Points We Solve", + { "depth": 79, "slug": 1016, "text": 1017 }, + "planned-features", + "Planned Features", + [], + [], + { "title": 951 }, + [], + "01-vision/progressive-stratification", + { "id": 1022, "data": 1024, "body": 1028, "filePath": 1029, "digest": 1030, "rendered": 1031 }, + { + "title": 864, + "editUrl": 16, + "head": 1025, + "template": 18, + "sidebar": 1026, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 1027 }, + {}, + "# Progressive Stratification\n\nWhy VariScout's filter chip drill-down is the right interaction model for variation analysis --- and where it might not be.\n\n---\n\n## Part 1: The Concept\n\n### The analyst's problem\n\nVariation data is multidimensional. A production line generates measurements across time, machines, operators, shifts, materials, and environmental conditions. The analyst's question is always the same: **where is the variation concentrated?** But the data doesn't answer that directly.\n\nTraditional approaches force uncomfortable trade-offs:\n\n| Approach | Limitation |\n| ----------------------------------- | -------------------------------------------------------------------------- |\n| One chart at a time | No way to see how factors interact with each other |\n| Pivot tables | Combinatorial explosion --- 4 factors x 5 levels each = 625 cells |\n| Statistical software (Minitab, JMP) | Powerful but expensive, steep learning curve, outputs p-values not actions |\n| Dashboard tools (Tableau, Power BI) | Good at slicing, but don't quantify how much each slice explains |\n\nThe fundamental challenge is that this is an **exploration problem**, not a hypothesis-testing problem. The analyst doesn't start with \"I think Machine C is the problem\" --- they start with \"something is wrong and I don't know where to look.\" The tool needs to support open-ended investigation that converges on a specific, actionable finding.\n\n### Progressive stratification as the solution\n\nProgressive stratification converts a multidimensional problem into a sequential, one-factor-at-a-time investigation. The analyst:\n\n1. Looks at which factor explains the most variation (via the Boxplot's eta-squared display)\n2. Filters to the highest-impact level of that factor\n3. Sees how the remaining factors redistribute in the now-filtered data\n4. Repeats until enough variation is isolated to act on\n\nThis is analogous to **binary search** applied to a factor space. You don't examine every combination --- you narrow down by the highest-impact factor at each step. Each step does two things simultaneously:\n\n- **Reduces the problem space** --- fewer factors left to investigate\n- **Quantifies progress** --- the cumulative variation bar shows \"67% of total variation captured\"\n\nThe endpoint is a specific, actionable condition (\"Operator Kim on Machine C during Night Shift accounts for 46% of all variation\") --- not a vague recommendation (\"improve quality\"). This specificity is what makes the methodology useful to operations managers who need to assign resources and measure improvement.\n\n### Why filter chips with contribution %\n\nThe UI choices in VariScout's drill-down are not arbitrary. Each design decision addresses a specific analytical need.\n\n**Why chips instead of hierarchical breadcrumbs.** A traditional breadcrumb trail (Home > Category > Product) implies strict nesting --- removing a middle element invalidates everything after it. But variation factors are independent. Filtering by Shift and then by Machine doesn't create a hierarchy where Machine is \"inside\" Shift. You can remove the Shift filter and the Machine filter still makes sense. Chips reflect this independence: each chip is a standalone filter that can be added, removed, or modified without affecting the others.\n\n**Why contribution to total (not local eta-squared).** Local eta-squared answers \"how much does this factor explain within the current subset?\" --- useful for a statistician examining the filtered data in isolation, but it disconnects from the original problem. If the analyst filters to Night Shift (67% of total) and then sees Machine explains 36% of the Night Shift subset, the local eta-squared is 36%. But what they actually need to know is: \"how much of my TOTAL problem does Machine explain?\" That's 24% (36% of the 67% Night Shift portion). Contribution to total keeps the analyst anchored to the original question at every step.\n\n**Why multi-select.** Sometimes two values together tell the story. \"Machines A and C together account for 60% of variation\" is more useful than being forced to pick one. Single-select drill-down imposes artificial binary choices that don't match how real process factors behave. Multi-select also enables comparison workflows: select all the \"good\" operators to establish a baseline, then see what's different about the excluded ones.\n\n**Why the variation bar.** The cumulative variation bar gives a visceral sense of progress --- \"am I getting somewhere?\" The color thresholds (green at 50%+, amber at 30--50%, blue below 30%) translate statistics into actionable confidence levels. A plant manager doesn't need to understand eta-squared --- they need to know \"is this enough to act on?\" The bar answers that question at a glance.\n\n### Connection to Four Lenses and Two Voices\n\nProgressive stratification is the mechanism that makes VariScout's core frameworks actionable.\n\n**Four Lenses.** The Boxplot (FLOW lens) is the natural entry point --- it shows eta-squared by factor, immediately revealing where variation concentrates. But the drill-down doesn't happen in one lens alone. Linked filtering means that drilling in the Boxplot simultaneously updates the I-Chart (CHANGE), Pareto (FAILURE), and Capability (VALUE). The analyst sees not just \"Machine C has high variation\" but also \"Machine C's timeline shows a drift starting in week 3\" (I-Chart), \"Machine C's failure mode is predominantly oversized\" (Pareto), and \"Machine C's Cpk is 0.4 vs the overall 0.8\" (Capability). The Four Lenses become a coordinated investigation team rather than four independent displays.\n\n**Two Voices.** The drill-down finds process-voice patterns --- which factors drive variation in the process itself. The Capability lens (VALUE) then asks the customer-voice question: \"does this variation actually matter to the customer?\" A factor might explain 40% of process variation but the filtered Cpk might still be 1.5 --- meaning the process easily meets spec even with this factor active. Conversely, a factor explaining only 15% of variation might push Cpk below 1.0 for that subset, making it the real priority despite its lower statistical contribution. Progressive stratification surfaces both perspectives simultaneously.\n\n---\n\n## Part 2: Tensions and Open Questions\n\nEach tension and pattern below has been evaluated individually against VariScout's philosophy, personas, and competitive positioning --- see [Evaluations](evaluations/index.md).\n\n### Where the current design may be insufficient\n\n**Hierarchy assumption.** The sequential drill-down captures main effects --- how much variation each factor explains independently. But factors can interact: \"Machine C is only problematic on Night Shift\" is an interaction effect that the one-factor-at-a-time drill-down may miss. The regression panel handles interaction analysis, but the connection between the drill-down and the regression panel isn't obvious in the UI. The variation funnel shows a prompt when 2+ factors are in the drill stack (\"Try the Regression Panel with Include interactions\"), but this requires the analyst to notice and act on the prompt.\n\n**Discoverability.** The entire progressive stratification system starts with clicking a boxplot bar. If the analyst doesn't know to click, the most powerful feature is invisible. The variation funnel exists as an alternative entry point and progress tracker, but it's behind an icon in the toolbar. First-time users may see four static charts and never discover the interactive drill-down underneath.\n\n**Factor ordering.** The analyst chooses which factor to drill next. The Boxplot shows eta-squared for each factor, which implicitly suggests the highest-eta-squared factor is the best next drill target. But the analyst may not read it that way --- or may have domain knowledge that makes a different factor more interesting. Should the system suggest the next drill target more explicitly? There's a tension between guided and exploratory interaction.\n\n**\"When to stop\" judgment.** The color-coded variation bar helps (green = strong isolation, amber = moderate, blue = weak), but actionability and statistical explanatory power aren't the same thing. Isolating 46% of variation to \"Machine C on Night Shift\" is only useful if someone can actually change something about Machine C on Night Shift. If Machine C is the only machine available and Night Shift can't be eliminated, the finding is descriptively accurate but operationally useless. The tool quantifies variation sources but can't assess whether those sources are controllable.\n\n**Mobile screen budget.** Filter chips, the variation bar, and four charts all compete for screen space. On mobile, the filtering UI takes real estate from the charts that make it meaningful. The current design handles this with responsive margins and collapsible sections, but there's an inherent tension between showing the analytical state (active filters, cumulative progress) and showing the analytical content (the charts themselves).\n\n**Path dependency.** The order you drill matters for the intermediate contribution percentages. Filtering by Shift first then Machine gives different intermediate numbers than Machine first then Shift. The final cumulative result converges (the total variation explained by the combination is similar regardless of order), but the journey feels different. An analyst who drills Shift first sees \"Shift explains 67%\" and may conclude Shift is the dominant factor. An analyst who drills Machine first sees \"Machine explains 42%\" and draws a different intermediate conclusion. Both reach roughly the same endpoint, but the narrative differs. Whether this is confusing or simply an accurate reflection of how factor contribution depends on context is an open question.\n\n### Alternative patterns worth considering\n\nThese aren't proposals for implementation --- they're design patterns that address specific limitations of the current approach, worth evaluating as the product evolves.\n\n**Factor suggestion.** After each filter, highlight the next highest-impact factor: \"Try Machine next --- explains 45% of remaining variation.\" This reduces analyst guesswork and addresses the factor ordering tension. The risk is over-automation: if the system always suggests the next step, the analyst stops thinking about which factor matters and just follows the prompts. The Sock Mystery pedagogy depends on the analyst's own curiosity driving the investigation.\n\n**Automatic top-combination finder.** Use the regression engine to identify the highest-impact 2--3 filter combination automatically, then present it as a starting point. The analyst refines from there rather than building from scratch. This inverts the current workflow: instead of bottom-up exploration, the analyst starts with a system-generated hypothesis and validates or adjusts it. Useful for experienced analysts who want speed over discovery, but potentially harmful for learning.\n\n**Parallel path comparison.** \"You drilled Shift then Machine. What if you had started with Machine then Shift?\" Show alternative drill paths and whether they converge on the same finding. This directly addresses path dependency concerns by making the convergence (or divergence) visible. The cost is UI complexity and potential information overload.\n\n**Interaction heatmap.** A small matrix visualization showing factor-by-factor interaction strength before drilling. Cells are colored by interaction eta-squared. This helps the analyst see where interactions might matter before committing to a drill path. Addresses the interaction blindness limitation of one-factor-at-a-time drilling. Could be shown as a small panel alongside the Boxplot.\n\n**Sidebar filter panel (Tableau-style).** An always-visible panel listing all factors with checkboxes and sliders. More discoverable than click-to-drill (the filters are always visible, not hidden behind chart interactions), but less integrated with the analytical narrative. The analyst would be managing filters in one panel and reading charts in another, rather than the current approach where filtering is embedded in the chart interaction itself. Trade-off: discoverability vs analytical flow.\n\n**Small multiples.** Show all factor-by-value combinations as a grid of mini-charts. Visual and comprehensive, but quadratic in the number of factors --- 4 factors with 5 levels each means 20 mini-charts, and adding a second dimension makes it 400. Useful for low-dimensional data (2--3 factors), overwhelming beyond that.\n\n**Factor map (network visualization).** Display factors as nodes sized by eta-squared, with values as branches colored by contribution. The analyst's current filter path highlights as a trail through the map. Factor-by-factor interactions show as connecting lines between nodes. This addresses several limitations simultaneously: spatial overview of the entire factor landscape at a glance, interactions visible before drilling, no imposed sequence, and no screen space competition with charts (opens in a separate window). Could serve as an alternative entry point to the boxplot click, or as a \"strategy view\" alongside the tactical chip trail.\n\n---\n\n## Part 3: Cross-references\n\nThis document describes the _why_ behind VariScout's drill-down design. The _what_ and _how_ are documented elsewhere:\n\n| Topic | Document |\n| ----------------------------------- | ------------------------------------------------------------------------------- |\n| Product philosophy and EDA mindset | [EDA for Process Improvement](philosophy.md) |\n| Four Lenses drill-down methodology | [Drill-Down: Progressive Variation Analysis](four-lenses/drilldown.md) |\n| Drill-down implementation and hooks | [Drill-Down Navigation](../03-features/navigation/drill-down.md) |\n| Filter chip UI specification | [Filter Chips Navigation](../03-features/navigation/breadcrumbs.md) |\n| Linked filtering across charts | [Linked Filtering](../03-features/navigation/linked-filtering.md) |\n| Step-by-step drill-down workflow | [Drill-Down Analysis Workflow](../03-features/workflows/drill-down-workflow.md) |\n| Variation decomposition statistics | [Variation Decomposition](../03-features/analysis/variation-decomposition.md) |", + "src/content/docs/01-vision/progressive-stratification.md", + "859041e49f1843ab", + { "html": 1032, "metadata": 1033 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"progressive-stratification\">Progressive Stratification\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#progressive-stratification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Progressive Stratification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Why VariScout’s filter chip drill-down is the right interaction model for variation analysis --- and where it might not be.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-1-the-concept\">Part 1: The Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-1-the-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 1: The Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-analysts-problem\">The analyst’s problem\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-analysts-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The analyst’s problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Variation data is multidimensional. A production line generates measurements across time, machines, operators, shifts, materials, and environmental conditions. The analyst’s question is always the same: \u003Cstrong>where is the variation concentrated?\u003C/strong> But the data doesn’t answer that directly.\u003C/p>\n\u003Cp>Traditional approaches force uncomfortable trade-offs:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Approach\u003C/th>\u003Cth>Limitation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>One chart at a time\u003C/td>\u003Ctd>No way to see how factors interact with each other\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pivot tables\u003C/td>\u003Ctd>Combinatorial explosion --- 4 factors x 5 levels each = 625 cells\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Statistical software (Minitab, JMP)\u003C/td>\u003Ctd>Powerful but expensive, steep learning curve, outputs p-values not actions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Dashboard tools (Tableau, Power BI)\u003C/td>\u003Ctd>Good at slicing, but don’t quantify how much each slice explains\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The fundamental challenge is that this is an \u003Cstrong>exploration problem\u003C/strong>, not a hypothesis-testing problem. The analyst doesn’t start with “I think Machine C is the problem” --- they start with “something is wrong and I don’t know where to look.” The tool needs to support open-ended investigation that converges on a specific, actionable finding.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"progressive-stratification-as-the-solution\">Progressive stratification as the solution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#progressive-stratification-as-the-solution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Progressive stratification as the solution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Progressive stratification converts a multidimensional problem into a sequential, one-factor-at-a-time investigation. The analyst:\u003C/p>\n\u003Col>\n\u003Cli>Looks at which factor explains the most variation (via the Boxplot’s eta-squared display)\u003C/li>\n\u003Cli>Filters to the highest-impact level of that factor\u003C/li>\n\u003Cli>Sees how the remaining factors redistribute in the now-filtered data\u003C/li>\n\u003Cli>Repeats until enough variation is isolated to act on\u003C/li>\n\u003C/ol>\n\u003Cp>This is analogous to \u003Cstrong>binary search\u003C/strong> applied to a factor space. You don’t examine every combination --- you narrow down by the highest-impact factor at each step. Each step does two things simultaneously:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Reduces the problem space\u003C/strong> --- fewer factors left to investigate\u003C/li>\n\u003Cli>\u003Cstrong>Quantifies progress\u003C/strong> --- the cumulative variation bar shows “67% of total variation captured”\u003C/li>\n\u003C/ul>\n\u003Cp>The endpoint is a specific, actionable condition (“Operator Kim on Machine C during Night Shift accounts for 46% of all variation”) --- not a vague recommendation (“improve quality”). This specificity is what makes the methodology useful to operations managers who need to assign resources and measure improvement.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-filter-chips-with-contribution\">Why filter chips with contribution %\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-filter-chips-with-contribution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why filter chips with contribution %”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The UI choices in VariScout’s drill-down are not arbitrary. Each design decision addresses a specific analytical need.\u003C/p>\n\u003Cp>\u003Cstrong>Why chips instead of hierarchical breadcrumbs.\u003C/strong> A traditional breadcrumb trail (Home > Category > Product) implies strict nesting --- removing a middle element invalidates everything after it. But variation factors are independent. Filtering by Shift and then by Machine doesn’t create a hierarchy where Machine is “inside” Shift. You can remove the Shift filter and the Machine filter still makes sense. Chips reflect this independence: each chip is a standalone filter that can be added, removed, or modified without affecting the others.\u003C/p>\n\u003Cp>\u003Cstrong>Why contribution to total (not local eta-squared).\u003C/strong> Local eta-squared answers “how much does this factor explain within the current subset?” --- useful for a statistician examining the filtered data in isolation, but it disconnects from the original problem. If the analyst filters to Night Shift (67% of total) and then sees Machine explains 36% of the Night Shift subset, the local eta-squared is 36%. But what they actually need to know is: “how much of my TOTAL problem does Machine explain?” That’s 24% (36% of the 67% Night Shift portion). Contribution to total keeps the analyst anchored to the original question at every step.\u003C/p>\n\u003Cp>\u003Cstrong>Why multi-select.\u003C/strong> Sometimes two values together tell the story. “Machines A and C together account for 60% of variation” is more useful than being forced to pick one. Single-select drill-down imposes artificial binary choices that don’t match how real process factors behave. Multi-select also enables comparison workflows: select all the “good” operators to establish a baseline, then see what’s different about the excluded ones.\u003C/p>\n\u003Cp>\u003Cstrong>Why the variation bar.\u003C/strong> The cumulative variation bar gives a visceral sense of progress --- “am I getting somewhere?” The color thresholds (green at 50%+, amber at 30—50%, blue below 30%) translate statistics into actionable confidence levels. A plant manager doesn’t need to understand eta-squared --- they need to know “is this enough to act on?” The bar answers that question at a glance.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"connection-to-four-lenses-and-two-voices\">Connection to Four Lenses and Two Voices\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#connection-to-four-lenses-and-two-voices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Connection to Four Lenses and Two Voices”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Progressive stratification is the mechanism that makes VariScout’s core frameworks actionable.\u003C/p>\n\u003Cp>\u003Cstrong>Four Lenses.\u003C/strong> The Boxplot (FLOW lens) is the natural entry point --- it shows eta-squared by factor, immediately revealing where variation concentrates. But the drill-down doesn’t happen in one lens alone. Linked filtering means that drilling in the Boxplot simultaneously updates the I-Chart (CHANGE), Pareto (FAILURE), and Capability (VALUE). The analyst sees not just “Machine C has high variation” but also “Machine C’s timeline shows a drift starting in week 3” (I-Chart), “Machine C’s failure mode is predominantly oversized” (Pareto), and “Machine C’s Cpk is 0.4 vs the overall 0.8” (Capability). The Four Lenses become a coordinated investigation team rather than four independent displays.\u003C/p>\n\u003Cp>\u003Cstrong>Two Voices.\u003C/strong> The drill-down finds process-voice patterns --- which factors drive variation in the process itself. The Capability lens (VALUE) then asks the customer-voice question: “does this variation actually matter to the customer?” A factor might explain 40% of process variation but the filtered Cpk might still be 1.5 --- meaning the process easily meets spec even with this factor active. Conversely, a factor explaining only 15% of variation might push Cpk below 1.0 for that subset, making it the real priority despite its lower statistical contribution. Progressive stratification surfaces both perspectives simultaneously.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-2-tensions-and-open-questions\">Part 2: Tensions and Open Questions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-2-tensions-and-open-questions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 2: Tensions and Open Questions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each tension and pattern below has been evaluated individually against VariScout’s philosophy, personas, and competitive positioning --- see \u003Ca href=\"evaluations/index.md\">Evaluations\u003C/a>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"where-the-current-design-may-be-insufficient\">Where the current design may be insufficient\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#where-the-current-design-may-be-insufficient\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Where the current design may be insufficient”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Hierarchy assumption.\u003C/strong> The sequential drill-down captures main effects --- how much variation each factor explains independently. But factors can interact: “Machine C is only problematic on Night Shift” is an interaction effect that the one-factor-at-a-time drill-down may miss. The regression panel handles interaction analysis, but the connection between the drill-down and the regression panel isn’t obvious in the UI. The variation funnel shows a prompt when 2+ factors are in the drill stack (“Try the Regression Panel with Include interactions”), but this requires the analyst to notice and act on the prompt.\u003C/p>\n\u003Cp>\u003Cstrong>Discoverability.\u003C/strong> The entire progressive stratification system starts with clicking a boxplot bar. If the analyst doesn’t know to click, the most powerful feature is invisible. The variation funnel exists as an alternative entry point and progress tracker, but it’s behind an icon in the toolbar. First-time users may see four static charts and never discover the interactive drill-down underneath.\u003C/p>\n\u003Cp>\u003Cstrong>Factor ordering.\u003C/strong> The analyst chooses which factor to drill next. The Boxplot shows eta-squared for each factor, which implicitly suggests the highest-eta-squared factor is the best next drill target. But the analyst may not read it that way --- or may have domain knowledge that makes a different factor more interesting. Should the system suggest the next drill target more explicitly? There’s a tension between guided and exploratory interaction.\u003C/p>\n\u003Cp>\u003Cstrong>“When to stop” judgment.\u003C/strong> The color-coded variation bar helps (green = strong isolation, amber = moderate, blue = weak), but actionability and statistical explanatory power aren’t the same thing. Isolating 46% of variation to “Machine C on Night Shift” is only useful if someone can actually change something about Machine C on Night Shift. If Machine C is the only machine available and Night Shift can’t be eliminated, the finding is descriptively accurate but operationally useless. The tool quantifies variation sources but can’t assess whether those sources are controllable.\u003C/p>\n\u003Cp>\u003Cstrong>Mobile screen budget.\u003C/strong> Filter chips, the variation bar, and four charts all compete for screen space. On mobile, the filtering UI takes real estate from the charts that make it meaningful. The current design handles this with responsive margins and collapsible sections, but there’s an inherent tension between showing the analytical state (active filters, cumulative progress) and showing the analytical content (the charts themselves).\u003C/p>\n\u003Cp>\u003Cstrong>Path dependency.\u003C/strong> The order you drill matters for the intermediate contribution percentages. Filtering by Shift first then Machine gives different intermediate numbers than Machine first then Shift. The final cumulative result converges (the total variation explained by the combination is similar regardless of order), but the journey feels different. An analyst who drills Shift first sees “Shift explains 67%” and may conclude Shift is the dominant factor. An analyst who drills Machine first sees “Machine explains 42%” and draws a different intermediate conclusion. Both reach roughly the same endpoint, but the narrative differs. Whether this is confusing or simply an accurate reflection of how factor contribution depends on context is an open question.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"alternative-patterns-worth-considering\">Alternative patterns worth considering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#alternative-patterns-worth-considering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Alternative patterns worth considering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These aren’t proposals for implementation --- they’re design patterns that address specific limitations of the current approach, worth evaluating as the product evolves.\u003C/p>\n\u003Cp>\u003Cstrong>Factor suggestion.\u003C/strong> After each filter, highlight the next highest-impact factor: “Try Machine next --- explains 45% of remaining variation.” This reduces analyst guesswork and addresses the factor ordering tension. The risk is over-automation: if the system always suggests the next step, the analyst stops thinking about which factor matters and just follows the prompts. The Sock Mystery pedagogy depends on the analyst’s own curiosity driving the investigation.\u003C/p>\n\u003Cp>\u003Cstrong>Automatic top-combination finder.\u003C/strong> Use the regression engine to identify the highest-impact 2—3 filter combination automatically, then present it as a starting point. The analyst refines from there rather than building from scratch. This inverts the current workflow: instead of bottom-up exploration, the analyst starts with a system-generated hypothesis and validates or adjusts it. Useful for experienced analysts who want speed over discovery, but potentially harmful for learning.\u003C/p>\n\u003Cp>\u003Cstrong>Parallel path comparison.\u003C/strong> “You drilled Shift then Machine. What if you had started with Machine then Shift?” Show alternative drill paths and whether they converge on the same finding. This directly addresses path dependency concerns by making the convergence (or divergence) visible. The cost is UI complexity and potential information overload.\u003C/p>\n\u003Cp>\u003Cstrong>Interaction heatmap.\u003C/strong> A small matrix visualization showing factor-by-factor interaction strength before drilling. Cells are colored by interaction eta-squared. This helps the analyst see where interactions might matter before committing to a drill path. Addresses the interaction blindness limitation of one-factor-at-a-time drilling. Could be shown as a small panel alongside the Boxplot.\u003C/p>\n\u003Cp>\u003Cstrong>Sidebar filter panel (Tableau-style).\u003C/strong> An always-visible panel listing all factors with checkboxes and sliders. More discoverable than click-to-drill (the filters are always visible, not hidden behind chart interactions), but less integrated with the analytical narrative. The analyst would be managing filters in one panel and reading charts in another, rather than the current approach where filtering is embedded in the chart interaction itself. Trade-off: discoverability vs analytical flow.\u003C/p>\n\u003Cp>\u003Cstrong>Small multiples.\u003C/strong> Show all factor-by-value combinations as a grid of mini-charts. Visual and comprehensive, but quadratic in the number of factors --- 4 factors with 5 levels each means 20 mini-charts, and adding a second dimension makes it 400. Useful for low-dimensional data (2—3 factors), overwhelming beyond that.\u003C/p>\n\u003Cp>\u003Cstrong>Factor map (network visualization).\u003C/strong> Display factors as nodes sized by eta-squared, with values as branches colored by contribution. The analyst’s current filter path highlights as a trail through the map. Factor-by-factor interactions show as connecting lines between nodes. This addresses several limitations simultaneously: spatial overview of the entire factor landscape at a glance, interactions visible before drilling, no imposed sequence, and no screen space competition with charts (opens in a separate window). Could serve as an alternative entry point to the boxplot click, or as a “strategy view” alongside the tactical chip trail.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-3-cross-references\">Part 3: Cross-references\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-3-cross-references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 3: Cross-references”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This document describes the \u003Cem>why\u003C/em> behind VariScout’s drill-down design. The \u003Cem>what\u003C/em> and \u003Cem>how\u003C/em> are documented elsewhere:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Topic\u003C/th>\u003Cth>Document\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Product philosophy and EDA mindset\u003C/td>\u003Ctd>\u003Ca href=\"philosophy.md\">EDA for Process Improvement\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Four Lenses drill-down methodology\u003C/td>\u003Ctd>\u003Ca href=\"four-lenses/drilldown.md\">Drill-Down: Progressive Variation Analysis\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Drill-down implementation and hooks\u003C/td>\u003Ctd>\u003Ca href=\"../03-features/navigation/drill-down.md\">Drill-Down Navigation\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filter chip UI specification\u003C/td>\u003Ctd>\u003Ca href=\"../03-features/navigation/breadcrumbs.md\">Filter Chips Navigation\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Linked filtering across charts\u003C/td>\u003Ctd>\u003Ca href=\"../03-features/navigation/linked-filtering.md\">Linked Filtering\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step-by-step drill-down workflow\u003C/td>\u003Ctd>\u003Ca href=\"../03-features/workflows/drill-down-workflow.md\">Drill-Down Analysis Workflow\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Variation decomposition statistics\u003C/td>\u003Ctd>\u003Ca href=\"../03-features/analysis/variation-decomposition.md\">Variation Decomposition\u003C/a>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 1034, + "localImagePaths": 1063, + "remoteImagePaths": 1064, + "frontmatter": 1065, + "imagePaths": 1066 + }, + [1035, 1036, 1039, 1042, 1045, 1048, 1051, 1054, 1057, 1060], + { "depth": 30, "slug": 863, "text": 864 }, + { "depth": 33, "slug": 1037, "text": 1038 }, + "part-1-the-concept", + "Part 1: The Concept", + { "depth": 79, "slug": 1040, "text": 1041 }, + "the-analysts-problem", + "The analyst’s problem", + { "depth": 79, "slug": 1043, "text": 1044 }, + "progressive-stratification-as-the-solution", + "Progressive stratification as the solution", + { "depth": 79, "slug": 1046, "text": 1047 }, + "why-filter-chips-with-contribution", + "Why filter chips with contribution %", + { "depth": 79, "slug": 1049, "text": 1050 }, + "connection-to-four-lenses-and-two-voices", + "Connection to Four Lenses and Two Voices", + { "depth": 33, "slug": 1052, "text": 1053 }, + "part-2-tensions-and-open-questions", + "Part 2: Tensions and Open Questions", + { "depth": 79, "slug": 1055, "text": 1056 }, + "where-the-current-design-may-be-insufficient", + "Where the current design may be insufficient", + { "depth": 79, "slug": 1058, "text": 1059 }, + "alternative-patterns-worth-considering", + "Alternative patterns worth considering", + { "depth": 33, "slug": 1061, "text": 1062 }, + "part-3-cross-references", + "Part 3: Cross-references", + [], + [], + { "title": 864 }, + [], + "03-features", + { "id": 1067, "data": 1069, "body": 1074, "filePath": 1075, "digest": 1076, "rendered": 1077 }, + { + "title": 1070, + "editUrl": 16, + "head": 1071, + "template": 18, + "sidebar": 1072, + "pagefind": 16, + "draft": 20 + }, + "Features", + [], + { "hidden": 20, "attrs": 1073 }, + {}, + "# Features\n\nCentralized feature specifications for VariScout.\n\n---\n\n## Product Documentation\n\n| Document | Description |\n| ----------------------------------- | ------------------------------------ |\n| [Specifications](specifications.md) | Product specs, tagline, capabilities |\n| [User Guide](user-guide.md) | End-user guide for VariScout |\n\n---\n\n## Analysis Tools\n\nThe core statistical charts based on Watson's Four Lenses:\n\n| Chart | Lens | Purpose |\n| ------------------------------------------------ | ------- | ---------------------------------------- |\n| [I-Chart](analysis/i-chart.md) | CHANGE | Time-based stability analysis |\n| [Boxplot](analysis/boxplot.md) | FLOW | Factor comparison (includes Violin Mode) |\n| [Pareto](analysis/pareto.md) | FAILURE | Problem concentration |\n| [Capability](analysis/capability.md) | VALUE | Specification compliance |\n| [Regression](analysis/regression.md) | - | Correlation analysis |\n| [Performance Mode](analysis/performance-mode.md) | - | Multi-channel analysis |\n\n### Advanced Analysis\n\n| Feature | Description |\n| ------------------------------------------------ | -------------------------------------------- |\n| [Nelson Rules](analysis/nelson-rules.md) | Control chart pattern detection rules |\n| [Staged Analysis](analysis/staged-analysis.md) | Before/after comparison with stage columns |\n| [Probability Plot](analysis/probability-plot.md) | Normal probability plot for distribution fit |\n\n---\n\n## Analysis Journey\n\n| Map | Description |\n| ---------------------------------------------------------------------- | ------------------------------------------------ |\n| [Analysis Journey Map](workflows/analysis-journey-map.md) | 4-phase model: Frame → Scout → Investigate → Improve |\n| [Investigation Lifecycle Map](workflows/investigation-lifecycle-map.md) | IDEOI state diagram for the Investigate phase |\n\n## Analyst Workflows\n\nHow analysts combine VariScout tools to solve real problems. See the [Workflows index](workflows/index.md) for the full guide.\n\n| Workflow | Description |\n| --------------------------------------------------------------- | -------------------------------------- |\n| [Four Lenses](workflows/four-lenses-workflow.md) | Foundational CHANGE-FLOW-FAILURE-VALUE |\n| [Drill-Down](workflows/drill-down-workflow.md) | Progressive stratification |\n| [Performance Mode](workflows/performance-mode-workflow.md) | Multi-channel analysis workflow |\n| [Quick Check](workflows/quick-check.md) | 5-minute shift monitoring |\n| [Deep Dive](workflows/deep-dive.md) | 30-minute systematic investigation |\n| [Decision Trees](workflows/decision-trees.md) | Chart selection flowcharts |\n| [Investigation to Action](workflows/investigation-to-action.md) | Investigate, refine, project |\n| [Process Maps](workflows/process-maps.md) | Step-by-step visual action maps |\n\n---\n\n## Navigation\n\nHow users explore and filter data:\n\n| Feature | Description |\n| -------------------------------------------------- | -------------------------- |\n| [Drill-Down](navigation/drill-down.md) | Progressive stratification |\n| [Linked Filtering](navigation/linked-filtering.md) | Cross-chart filtering |\n| [Breadcrumbs](navigation/breadcrumbs.md) | Analysis path tracking |\n\n---\n\n## Data\n\nData handling and storage:\n\n| Feature | Description |\n| -------------------------------- | ----------------------- |\n| [Data Input](data/data-input.md) | File upload and parsing |\n| [Validation](data/validation.md) | Data quality checks |\n| [Storage](data/storage.md) | IndexedDB persistence |\n\n---\n\n## Learning\n\nEducational features:\n\n| Feature | Description |\n| ------------------------------------------------------ | ------------------------- |\n| [Glossary](learning/glossary.md) | Term definitions |\n| [Help Tooltips](learning/help-tooltips.md) | Contextual help |\n| [Case-Based Learning](learning/case-based-learning.md) | Learning through examples |", + "src/content/docs/03-features/index.md", + "07866c3249fe4426", + { "html": 1078, "metadata": 1079 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"features\">Features\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Centralized feature specifications for VariScout.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"product-documentation\">Product Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#product-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Documentation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Document\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"specifications.md\">Specifications\u003C/a>\u003C/td>\u003Ctd>Product specs, tagline, capabilities\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"user-guide.md\">User Guide\u003C/a>\u003C/td>\u003Ctd>End-user guide for VariScout\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysis-tools\">Analysis Tools\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-tools\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis Tools”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The core statistical charts based on Watson’s Four Lenses:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Lens\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"analysis/i-chart.md\">I-Chart\u003C/a>\u003C/td>\u003Ctd>CHANGE\u003C/td>\u003Ctd>Time-based stability analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"analysis/boxplot.md\">Boxplot\u003C/a>\u003C/td>\u003Ctd>FLOW\u003C/td>\u003Ctd>Factor comparison (includes Violin Mode)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"analysis/pareto.md\">Pareto\u003C/a>\u003C/td>\u003Ctd>FAILURE\u003C/td>\u003Ctd>Problem concentration\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"analysis/capability.md\">Capability\u003C/a>\u003C/td>\u003Ctd>VALUE\u003C/td>\u003Ctd>Specification compliance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"analysis/regression.md\">Regression\u003C/a>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Correlation analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"analysis/performance-mode.md\">Performance Mode\u003C/a>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Multi-channel analysis\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"advanced-analysis\">Advanced Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#advanced-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Advanced Analysis”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"analysis/nelson-rules.md\">Nelson Rules\u003C/a>\u003C/td>\u003Ctd>Control chart pattern detection rules\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"analysis/staged-analysis.md\">Staged Analysis\u003C/a>\u003C/td>\u003Ctd>Before/after comparison with stage columns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"analysis/probability-plot.md\">Probability Plot\u003C/a>\u003C/td>\u003Ctd>Normal probability plot for distribution fit\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysis-journey\">Analysis Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis Journey”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Map\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"workflows/analysis-journey-map.md\">Analysis Journey Map\u003C/a>\u003C/td>\u003Ctd>4-phase model: Frame → Scout → Investigate → Improve\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"workflows/investigation-lifecycle-map.md\">Investigation Lifecycle Map\u003C/a>\u003C/td>\u003Ctd>IDEOI state diagram for the Investigate phase\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analyst-workflows\">Analyst Workflows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analyst-workflows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analyst Workflows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How analysts combine VariScout tools to solve real problems. See the \u003Ca href=\"workflows/index.md\">Workflows index\u003C/a> for the full guide.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Workflow\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"workflows/four-lenses-workflow.md\">Four Lenses\u003C/a>\u003C/td>\u003Ctd>Foundational CHANGE-FLOW-FAILURE-VALUE\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"workflows/drill-down-workflow.md\">Drill-Down\u003C/a>\u003C/td>\u003Ctd>Progressive stratification\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"workflows/performance-mode-workflow.md\">Performance Mode\u003C/a>\u003C/td>\u003Ctd>Multi-channel analysis workflow\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"workflows/quick-check.md\">Quick Check\u003C/a>\u003C/td>\u003Ctd>5-minute shift monitoring\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"workflows/deep-dive.md\">Deep Dive\u003C/a>\u003C/td>\u003Ctd>30-minute systematic investigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"workflows/decision-trees.md\">Decision Trees\u003C/a>\u003C/td>\u003Ctd>Chart selection flowcharts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"workflows/investigation-to-action.md\">Investigation to Action\u003C/a>\u003C/td>\u003Ctd>Investigate, refine, project\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"workflows/process-maps.md\">Process Maps\u003C/a>\u003C/td>\u003Ctd>Step-by-step visual action maps\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"navigation\">Navigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Navigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How users explore and filter data:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"navigation/drill-down.md\">Drill-Down\u003C/a>\u003C/td>\u003Ctd>Progressive stratification\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"navigation/linked-filtering.md\">Linked Filtering\u003C/a>\u003C/td>\u003Ctd>Cross-chart filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"navigation/breadcrumbs.md\">Breadcrumbs\u003C/a>\u003C/td>\u003Ctd>Analysis path tracking\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data\">Data\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Data handling and storage:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"data/data-input.md\">Data Input\u003C/a>\u003C/td>\u003Ctd>File upload and parsing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"data/validation.md\">Validation\u003C/a>\u003C/td>\u003Ctd>Data quality checks\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"data/storage.md\">Storage\u003C/a>\u003C/td>\u003Ctd>IndexedDB persistence\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"learning\">Learning\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#learning\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Learning”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Educational features:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"learning/glossary.md\">Glossary\u003C/a>\u003C/td>\u003Ctd>Term definitions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"learning/help-tooltips.md\">Help Tooltips\u003C/a>\u003C/td>\u003Ctd>Contextual help\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"learning/case-based-learning.md\">Case-Based Learning\u003C/a>\u003C/td>\u003Ctd>Learning through examples\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 1080, + "localImagePaths": 1107, + "remoteImagePaths": 1108, + "frontmatter": 1109, + "imagePaths": 1110 + }, + [1081, 1083, 1086, 1089, 1092, 1095, 1098, 1101, 1104], + { "depth": 30, "slug": 1082, "text": 1070 }, + "features", + { "depth": 33, "slug": 1084, "text": 1085 }, + "product-documentation", + "Product Documentation", + { "depth": 33, "slug": 1087, "text": 1088 }, + "analysis-tools", + "Analysis Tools", + { "depth": 79, "slug": 1090, "text": 1091 }, + "advanced-analysis", + "Advanced Analysis", + { "depth": 33, "slug": 1093, "text": 1094 }, + "analysis-journey", + "Analysis Journey", + { "depth": 33, "slug": 1096, "text": 1097 }, + "analyst-workflows", + "Analyst Workflows", + { "depth": 33, "slug": 1099, "text": 1100 }, + "navigation", + "Navigation", + { "depth": 33, "slug": 1102, "text": 1103 }, + "data", + "Data", + { "depth": 33, "slug": 1105, "text": 1106 }, + "learning", + "Learning", + [], + [], + { "title": 1070 }, + [], + "03-features/user-guide", + { "id": 1111, "data": 1113, "body": 1118, "filePath": 1119, "digest": 1120, "rendered": 1121 }, + { + "title": 1114, + "editUrl": 16, + "head": 1115, + "template": 18, + "sidebar": 1116, + "pagefind": 16, + "draft": 20 + }, + "VariScout Lite: User Guide", + [], + { "hidden": 20, "attrs": 1117 }, + {}, + "# VariScout Lite: User Guide\n\nThis guide covers advanced features and workflows in VariScout Lite, focusing on interactive customization and specification management.\n\n## Interactive Chart Customization\n\nVariScout Lite allows you to customize chart labels and axis names directly on the dashboard without altering your original data source. This is called **Aliasing**.\n\n### Column Renaming at Setup\n\nYou can rename columns during the column mapping step, before analysis begins.\n\n1. After pasting or uploading data, the **ColumnMapping** screen shows each column as a data-rich card with a type badge, sample values, and unique count.\n2. Click the **pencil icon** on any column card.\n3. Type a new name in the inline input, then press **Enter** or click away to save.\n4. The alias persists through the analysis — filter chips, chart axes, and breadcrumbs all use the renamed label.\n5. The original column name appears as a subtitle on the card for reference.\n\nThis is useful when your source data has cryptic column headers (e.g., \"COL_3\") and you want human-readable names from the start.\n\n### Renaming Axis Titles\n\nYou can rename the Y-axis (Outcome) and X-axis (Factor/Category) labels to make charts more presentation-ready.\n\n1. **Hover** over any axis label (e.g., \"Weight\" on the Y-axis). The cursor will change to a pointer.\n2. **Click** the label. A small popup editor will appear.\n3. **Type** the new name (e.g., \"Net Weight (g)\").\n4. **Click Save** (Check icon).\n - _Note: This creates an \"alias\". Your original data column name remains unchanged._\n\n### Renaming Categories (Boxplot)\n\nIf your data has cryptic codes (e.g., \"M1\", \"M2\"), you can rename them to meaningful labels (e.g., \"Machine 1\", \"Machine 2\") directly on the Boxplot.\n\n1. **Click** the X-axis label of the Boxplot (e.g., \"MachineID\").\n2. The **Label & Category Editor** will open.\n3. You will see a list of all unique values found in that column.\n4. Enter a **Display Name** next to any value you wish to rename.\n5. **Click Save**. The chart will update immediately.\n\n---\n\n## Specification Management\n\nSpecifications (Spec Limits) define what is considered \"acceptable\" quality. VariScout Lite supports both standard limits and complex multi-tier grading.\n\n### Setting Specifications — Two Entry Points\n\nYou can set specification limits at two points in the workflow. Both approaches auto-apply on blur; there is no separate Apply button.\n\n**Option 1: During Column Mapping (optional, at setup time)**\n\nThe ColumnMapping screen shows each column as a data-rich card with type badge (Numeric, Categorical, Date), sample values, and unique count. At the bottom, a collapsible **\"Set Specification Limits\"** section is available (collapsed by default).\n\n1. After pasting or uploading data, review the column cards and confirm your outcome and factor selections.\n2. Scroll to the bottom and click **\"Set Specification Limits\"** to expand the section.\n3. Enter any combination of **Target**, **LSL**, and **USL** — all three are optional.\n4. Continue to analysis. The values carry over automatically.\n\nThis is the fastest path when you already know your spec limits before starting.\n\n**Option 2: Inline in the Stats Panel (at analysis time)**\n\nIf you reach the dashboard without specs set, the Stats Panel shows an inline entry area instead of silently omitting Cp/Cpk/Pass Rate.\n\n1. Look for the **\"Set a target to enable Cp/Cpk\"** prompt in the Stats Panel.\n2. Enter a **Target** value first (lowest commitment — unlocks partial feedback).\n3. Click **\"+ LSL/USL\"** to expand and add the full specification range.\n4. Click or tab away from the field — values apply immediately.\n5. The inline entry area transforms into the normal Cp/Cpk/Pass Rate stat cards.\n\n**Option 3: Via the Specs dropdown in the I-Chart header**\n\n1. In the **I-Chart header**, click the **\"Specs\"** dropdown button.\n2. A popover will appear with checkboxes and input fields for each limit.\n3. Enter your limits:\n - **USL (Upper Spec Limit)**: Maximum acceptable value.\n - **LSL (Lower Spec Limit)**: Minimum acceptable value.\n - **Target**: Ideal value (optional, drawn in green).\n4. Use the checkboxes to toggle visibility of each limit on the chart.\n\n**Result (any entry point):**\n\n- Red dotted lines appear on charts (I-Chart & Boxplot).\n- Cp, Cpk, and Pass/Fail rates are instantly calculated in the Stats Panel.\n- Histogram updates to show spec boundaries.\n\n---\n\n## Visualization Options\n\nYou can toggle visibility of chart elements and change display settings in the **Settings Panel**.\n\n1. Click the **Settings icon (⚙)** in the top right of the header.\n2. The Settings Panel will slide in from the right.\n3. In the **\"Display Options\"** section, toggle:\n - **Lock Y-axis when drilling**: Keep the Y-axis scale consistent when filtering data.\n - **Show Control Limits**: Display UCL/Mean/LCL lines on the I-Chart (statistical process control limits based on 3-sigma rule).\n - **Show distribution shape**: Overlay density curves (violin plots) on boxplots to reveal distribution shape, bimodality, and skewness.\n4. In the **\"Y-Axis Scale Mode\"** section, choose:\n - **Auto**: Automatically fit scale to data and specification limits.\n - **Start at Zero**: Force Y-axis minimum to zero (useful for ratio data).\n - **Manual**: Set explicit Min and Max values for the Y-axis.\n5. Spec limit visibility (USL/LSL/Target) is now controlled via the **Specs dropdown** in the I-Chart header.\n\n---\n\n## Editing Data\n\nAfter loading data, you can edit individual values, add rows, or delete rows directly in the **Data Table Editor** without re-importing your dataset.\n\n### Opening the Editor\n\n- **PWA**: Click the **Data Table** button in the toolbar\n- **Azure App**: Click the **Pencil** icon in the toolbar, or the pencil button in the DataPanel header\n\n### Editing Cells\n\n1. **Click** any cell to start editing — the cell turns into a text input\n2. Type the new value\n3. Use keyboard shortcuts to navigate:\n\n| Key | Action |\n| ------------ | ----------------------------------------------- |\n| `Tab` | Move to next column (wraps to next row) |\n| `Shift+Tab` | Move to previous column (wraps to previous row) |\n| `Enter` | Move to next row (same column) |\n| `Arrow Up` | Move to previous row (same column) |\n| `Arrow Down` | Move to next row (same column) |\n| `Escape` | Cancel edit |\n\n4. Edited values show an **(unsaved changes)** indicator in the header\n\n### Multi-cell Paste\n\nYou can paste tab-delimited data (e.g. from Excel or Google Sheets) directly into the table:\n\n- **In-cell paste**: Click a cell to start editing, then press **Ctrl+V** (or **Cmd+V**). If the clipboard contains multiple rows/columns, the grid fills starting from that cell. Single-value paste works normally.\n- **Header Paste button**: Click the **Paste** button in the toolbar to paste clipboard data starting from the top-left cell.\n\nPasted data auto-expands rows if it extends beyond the existing table. Columns are capped at existing columns (use the Add Data flow to add new columns). Numeric values are parsed automatically.\n\n### Adding and Deleting Rows\n\n- Click **Add Row** in the header to append a blank row\n- Paste multiple rows from a spreadsheet to bulk-add data\n- Click the **trash icon** on any row to delete it\n\n### Applying Changes\n\nEdits are made on a local copy. Click **Apply Changes** to commit all edits — charts update immediately. Click **Cancel** to discard.\n\n### Status Indicators\n\n- **PASS / USL / LSL** badges show spec status for the outcome column\n- **Amber warning** icon marks excluded rows (hover for reason)\n- **Red alert** icon marks control violations (Azure App)\n\n---\n\n## Adding Data During Analysis (Azure App)\n\nThe Azure App lets you add more data to an existing analysis without starting over. Click the **\"Add Data\"** dropdown in the Editor toolbar to see three options:\n\n| Option | Use When |\n| ---------------- | -------------------------------------------------- |\n| **Paste Data** | You have additional rows or columns in a clipboard |\n| **Upload File** | You have a CSV/Excel file with new data |\n| **Manual Entry** | You want to type in additional measurements |\n\n### How It Works\n\nVariScout auto-detects whether the new data should be appended as rows or added as columns:\n\n- **Same columns** → rows are appended to the bottom of the dataset\n- **New columns** → columns are added side-by-side (index-aligned), and ColumnMapping opens for the new columns\n- **Completely different data** → a confirmation dialog asks before replacing the current dataset\n\nAfter adding data, a brief toast confirms the result (e.g., \"Added 50 rows\").\n\n> This feature is available in the Azure App only. The PWA loads data once per session.\n\n---\n\n## Manual Data Entry\n\nVariScout Lite includes a touch-optimized data entry mode for field use or when you need to quickly input measurements.\n\n### Accessing Manual Entry\n\n1. From the home screen, click **\"Or enter data manually\"** (below the Paste button)\n2. In the Azure App, also available via the **Manual Entry** option in the data menu\n\n### Step 1: Choose Analysis Mode\n\nSelect your analysis type:\n\n| Mode | Use Case | Output |\n| --------------------- | ------------------------------------- | ---------------- |\n| **Standard Analysis** | Factor-outcome analysis (Y = f(X)) | Dashboard |\n| **Performance Mode** | Multi-channel comparison (fill heads) | Performance view |\n\n### Step 1a: Standard Analysis Setup\n\n1. **Outcome (Y)**: Name of the measurement you're recording (e.g., \"Weight\", \"Diameter\", \"pH\")\n2. **Factors (X)**: Grouping variables (e.g., \"Operator\", \"Machine\", \"Batch\")\n - Click **+ Add Factor** to add more (up to 3 recommended)\n - Click the **X** to remove a factor\n3. Click **Continue** to proceed to data entry\n\n### Step 1b: Performance Mode Setup\n\n1. **Measure Label**: Base name for channels (e.g., \"Head\", \"Nozzle\", \"Cavity\")\n2. **Number of Channels**: How many parallel channels (3-20)\n - Preview shows generated column names (e.g., \"Head 1, Head 2, ...\")\n3. Click **Continue** to proceed to data entry\n\n### Step 2: Enter Your Data\n\nThe data entry grid has these features:\n\n#### Keyboard Navigation\n\n| Key | Action |\n| -------------------- | ------------------------------- |\n| `Tab` | Move to next cell |\n| `Shift+Tab` | Move to previous cell |\n| `Enter` | Move to next cell (same as Tab) |\n| `Enter` on last cell | Creates a new row |\n\n#### Touch-Optimized Design\n\n- Large **56px input fields** for easy tablet/phone use\n- Clear visual feedback on focus\n- **Add Row** button prominently placed\n\n#### Spec Limit Feedback\n\n1. Enter **USL** and/or **LSL** in the header area\n2. Each measurement shows instant visual feedback:\n - **Green border**: Within spec (PASS)\n - **Red border + text**: Exceeds USL\n - **Amber border + text**: Below LSL\n\n#### Running Statistics\n\nAs you enter data, live statistics appear:\n\n**Standard Mode:**\n\n- **Count**: Number of valid measurements\n- **Mean**: Running average\n- **Min/Max**: Range of values\n- **Pass Rate**: Percentage meeting specs (if limits defined)\n\n**Performance Mode:**\nPer-channel statistics cards showing:\n\n- **n**: Sample count per channel\n- **μ (Mean)**: Average value per channel\n- **Cpk**: Process capability index (when specs set)\n- **Status indicator**: Green (Cpk ≥ 1.33), Amber (1.0-1.33), Red (\u003C 1.0)\n\n#### Paste from Clipboard\n\nClick the **Paste** button to paste tab-separated data from Excel:\n\n1. Copy cells in Excel (columns should match your factor + outcome order)\n2. Click **Paste from Clipboard**\n3. Data is appended to existing rows\n\n### Analyzing Your Data\n\n1. Enter at least one measurement\n2. Click **Analyze** to proceed to the dashboard\n3. Your spec limits (if set) carry over to the analysis\n\n---\n\n## Data Import Formats\n\n### Supported File Types\n\n| Format | Extension | Notes |\n| ------ | --------- | ------------------------------------- |\n| CSV | `.csv` | Comma-separated, UTF-8 recommended |\n| Excel | `.xlsx` | First sheet only, first row = headers |\n\n### CSV Requirements\n\n```csv\nSupplier,Shift,Weight\nFarm A,Morning,325.5\nFarm B,Afternoon,318.2\nFarm A,Morning,330.1\n```\n\n- **First row**: Column headers (required)\n- **Encoding**: UTF-8 preferred (for international characters)\n- **Delimiter**: Comma (`,`)\n- **Numeric columns**: Use period (`.`) for decimals\n\n### Excel Requirements\n\n- **Sheet**: Only the first sheet is read\n- **Headers**: First row must contain column names\n- **Data types**: Numeric columns should be formatted as numbers\n- **Limit**: Maximum 50,000 rows\n\n### Data Size Limits\n\n| Threshold | Behavior |\n| ------------------- | ------------------------------------- |\n| \u003C 5,000 rows | Loads immediately |\n| 5,000 - 50,000 rows | Warning prompt (may slow performance) |\n| > 50,000 rows | Rejected (file too large) |\n\n### Data Validation\n\nWhen you upload a file, VariScout automatically validates your data and shows a summary:\n\n**What Gets Validated:**\n\n- The outcome column (Y) is checked for valid numeric values\n- Rows with missing or non-numeric values are excluded from analysis\n\n**Validation Summary Banner:**\nAfter uploading, you'll see a banner showing:\n\n- Total rows in the file\n- Valid rows ready for analysis\n- Excluded rows with reasons (if any)\n\n**Viewing Excluded Rows:**\n\n1. Click **\"View Excluded Rows\"** in the validation banner\n2. The Data Table opens filtered to show only problem rows\n3. Excluded rows are highlighted with an amber background\n4. Hover over the warning icon to see the specific issue\n\n**Common Issues:**\n| Issue | Cause | Solution |\n|-------|-------|----------|\n| Missing values | Empty cells in outcome column | Fill in values or remove rows in source file |\n| Non-numeric values | Text like \"N/A\" or \"pending\" | Replace with numbers or remove rows |\n\nValidation is informational — your analysis proceeds with valid rows. You can inspect issues anytime via the Data Table.\n\n### Pareto Data Source\n\nBy default, the Pareto chart counts occurrences from your selected factors. For some use cases, you may want to use pre-aggregated data instead.\n\n**Default: Derived from Factors**\n\n- Counts computed automatically from your data\n- Updates when you apply filters\n- Uses the selected factor for grouping\n\n**Optional: Separate Pareto File**\n\nIf you have pre-aggregated counts (e.g., from ERP or MES systems):\n\n1. In the column mapping screen, scroll to **\"Pareto Source\"**\n2. Drop a CSV/Excel file with category + count columns\n3. The chart will use this data instead\n\n**Important:** Separate Pareto data is NOT linked to main data filters. When you filter your process data, the Pareto chart won't update if using a separate file.\n\n### Auto-Detection\n\nVariScout uses smart keyword-based detection to suggest column roles:\n\n**Outcome (Y) Detection** — Numeric columns containing:\n\n- Measurement terms: `weight`, `length`, `width`, `height`, `thickness`\n- Time metrics: `time`, `duration`, `cycle`, `lead`, `ct`\n- Process values: `temperature`, `pressure`, `yield`, `output`\n\n**Factor (X) Detection** — Categorical columns containing:\n\n- Process factors: `shift`, `operator`, `machine`, `line`, `station`\n- Grouping terms: `product`, `batch`, `supplier`, `lot`, `team`\n\n**Time Column Detection** — Columns containing:\n\n- `date`, `time`, `timestamp`, `datetime`, `created`, `recorded`\n\nThe detection algorithm also:\n\n- Analyzes multiple rows (not just the first) to determine column types\n- Prioritizes keyword matches over simple type detection\n- Limits factors to 3 columns maximum\n\nYou can always override these suggestions in the column mapping screen.\n\n---\n\n## Annotating Charts\n\nYou can add text notes to any chart and, on Boxplot and Pareto, apply highlight colors to categories — useful for marking findings before exporting charts for reports.\n\n### Boxplot and Pareto: Highlighting a Category\n\n1. **Right-click** any boxplot box or pareto bar\n2. A context menu appears with color options: Red, Amber, Green\n3. **Click a color** to apply the highlight — the box/bar fills with that color\n4. To remove a highlight, right-click and choose **Clear highlight**\n\n### Boxplot and Pareto: Adding a Text Note\n\n1. **Right-click** the box/bar you want to annotate\n2. Click **\"+ Add note\"** in the context menu\n3. A text box appears anchored to that category\n4. **Click the text** to edit it — type your note, then click away to save\n5. **Drag the text box** to reposition it relative to the anchor\n6. **Drag the right edge** to resize the width\n7. **Hover** and click **×** to delete the note\n\n### I-Chart: Adding a Free-Floating Text Note\n\n1. **Right-click** anywhere in the I-Chart area\n2. A text note appears immediately at the click position — no context menu\n3. **Click the text** to edit it, then click away to save\n4. **Drag the note** to reposition it anywhere on the chart\n5. **Drag the right edge** to resize the width\n6. **Hover** and click **×** to delete the note\n\nI-Chart notes are **free-floating**: they are anchored to a percentage position within the chart area, not to a data point. Notes remain at their visual position when you filter data or change the time range.\n\nNote: I-Chart dots use fixed semantic colors (blue = in-control, red = violation). Highlight colors are not available for I-Chart dots.\n\n### Clearing All Annotations\n\n- Each chart card shows a small **×** button in the header when annotations exist\n- Click it to clear all highlights and text notes for that chart\n\n### Important Behavior\n\n- **Left-click always does drill-down** — annotations don't interfere with normal navigation\n- When you filter, sort, or drill-down Boxplot/Pareto notes **snap back to their default position** (offsets reset); I-Chart notes stay at their percentage position\n- Boxplot/Pareto notes are **hidden** when their anchor category is filtered out\n- Annotations appear in **copy-to-clipboard** chart images (PNG)\n\n---\n\n## Point Selection (Brushing)\n\nYou can select points directly on the I-Chart to create ad-hoc grouping factors.\n\n### How to Select\n\n| Action | Effect |\n| ------------- | ----------------------------------------- |\n| Drag on chart | Draw a selection rectangle (brush) |\n| Ctrl+click | Toggle a single point in/out of selection |\n| Shift+click | Add a single point to the selection |\n| Esc | Clear the selection |\n\n### Create Factor Workflow\n\n1. Select points on the I-Chart using any combination of drag and click\n2. The **Selection Panel** appears showing the count of selected points\n3. Click **\"Create Factor\"** and enter a name (e.g., \"Startup batch\")\n4. A new factor column is created with your named group and \"Other\"\n5. The dashboard auto-filters to show your selected points — continue analysis with Boxplot, Pareto, and Capability\n\nThis is useful when you spot instability patterns on the I-Chart that don't align with any existing factor in your data.\n\n---\n\n## Tips & Tricks\n\n- **Keyboard Shortcuts**: Press `Esc` to instantly clear all chart filters.\n- **Reset Scaling**: If you manually zoomed or panned, double-click the chart area or use the \"Reset\" button in scale settings to fit to data.\n- **Large Mode**: Presenting to a group? Open Settings (⚙) and toggle \"Large Mode\" for 30% larger text.\n- **Export Charts**: Use the Share button (↗) to export charts as PNG images.\n- **Linked Filtering**: Click any bar in Pareto or group in Boxplot to filter all charts instantly.\n- **Focus Mode**: Click the fullscreen icon (⛶) to maximize. **Use Arrow Keys (Left/Right)** or on-screen buttons to cycle through charts like a slideshow.\n- **Data Table**: Toggle the Data Panel (📊) to view raw data alongside your charts. Click a row to highlight it in the chart.\n- **Save Project** (Azure App): Use the Save button to save your work to the browser. The PWA is session-only — data is cleared on refresh.\n\n---\n\n## Troubleshooting / FAQ\n\n### Data Issues\n\n**Q: My data isn't showing up after upload**\n\nA: Check that:\n\n1. Your file has a header row\n2. At least one column contains numeric data\n3. File size is under 50,000 rows\n\n**Q: Numeric column is being treated as text**\n\nA: Excel may format numbers as text. Re-format the column as \"Number\" in Excel and re-export.\n\n**Q: Special characters (é, ü, etc.) look wrong**\n\nA: Save your CSV as UTF-8 encoding. In Excel: Save As → CSV UTF-8.\n\n### Charts\n\n**Q: I-Chart control limits seem wrong**\n\nA: Control limits (UCL/LCL) are calculated from your data using the 3-sigma rule:\n\n- UCL = Mean + 3 × StdDev\n- LCL = Mean − 3 × StdDev\n\nThey reflect what your process **is doing**, not what it **should do**. Specification limits (USL/LSL) are separate.\n\n**Q: Charts are too small on my screen**\n\nA: Enable **Large Mode** in Settings for 30% larger fonts and touch targets.\n\n### Offline Use\n\n**Q: Can I use VariScout without internet?**\n\nA: Yes! After visiting once, the app caches itself via Service Worker for offline use.\n\n**Q: Where is my data stored?**\n\nA: All data stays in your browser — nothing is sent to any server.\n\n- **Azure App**: Save analyses to IndexedDB + sync to OneDrive. Click **\"Save\"** in the toolbar.\n- **PWA (Free)**: Session-only — data lives in memory and is cleared on refresh. No save feature.\n\n### Export\n\n**Q: How do I share my analysis?**\n\nA: Click the **Share icon (↗)** in the header to see export options:\n\n- **Export Image (PNG)**: Save charts as images for presentations\n- **Export Data (CSV)**: Download the filtered data as a spreadsheet\n- **Download Project (.vrs)**: Save the complete analysis for sharing (Azure App only)\n\nIn the Azure App, others can import .vrs files by clicking the **Logo** and selecting **\"Open Project\"**.", + "src/content/docs/03-features/user-guide.md", + "b4e739b0c84bfa7e", + { "html": 1122, "metadata": 1123 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"variscout-lite-user-guide\">VariScout Lite: User Guide\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-lite-user-guide\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout Lite: User Guide”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This guide covers advanced features and workflows in VariScout Lite, focusing on interactive customization and specification management.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interactive-chart-customization\">Interactive Chart Customization\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interactive-chart-customization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interactive Chart Customization”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout Lite allows you to customize chart labels and axis names directly on the dashboard without altering your original data source. This is called \u003Cstrong>Aliasing\u003C/strong>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"column-renaming-at-setup\">Column Renaming at Setup\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#column-renaming-at-setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Column Renaming at Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You can rename columns during the column mapping step, before analysis begins.\u003C/p>\n\u003Col>\n\u003Cli>After pasting or uploading data, the \u003Cstrong>ColumnMapping\u003C/strong> screen shows each column as a data-rich card with a type badge, sample values, and unique count.\u003C/li>\n\u003Cli>Click the \u003Cstrong>pencil icon\u003C/strong> on any column card.\u003C/li>\n\u003Cli>Type a new name in the inline input, then press \u003Cstrong>Enter\u003C/strong> or click away to save.\u003C/li>\n\u003Cli>The alias persists through the analysis — filter chips, chart axes, and breadcrumbs all use the renamed label.\u003C/li>\n\u003Cli>The original column name appears as a subtitle on the card for reference.\u003C/li>\n\u003C/ol>\n\u003Cp>This is useful when your source data has cryptic column headers (e.g., “COL_3”) and you want human-readable names from the start.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"renaming-axis-titles\">Renaming Axis Titles\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#renaming-axis-titles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Renaming Axis Titles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You can rename the Y-axis (Outcome) and X-axis (Factor/Category) labels to make charts more presentation-ready.\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Hover\u003C/strong> over any axis label (e.g., “Weight” on the Y-axis). The cursor will change to a pointer.\u003C/li>\n\u003Cli>\u003Cstrong>Click\u003C/strong> the label. A small popup editor will appear.\u003C/li>\n\u003Cli>\u003Cstrong>Type\u003C/strong> the new name (e.g., “Net Weight (g)”).\u003C/li>\n\u003Cli>\u003Cstrong>Click Save\u003C/strong> (Check icon).\n\u003Cul>\n\u003Cli>\u003Cem>Note: This creates an “alias”. Your original data column name remains unchanged.\u003C/em>\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"renaming-categories-boxplot\">Renaming Categories (Boxplot)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#renaming-categories-boxplot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Renaming Categories (Boxplot)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>If your data has cryptic codes (e.g., “M1”, “M2”), you can rename them to meaningful labels (e.g., “Machine 1”, “Machine 2”) directly on the Boxplot.\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Click\u003C/strong> the X-axis label of the Boxplot (e.g., “MachineID”).\u003C/li>\n\u003Cli>The \u003Cstrong>Label & Category Editor\u003C/strong> will open.\u003C/li>\n\u003Cli>You will see a list of all unique values found in that column.\u003C/li>\n\u003Cli>Enter a \u003Cstrong>Display Name\u003C/strong> next to any value you wish to rename.\u003C/li>\n\u003Cli>\u003Cstrong>Click Save\u003C/strong>. The chart will update immediately.\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"specification-management\">Specification Management\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#specification-management\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Specification Management”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Specifications (Spec Limits) define what is considered “acceptable” quality. VariScout Lite supports both standard limits and complex multi-tier grading.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"setting-specifications--two-entry-points\">Setting Specifications — Two Entry Points\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#setting-specifications--two-entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Setting Specifications — Two Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You can set specification limits at two points in the workflow. Both approaches auto-apply on blur; there is no separate Apply button.\u003C/p>\n\u003Cp>\u003Cstrong>Option 1: During Column Mapping (optional, at setup time)\u003C/strong>\u003C/p>\n\u003Cp>The ColumnMapping screen shows each column as a data-rich card with type badge (Numeric, Categorical, Date), sample values, and unique count. At the bottom, a collapsible \u003Cstrong>“Set Specification Limits”\u003C/strong> section is available (collapsed by default).\u003C/p>\n\u003Col>\n\u003Cli>After pasting or uploading data, review the column cards and confirm your outcome and factor selections.\u003C/li>\n\u003Cli>Scroll to the bottom and click \u003Cstrong>“Set Specification Limits”\u003C/strong> to expand the section.\u003C/li>\n\u003Cli>Enter any combination of \u003Cstrong>Target\u003C/strong>, \u003Cstrong>LSL\u003C/strong>, and \u003Cstrong>USL\u003C/strong> — all three are optional.\u003C/li>\n\u003Cli>Continue to analysis. The values carry over automatically.\u003C/li>\n\u003C/ol>\n\u003Cp>This is the fastest path when you already know your spec limits before starting.\u003C/p>\n\u003Cp>\u003Cstrong>Option 2: Inline in the Stats Panel (at analysis time)\u003C/strong>\u003C/p>\n\u003Cp>If you reach the dashboard without specs set, the Stats Panel shows an inline entry area instead of silently omitting Cp/Cpk/Pass Rate.\u003C/p>\n\u003Col>\n\u003Cli>Look for the \u003Cstrong>“Set a target to enable Cp/Cpk”\u003C/strong> prompt in the Stats Panel.\u003C/li>\n\u003Cli>Enter a \u003Cstrong>Target\u003C/strong> value first (lowest commitment — unlocks partial feedback).\u003C/li>\n\u003Cli>Click \u003Cstrong>”+ LSL/USL”\u003C/strong> to expand and add the full specification range.\u003C/li>\n\u003Cli>Click or tab away from the field — values apply immediately.\u003C/li>\n\u003Cli>The inline entry area transforms into the normal Cp/Cpk/Pass Rate stat cards.\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Option 3: Via the Specs dropdown in the I-Chart header\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>In the \u003Cstrong>I-Chart header\u003C/strong>, click the \u003Cstrong>“Specs”\u003C/strong> dropdown button.\u003C/li>\n\u003Cli>A popover will appear with checkboxes and input fields for each limit.\u003C/li>\n\u003Cli>Enter your limits:\n\u003Cul>\n\u003Cli>\u003Cstrong>USL (Upper Spec Limit)\u003C/strong>: Maximum acceptable value.\u003C/li>\n\u003Cli>\u003Cstrong>LSL (Lower Spec Limit)\u003C/strong>: Minimum acceptable value.\u003C/li>\n\u003Cli>\u003Cstrong>Target\u003C/strong>: Ideal value (optional, drawn in green).\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>Use the checkboxes to toggle visibility of each limit on the chart.\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Result (any entry point):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Red dotted lines appear on charts (I-Chart & Boxplot).\u003C/li>\n\u003Cli>Cp, Cpk, and Pass/Fail rates are instantly calculated in the Stats Panel.\u003C/li>\n\u003Cli>Histogram updates to show spec boundaries.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visualization-options\">Visualization Options\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visualization-options\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visualization Options”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You can toggle visibility of chart elements and change display settings in the \u003Cstrong>Settings Panel\u003C/strong>.\u003C/p>\n\u003Col>\n\u003Cli>Click the \u003Cstrong>Settings icon (⚙)\u003C/strong> in the top right of the header.\u003C/li>\n\u003Cli>The Settings Panel will slide in from the right.\u003C/li>\n\u003Cli>In the \u003Cstrong>“Display Options”\u003C/strong> section, toggle:\n\u003Cul>\n\u003Cli>\u003Cstrong>Lock Y-axis when drilling\u003C/strong>: Keep the Y-axis scale consistent when filtering data.\u003C/li>\n\u003Cli>\u003Cstrong>Show Control Limits\u003C/strong>: Display UCL/Mean/LCL lines on the I-Chart (statistical process control limits based on 3-sigma rule).\u003C/li>\n\u003Cli>\u003Cstrong>Show distribution shape\u003C/strong>: Overlay density curves (violin plots) on boxplots to reveal distribution shape, bimodality, and skewness.\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>In the \u003Cstrong>“Y-Axis Scale Mode”\u003C/strong> section, choose:\n\u003Cul>\n\u003Cli>\u003Cstrong>Auto\u003C/strong>: Automatically fit scale to data and specification limits.\u003C/li>\n\u003Cli>\u003Cstrong>Start at Zero\u003C/strong>: Force Y-axis minimum to zero (useful for ratio data).\u003C/li>\n\u003Cli>\u003Cstrong>Manual\u003C/strong>: Set explicit Min and Max values for the Y-axis.\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>Spec limit visibility (USL/LSL/Target) is now controlled via the \u003Cstrong>Specs dropdown\u003C/strong> in the I-Chart header.\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"editing-data\">Editing Data\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#editing-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Editing Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After loading data, you can edit individual values, add rows, or delete rows directly in the \u003Cstrong>Data Table Editor\u003C/strong> without re-importing your dataset.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"opening-the-editor\">Opening the Editor\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#opening-the-editor\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Opening the Editor”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>PWA\u003C/strong>: Click the \u003Cstrong>Data Table\u003C/strong> button in the toolbar\u003C/li>\n\u003Cli>\u003Cstrong>Azure App\u003C/strong>: Click the \u003Cstrong>Pencil\u003C/strong> icon in the toolbar, or the pencil button in the DataPanel header\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"editing-cells\">Editing Cells\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#editing-cells\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Editing Cells”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Click\u003C/strong> any cell to start editing — the cell turns into a text input\u003C/li>\n\u003Cli>Type the new value\u003C/li>\n\u003Cli>Use keyboard shortcuts to navigate:\u003C/li>\n\u003C/ol>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Key\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Tab\u003C/code>\u003C/td>\u003Ctd>Move to next column (wraps to next row)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Shift+Tab\u003C/code>\u003C/td>\u003Ctd>Move to previous column (wraps to previous row)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Enter\u003C/code>\u003C/td>\u003Ctd>Move to next row (same column)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Arrow Up\u003C/code>\u003C/td>\u003Ctd>Move to previous row (same column)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Arrow Down\u003C/code>\u003C/td>\u003Ctd>Move to next row (same column)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Escape\u003C/code>\u003C/td>\u003Ctd>Cancel edit\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Col start=\"4\">\n\u003Cli>Edited values show an \u003Cstrong>(unsaved changes)\u003C/strong> indicator in the header\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"multi-cell-paste\">Multi-cell Paste\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#multi-cell-paste\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Multi-cell Paste”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You can paste tab-delimited data (e.g. from Excel or Google Sheets) directly into the table:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>In-cell paste\u003C/strong>: Click a cell to start editing, then press \u003Cstrong>Ctrl+V\u003C/strong> (or \u003Cstrong>Cmd+V\u003C/strong>). If the clipboard contains multiple rows/columns, the grid fills starting from that cell. Single-value paste works normally.\u003C/li>\n\u003Cli>\u003Cstrong>Header Paste button\u003C/strong>: Click the \u003Cstrong>Paste\u003C/strong> button in the toolbar to paste clipboard data starting from the top-left cell.\u003C/li>\n\u003C/ul>\n\u003Cp>Pasted data auto-expands rows if it extends beyond the existing table. Columns are capped at existing columns (use the Add Data flow to add new columns). Numeric values are parsed automatically.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"adding-and-deleting-rows\">Adding and Deleting Rows\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#adding-and-deleting-rows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Adding and Deleting Rows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Click \u003Cstrong>Add Row\u003C/strong> in the header to append a blank row\u003C/li>\n\u003Cli>Paste multiple rows from a spreadsheet to bulk-add data\u003C/li>\n\u003Cli>Click the \u003Cstrong>trash icon\u003C/strong> on any row to delete it\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"applying-changes\">Applying Changes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#applying-changes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Applying Changes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Edits are made on a local copy. Click \u003Cstrong>Apply Changes\u003C/strong> to commit all edits — charts update immediately. Click \u003Cstrong>Cancel\u003C/strong> to discard.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"status-indicators\">Status Indicators\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#status-indicators\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Status Indicators”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>PASS / USL / LSL\u003C/strong> badges show spec status for the outcome column\u003C/li>\n\u003Cli>\u003Cstrong>Amber warning\u003C/strong> icon marks excluded rows (hover for reason)\u003C/li>\n\u003Cli>\u003Cstrong>Red alert\u003C/strong> icon marks control violations (Azure App)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"adding-data-during-analysis-azure-app\">Adding Data During Analysis (Azure App)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#adding-data-during-analysis-azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Adding Data During Analysis (Azure App)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure App lets you add more data to an existing analysis without starting over. Click the \u003Cstrong>“Add Data”\u003C/strong> dropdown in the Editor toolbar to see three options:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Option\u003C/th>\u003Cth>Use When\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Paste Data\u003C/strong>\u003C/td>\u003Ctd>You have additional rows or columns in a clipboard\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Upload File\u003C/strong>\u003C/td>\u003Ctd>You have a CSV/Excel file with new data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Manual Entry\u003C/strong>\u003C/td>\u003Ctd>You want to type in additional measurements\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"how-it-works\">How It Works\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#how-it-works\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How It Works”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout auto-detects whether the new data should be appended as rows or added as columns:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Same columns\u003C/strong> → rows are appended to the bottom of the dataset\u003C/li>\n\u003Cli>\u003Cstrong>New columns\u003C/strong> → columns are added side-by-side (index-aligned), and ColumnMapping opens for the new columns\u003C/li>\n\u003Cli>\u003Cstrong>Completely different data\u003C/strong> → a confirmation dialog asks before replacing the current dataset\u003C/li>\n\u003C/ul>\n\u003Cp>After adding data, a brief toast confirms the result (e.g., “Added 50 rows”).\u003C/p>\n\u003Cblockquote>\n\u003Cp>This feature is available in the Azure App only. The PWA loads data once per session.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"manual-data-entry\">Manual Data Entry\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#manual-data-entry\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Manual Data Entry”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout Lite includes a touch-optimized data entry mode for field use or when you need to quickly input measurements.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"accessing-manual-entry\">Accessing Manual Entry\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#accessing-manual-entry\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Accessing Manual Entry”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>From the home screen, click \u003Cstrong>“Or enter data manually”\u003C/strong> (below the Paste button)\u003C/li>\n\u003Cli>In the Azure App, also available via the \u003Cstrong>Manual Entry\u003C/strong> option in the data menu\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-1-choose-analysis-mode\">Step 1: Choose Analysis Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-choose-analysis-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Choose Analysis Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Select your analysis type:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Mode\u003C/th>\u003Cth>Use Case\u003C/th>\u003Cth>Output\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Standard Analysis\u003C/strong>\u003C/td>\u003Ctd>Factor-outcome analysis (Y = f(X))\u003C/td>\u003Ctd>Dashboard\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Performance Mode\u003C/strong>\u003C/td>\u003Ctd>Multi-channel comparison (fill heads)\u003C/td>\u003Ctd>Performance view\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-1a-standard-analysis-setup\">Step 1a: Standard Analysis Setup\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-1a-standard-analysis-setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1a: Standard Analysis Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Outcome (Y)\u003C/strong>: Name of the measurement you’re recording (e.g., “Weight”, “Diameter”, “pH”)\u003C/li>\n\u003Cli>\u003Cstrong>Factors (X)\u003C/strong>: Grouping variables (e.g., “Operator”, “Machine”, “Batch”)\n\u003Cul>\n\u003Cli>Click \u003Cstrong>+ Add Factor\u003C/strong> to add more (up to 3 recommended)\u003C/li>\n\u003Cli>Click the \u003Cstrong>X\u003C/strong> to remove a factor\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>Click \u003Cstrong>Continue\u003C/strong> to proceed to data entry\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-1b-performance-mode-setup\">Step 1b: Performance Mode Setup\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-1b-performance-mode-setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1b: Performance Mode Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Measure Label\u003C/strong>: Base name for channels (e.g., “Head”, “Nozzle”, “Cavity”)\u003C/li>\n\u003Cli>\u003Cstrong>Number of Channels\u003C/strong>: How many parallel channels (3-20)\n\u003Cul>\n\u003Cli>Preview shows generated column names (e.g., “Head 1, Head 2, …”)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>Click \u003Cstrong>Continue\u003C/strong> to proceed to data entry\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-2-enter-your-data\">Step 2: Enter Your Data\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-enter-your-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Enter Your Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The data entry grid has these features:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"keyboard-navigation\">Keyboard Navigation\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#keyboard-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyboard Navigation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Key\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Tab\u003C/code>\u003C/td>\u003Ctd>Move to next cell\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Shift+Tab\u003C/code>\u003C/td>\u003Ctd>Move to previous cell\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Enter\u003C/code>\u003C/td>\u003Ctd>Move to next cell (same as Tab)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Enter\u003C/code> on last cell\u003C/td>\u003Ctd>Creates a new row\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"touch-optimized-design\">Touch-Optimized Design\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#touch-optimized-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Touch-Optimized Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Large \u003Cstrong>56px input fields\u003C/strong> for easy tablet/phone use\u003C/li>\n\u003Cli>Clear visual feedback on focus\u003C/li>\n\u003Cli>\u003Cstrong>Add Row\u003C/strong> button prominently placed\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"spec-limit-feedback\">Spec Limit Feedback\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#spec-limit-feedback\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Spec Limit Feedback”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Enter \u003Cstrong>USL\u003C/strong> and/or \u003Cstrong>LSL\u003C/strong> in the header area\u003C/li>\n\u003Cli>Each measurement shows instant visual feedback:\n\u003Cul>\n\u003Cli>\u003Cstrong>Green border\u003C/strong>: Within spec (PASS)\u003C/li>\n\u003Cli>\u003Cstrong>Red border + text\u003C/strong>: Exceeds USL\u003C/li>\n\u003Cli>\u003Cstrong>Amber border + text\u003C/strong>: Below LSL\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"running-statistics\">Running Statistics\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#running-statistics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Running Statistics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>As you enter data, live statistics appear:\u003C/p>\n\u003Cp>\u003Cstrong>Standard Mode:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Count\u003C/strong>: Number of valid measurements\u003C/li>\n\u003Cli>\u003Cstrong>Mean\u003C/strong>: Running average\u003C/li>\n\u003Cli>\u003Cstrong>Min/Max\u003C/strong>: Range of values\u003C/li>\n\u003Cli>\u003Cstrong>Pass Rate\u003C/strong>: Percentage meeting specs (if limits defined)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Performance Mode:\u003C/strong>\nPer-channel statistics cards showing:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>n\u003C/strong>: Sample count per channel\u003C/li>\n\u003Cli>\u003Cstrong>μ (Mean)\u003C/strong>: Average value per channel\u003C/li>\n\u003Cli>\u003Cstrong>Cpk\u003C/strong>: Process capability index (when specs set)\u003C/li>\n\u003Cli>\u003Cstrong>Status indicator\u003C/strong>: Green (Cpk ≥ 1.33), Amber (1.0-1.33), Red (< 1.0)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"paste-from-clipboard\">Paste from Clipboard\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#paste-from-clipboard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Paste from Clipboard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click the \u003Cstrong>Paste\u003C/strong> button to paste tab-separated data from Excel:\u003C/p>\n\u003Col>\n\u003Cli>Copy cells in Excel (columns should match your factor + outcome order)\u003C/li>\n\u003Cli>Click \u003Cstrong>Paste from Clipboard\u003C/strong>\u003C/li>\n\u003Cli>Data is appended to existing rows\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"analyzing-your-data\">Analyzing Your Data\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#analyzing-your-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analyzing Your Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Enter at least one measurement\u003C/li>\n\u003Cli>Click \u003Cstrong>Analyze\u003C/strong> to proceed to the dashboard\u003C/li>\n\u003Cli>Your spec limits (if set) carry over to the analysis\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-import-formats\">Data Import Formats\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-import-formats\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Import Formats”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"supported-file-types\">Supported File Types\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#supported-file-types\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Supported File Types”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Format\u003C/th>\u003Cth>Extension\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>CSV\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">.csv\u003C/code>\u003C/td>\u003Ctd>Comma-separated, UTF-8 recommended\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">.xlsx\u003C/code>\u003C/td>\u003Ctd>First sheet only, first row = headers\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"csv-requirements\">CSV Requirements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#csv-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CSV Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"csv\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Supplier,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Shift,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Weight\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Farm A,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Morning,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">325.5\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Farm B,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Afternoon,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">318.2\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Farm A,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Morning,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">330.1\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Supplier,Shift,WeightFarm A,Morning,325.5Farm B,Afternoon,318.2Farm A,Morning,330.1\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>First row\u003C/strong>: Column headers (required)\u003C/li>\n\u003Cli>\u003Cstrong>Encoding\u003C/strong>: UTF-8 preferred (for international characters)\u003C/li>\n\u003Cli>\u003Cstrong>Delimiter\u003C/strong>: Comma (\u003Ccode dir=\"auto\">,\u003C/code>)\u003C/li>\n\u003Cli>\u003Cstrong>Numeric columns\u003C/strong>: Use period (\u003Ccode dir=\"auto\">.\u003C/code>) for decimals\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"excel-requirements\">Excel Requirements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#excel-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Excel Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Sheet\u003C/strong>: Only the first sheet is read\u003C/li>\n\u003Cli>\u003Cstrong>Headers\u003C/strong>: First row must contain column names\u003C/li>\n\u003Cli>\u003Cstrong>Data types\u003C/strong>: Numeric columns should be formatted as numbers\u003C/li>\n\u003Cli>\u003Cstrong>Limit\u003C/strong>: Maximum 50,000 rows\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-size-limits\">Data Size Limits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-size-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Size Limits”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Threshold\u003C/th>\u003Cth>Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>< 5,000 rows\u003C/td>\u003Ctd>Loads immediately\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5,000 - 50,000 rows\u003C/td>\u003Ctd>Warning prompt (may slow performance)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>> 50,000 rows\u003C/td>\u003Ctd>Rejected (file too large)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-validation\">Data Validation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When you upload a file, VariScout automatically validates your data and shows a summary:\u003C/p>\n\u003Cp>\u003Cstrong>What Gets Validated:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>The outcome column (Y) is checked for valid numeric values\u003C/li>\n\u003Cli>Rows with missing or non-numeric values are excluded from analysis\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Validation Summary Banner:\u003C/strong>\nAfter uploading, you’ll see a banner showing:\u003C/p>\n\u003Cul>\n\u003Cli>Total rows in the file\u003C/li>\n\u003Cli>Valid rows ready for analysis\u003C/li>\n\u003Cli>Excluded rows with reasons (if any)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Viewing Excluded Rows:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Click \u003Cstrong>“View Excluded Rows”\u003C/strong> in the validation banner\u003C/li>\n\u003Cli>The Data Table opens filtered to show only problem rows\u003C/li>\n\u003Cli>Excluded rows are highlighted with an amber background\u003C/li>\n\u003Cli>Hover over the warning icon to see the specific issue\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Common Issues:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Issue\u003C/th>\u003Cth>Cause\u003C/th>\u003Cth>Solution\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Missing values\u003C/td>\u003Ctd>Empty cells in outcome column\u003C/td>\u003Ctd>Fill in values or remove rows in source file\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Non-numeric values\u003C/td>\u003Ctd>Text like “N/A” or “pending”\u003C/td>\u003Ctd>Replace with numbers or remove rows\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Validation is informational — your analysis proceeds with valid rows. You can inspect issues anytime via the Data Table.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pareto-data-source\">Pareto Data Source\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pareto-data-source\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pareto Data Source”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>By default, the Pareto chart counts occurrences from your selected factors. For some use cases, you may want to use pre-aggregated data instead.\u003C/p>\n\u003Cp>\u003Cstrong>Default: Derived from Factors\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Counts computed automatically from your data\u003C/li>\n\u003Cli>Updates when you apply filters\u003C/li>\n\u003Cli>Uses the selected factor for grouping\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Optional: Separate Pareto File\u003C/strong>\u003C/p>\n\u003Cp>If you have pre-aggregated counts (e.g., from ERP or MES systems):\u003C/p>\n\u003Col>\n\u003Cli>In the column mapping screen, scroll to \u003Cstrong>“Pareto Source”\u003C/strong>\u003C/li>\n\u003Cli>Drop a CSV/Excel file with category + count columns\u003C/li>\n\u003Cli>The chart will use this data instead\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Important:\u003C/strong> Separate Pareto data is NOT linked to main data filters. When you filter your process data, the Pareto chart won’t update if using a separate file.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"auto-detection\">Auto-Detection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#auto-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Auto-Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses smart keyword-based detection to suggest column roles:\u003C/p>\n\u003Cp>\u003Cstrong>Outcome (Y) Detection\u003C/strong> — Numeric columns containing:\u003C/p>\n\u003Cul>\n\u003Cli>Measurement terms: \u003Ccode dir=\"auto\">weight\u003C/code>, \u003Ccode dir=\"auto\">length\u003C/code>, \u003Ccode dir=\"auto\">width\u003C/code>, \u003Ccode dir=\"auto\">height\u003C/code>, \u003Ccode dir=\"auto\">thickness\u003C/code>\u003C/li>\n\u003Cli>Time metrics: \u003Ccode dir=\"auto\">time\u003C/code>, \u003Ccode dir=\"auto\">duration\u003C/code>, \u003Ccode dir=\"auto\">cycle\u003C/code>, \u003Ccode dir=\"auto\">lead\u003C/code>, \u003Ccode dir=\"auto\">ct\u003C/code>\u003C/li>\n\u003Cli>Process values: \u003Ccode dir=\"auto\">temperature\u003C/code>, \u003Ccode dir=\"auto\">pressure\u003C/code>, \u003Ccode dir=\"auto\">yield\u003C/code>, \u003Ccode dir=\"auto\">output\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Factor (X) Detection\u003C/strong> — Categorical columns containing:\u003C/p>\n\u003Cul>\n\u003Cli>Process factors: \u003Ccode dir=\"auto\">shift\u003C/code>, \u003Ccode dir=\"auto\">operator\u003C/code>, \u003Ccode dir=\"auto\">machine\u003C/code>, \u003Ccode dir=\"auto\">line\u003C/code>, \u003Ccode dir=\"auto\">station\u003C/code>\u003C/li>\n\u003Cli>Grouping terms: \u003Ccode dir=\"auto\">product\u003C/code>, \u003Ccode dir=\"auto\">batch\u003C/code>, \u003Ccode dir=\"auto\">supplier\u003C/code>, \u003Ccode dir=\"auto\">lot\u003C/code>, \u003Ccode dir=\"auto\">team\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Time Column Detection\u003C/strong> — Columns containing:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">date\u003C/code>, \u003Ccode dir=\"auto\">time\u003C/code>, \u003Ccode dir=\"auto\">timestamp\u003C/code>, \u003Ccode dir=\"auto\">datetime\u003C/code>, \u003Ccode dir=\"auto\">created\u003C/code>, \u003Ccode dir=\"auto\">recorded\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>The detection algorithm also:\u003C/p>\n\u003Cul>\n\u003Cli>Analyzes multiple rows (not just the first) to determine column types\u003C/li>\n\u003Cli>Prioritizes keyword matches over simple type detection\u003C/li>\n\u003Cli>Limits factors to 3 columns maximum\u003C/li>\n\u003C/ul>\n\u003Cp>You can always override these suggestions in the column mapping screen.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"annotating-charts\">Annotating Charts\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#annotating-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Annotating Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You can add text notes to any chart and, on Boxplot and Pareto, apply highlight colors to categories — useful for marking findings before exporting charts for reports.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"boxplot-and-pareto-highlighting-a-category\">Boxplot and Pareto: Highlighting a Category\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#boxplot-and-pareto-highlighting-a-category\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Boxplot and Pareto: Highlighting a Category”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Right-click\u003C/strong> any boxplot box or pareto bar\u003C/li>\n\u003Cli>A context menu appears with color options: Red, Amber, Green\u003C/li>\n\u003Cli>\u003Cstrong>Click a color\u003C/strong> to apply the highlight — the box/bar fills with that color\u003C/li>\n\u003Cli>To remove a highlight, right-click and choose \u003Cstrong>Clear highlight\u003C/strong>\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"boxplot-and-pareto-adding-a-text-note\">Boxplot and Pareto: Adding a Text Note\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#boxplot-and-pareto-adding-a-text-note\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Boxplot and Pareto: Adding a Text Note”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Right-click\u003C/strong> the box/bar you want to annotate\u003C/li>\n\u003Cli>Click \u003Cstrong>”+ Add note”\u003C/strong> in the context menu\u003C/li>\n\u003Cli>A text box appears anchored to that category\u003C/li>\n\u003Cli>\u003Cstrong>Click the text\u003C/strong> to edit it — type your note, then click away to save\u003C/li>\n\u003Cli>\u003Cstrong>Drag the text box\u003C/strong> to reposition it relative to the anchor\u003C/li>\n\u003Cli>\u003Cstrong>Drag the right edge\u003C/strong> to resize the width\u003C/li>\n\u003Cli>\u003Cstrong>Hover\u003C/strong> and click \u003Cstrong>×\u003C/strong> to delete the note\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"i-chart-adding-a-free-floating-text-note\">I-Chart: Adding a Free-Floating Text Note\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#i-chart-adding-a-free-floating-text-note\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “I-Chart: Adding a Free-Floating Text Note”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Right-click\u003C/strong> anywhere in the I-Chart area\u003C/li>\n\u003Cli>A text note appears immediately at the click position — no context menu\u003C/li>\n\u003Cli>\u003Cstrong>Click the text\u003C/strong> to edit it, then click away to save\u003C/li>\n\u003Cli>\u003Cstrong>Drag the note\u003C/strong> to reposition it anywhere on the chart\u003C/li>\n\u003Cli>\u003Cstrong>Drag the right edge\u003C/strong> to resize the width\u003C/li>\n\u003Cli>\u003Cstrong>Hover\u003C/strong> and click \u003Cstrong>×\u003C/strong> to delete the note\u003C/li>\n\u003C/ol>\n\u003Cp>I-Chart notes are \u003Cstrong>free-floating\u003C/strong>: they are anchored to a percentage position within the chart area, not to a data point. Notes remain at their visual position when you filter data or change the time range.\u003C/p>\n\u003Cp>Note: I-Chart dots use fixed semantic colors (blue = in-control, red = violation). Highlight colors are not available for I-Chart dots.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"clearing-all-annotations\">Clearing All Annotations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#clearing-all-annotations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Clearing All Annotations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Each chart card shows a small \u003Cstrong>×\u003C/strong> button in the header when annotations exist\u003C/li>\n\u003Cli>Click it to clear all highlights and text notes for that chart\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"important-behavior\">Important Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#important-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Important Behavior”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Left-click always does drill-down\u003C/strong> — annotations don’t interfere with normal navigation\u003C/li>\n\u003Cli>When you filter, sort, or drill-down Boxplot/Pareto notes \u003Cstrong>snap back to their default position\u003C/strong> (offsets reset); I-Chart notes stay at their percentage position\u003C/li>\n\u003Cli>Boxplot/Pareto notes are \u003Cstrong>hidden\u003C/strong> when their anchor category is filtered out\u003C/li>\n\u003Cli>Annotations appear in \u003Cstrong>copy-to-clipboard\u003C/strong> chart images (PNG)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"point-selection-brushing\">Point Selection (Brushing)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#point-selection-brushing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Point Selection (Brushing)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You can select points directly on the I-Chart to create ad-hoc grouping factors.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"how-to-select\">How to Select\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#how-to-select\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How to Select”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>Effect\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Drag on chart\u003C/td>\u003Ctd>Draw a selection rectangle (brush)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Ctrl+click\u003C/td>\u003Ctd>Toggle a single point in/out of selection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shift+click\u003C/td>\u003Ctd>Add a single point to the selection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Esc\u003C/td>\u003Ctd>Clear the selection\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"create-factor-workflow\">Create Factor Workflow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#create-factor-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Create Factor Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Select points on the I-Chart using any combination of drag and click\u003C/li>\n\u003Cli>The \u003Cstrong>Selection Panel\u003C/strong> appears showing the count of selected points\u003C/li>\n\u003Cli>Click \u003Cstrong>“Create Factor”\u003C/strong> and enter a name (e.g., “Startup batch”)\u003C/li>\n\u003Cli>A new factor column is created with your named group and “Other”\u003C/li>\n\u003Cli>The dashboard auto-filters to show your selected points — continue analysis with Boxplot, Pareto, and Capability\u003C/li>\n\u003C/ol>\n\u003Cp>This is useful when you spot instability patterns on the I-Chart that don’t align with any existing factor in your data.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tips--tricks\">Tips & Tricks\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tips--tricks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tips & Tricks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Keyboard Shortcuts\u003C/strong>: Press \u003Ccode dir=\"auto\">Esc\u003C/code> to instantly clear all chart filters.\u003C/li>\n\u003Cli>\u003Cstrong>Reset Scaling\u003C/strong>: If you manually zoomed or panned, double-click the chart area or use the “Reset” button in scale settings to fit to data.\u003C/li>\n\u003Cli>\u003Cstrong>Large Mode\u003C/strong>: Presenting to a group? Open Settings (⚙) and toggle “Large Mode” for 30% larger text.\u003C/li>\n\u003Cli>\u003Cstrong>Export Charts\u003C/strong>: Use the Share button (↗) to export charts as PNG images.\u003C/li>\n\u003Cli>\u003Cstrong>Linked Filtering\u003C/strong>: Click any bar in Pareto or group in Boxplot to filter all charts instantly.\u003C/li>\n\u003Cli>\u003Cstrong>Focus Mode\u003C/strong>: Click the fullscreen icon (⛶) to maximize. \u003Cstrong>Use Arrow Keys (Left/Right)\u003C/strong> or on-screen buttons to cycle through charts like a slideshow.\u003C/li>\n\u003Cli>\u003Cstrong>Data Table\u003C/strong>: Toggle the Data Panel (📊) to view raw data alongside your charts. Click a row to highlight it in the chart.\u003C/li>\n\u003Cli>\u003Cstrong>Save Project\u003C/strong> (Azure App): Use the Save button to save your work to the browser. The PWA is session-only — data is cleared on refresh.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"troubleshooting--faq\">Troubleshooting / FAQ\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#troubleshooting--faq\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Troubleshooting / FAQ”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-issues\">Data Issues\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-issues\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Issues”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Q: My data isn’t showing up after upload\u003C/strong>\u003C/p>\n\u003Cp>A: Check that:\u003C/p>\n\u003Col>\n\u003Cli>Your file has a header row\u003C/li>\n\u003Cli>At least one column contains numeric data\u003C/li>\n\u003Cli>File size is under 50,000 rows\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Q: Numeric column is being treated as text\u003C/strong>\u003C/p>\n\u003Cp>A: Excel may format numbers as text. Re-format the column as “Number” in Excel and re-export.\u003C/p>\n\u003Cp>\u003Cstrong>Q: Special characters (é, ü, etc.) look wrong\u003C/strong>\u003C/p>\n\u003Cp>A: Save your CSV as UTF-8 encoding. In Excel: Save As → CSV UTF-8.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"charts\">Charts\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Q: I-Chart control limits seem wrong\u003C/strong>\u003C/p>\n\u003Cp>A: Control limits (UCL/LCL) are calculated from your data using the 3-sigma rule:\u003C/p>\n\u003Cul>\n\u003Cli>UCL = Mean + 3 × StdDev\u003C/li>\n\u003Cli>LCL = Mean − 3 × StdDev\u003C/li>\n\u003C/ul>\n\u003Cp>They reflect what your process \u003Cstrong>is doing\u003C/strong>, not what it \u003Cstrong>should do\u003C/strong>. Specification limits (USL/LSL) are separate.\u003C/p>\n\u003Cp>\u003Cstrong>Q: Charts are too small on my screen\u003C/strong>\u003C/p>\n\u003Cp>A: Enable \u003Cstrong>Large Mode\u003C/strong> in Settings for 30% larger fonts and touch targets.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"offline-use\">Offline Use\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#offline-use\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Offline Use”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Q: Can I use VariScout without internet?\u003C/strong>\u003C/p>\n\u003Cp>A: Yes! After visiting once, the app caches itself via Service Worker for offline use.\u003C/p>\n\u003Cp>\u003Cstrong>Q: Where is my data stored?\u003C/strong>\u003C/p>\n\u003Cp>A: All data stays in your browser — nothing is sent to any server.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Azure App\u003C/strong>: Save analyses to IndexedDB + sync to OneDrive. Click \u003Cstrong>“Save”\u003C/strong> in the toolbar.\u003C/li>\n\u003Cli>\u003Cstrong>PWA (Free)\u003C/strong>: Session-only — data lives in memory and is cleared on refresh. No save feature.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"export\">Export\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#export\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Export”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Q: How do I share my analysis?\u003C/strong>\u003C/p>\n\u003Cp>A: Click the \u003Cstrong>Share icon (↗)\u003C/strong> in the header to see export options:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Export Image (PNG)\u003C/strong>: Save charts as images for presentations\u003C/li>\n\u003Cli>\u003Cstrong>Export Data (CSV)\u003C/strong>: Download the filtered data as a spreadsheet\u003C/li>\n\u003Cli>\u003Cstrong>Download Project (.vrs)\u003C/strong>: Save the complete analysis for sharing (Azure App only)\u003C/li>\n\u003C/ul>\n\u003Cp>In the Azure App, others can import .vrs files by clicking the \u003Cstrong>Logo\u003C/strong> and selecting \u003Cstrong>“Open Project”\u003C/strong>.\u003C/p>", + { + "headings": 1124, + "localImagePaths": 1280, + "remoteImagePaths": 1281, + "frontmatter": 1282, + "imagePaths": 1283 + }, + [ + 1125, 1127, 1130, 1133, 1136, 1139, 1142, 1145, 1148, 1151, 1154, 1157, 1160, 1163, 1166, 1169, + 1172, 1175, 1178, 1181, 1184, 1187, 1190, 1193, 1196, 1199, 1202, 1205, 1208, 1211, 1214, 1217, + 1220, 1223, 1226, 1229, 1232, 1235, 1238, 1241, 1244, 1247, 1250, 1253, 1256, 1259, 1262, 1265, + 1268, 1271, 1274, 1277 + ], + { "depth": 30, "slug": 1126, "text": 1114 }, + "variscout-lite-user-guide", + { "depth": 33, "slug": 1128, "text": 1129 }, + "interactive-chart-customization", + "Interactive Chart Customization", + { "depth": 79, "slug": 1131, "text": 1132 }, + "column-renaming-at-setup", + "Column Renaming at Setup", + { "depth": 79, "slug": 1134, "text": 1135 }, + "renaming-axis-titles", + "Renaming Axis Titles", + { "depth": 79, "slug": 1137, "text": 1138 }, + "renaming-categories-boxplot", + "Renaming Categories (Boxplot)", + { "depth": 33, "slug": 1140, "text": 1141 }, + "specification-management", + "Specification Management", + { "depth": 79, "slug": 1143, "text": 1144 }, + "setting-specifications--two-entry-points", + "Setting Specifications — Two Entry Points", + { "depth": 33, "slug": 1146, "text": 1147 }, + "visualization-options", + "Visualization Options", + { "depth": 33, "slug": 1149, "text": 1150 }, + "editing-data", + "Editing Data", + { "depth": 79, "slug": 1152, "text": 1153 }, + "opening-the-editor", + "Opening the Editor", + { "depth": 79, "slug": 1155, "text": 1156 }, + "editing-cells", + "Editing Cells", + { "depth": 79, "slug": 1158, "text": 1159 }, + "multi-cell-paste", + "Multi-cell Paste", + { "depth": 79, "slug": 1161, "text": 1162 }, + "adding-and-deleting-rows", + "Adding and Deleting Rows", + { "depth": 79, "slug": 1164, "text": 1165 }, + "applying-changes", + "Applying Changes", + { "depth": 79, "slug": 1167, "text": 1168 }, + "status-indicators", + "Status Indicators", + { "depth": 33, "slug": 1170, "text": 1171 }, + "adding-data-during-analysis-azure-app", + "Adding Data During Analysis (Azure App)", + { "depth": 79, "slug": 1173, "text": 1174 }, + "how-it-works", + "How It Works", + { "depth": 33, "slug": 1176, "text": 1177 }, + "manual-data-entry", + "Manual Data Entry", + { "depth": 79, "slug": 1179, "text": 1180 }, + "accessing-manual-entry", + "Accessing Manual Entry", + { "depth": 79, "slug": 1182, "text": 1183 }, + "step-1-choose-analysis-mode", + "Step 1: Choose Analysis Mode", + { "depth": 79, "slug": 1185, "text": 1186 }, + "step-1a-standard-analysis-setup", + "Step 1a: Standard Analysis Setup", + { "depth": 79, "slug": 1188, "text": 1189 }, + "step-1b-performance-mode-setup", + "Step 1b: Performance Mode Setup", + { "depth": 79, "slug": 1191, "text": 1192 }, + "step-2-enter-your-data", + "Step 2: Enter Your Data", + { "depth": 621, "slug": 1194, "text": 1195 }, + "keyboard-navigation", + "Keyboard Navigation", + { "depth": 621, "slug": 1197, "text": 1198 }, + "touch-optimized-design", + "Touch-Optimized Design", + { "depth": 621, "slug": 1200, "text": 1201 }, + "spec-limit-feedback", + "Spec Limit Feedback", + { "depth": 621, "slug": 1203, "text": 1204 }, + "running-statistics", + "Running Statistics", + { "depth": 621, "slug": 1206, "text": 1207 }, + "paste-from-clipboard", + "Paste from Clipboard", + { "depth": 79, "slug": 1209, "text": 1210 }, + "analyzing-your-data", + "Analyzing Your Data", + { "depth": 33, "slug": 1212, "text": 1213 }, + "data-import-formats", + "Data Import Formats", + { "depth": 79, "slug": 1215, "text": 1216 }, + "supported-file-types", + "Supported File Types", + { "depth": 79, "slug": 1218, "text": 1219 }, + "csv-requirements", + "CSV Requirements", + { "depth": 79, "slug": 1221, "text": 1222 }, + "excel-requirements", + "Excel Requirements", + { "depth": 79, "slug": 1224, "text": 1225 }, + "data-size-limits", + "Data Size Limits", + { "depth": 79, "slug": 1227, "text": 1228 }, + "data-validation", + "Data Validation", + { "depth": 79, "slug": 1230, "text": 1231 }, + "pareto-data-source", + "Pareto Data Source", + { "depth": 79, "slug": 1233, "text": 1234 }, + "auto-detection", + "Auto-Detection", + { "depth": 33, "slug": 1236, "text": 1237 }, + "annotating-charts", + "Annotating Charts", + { "depth": 79, "slug": 1239, "text": 1240 }, + "boxplot-and-pareto-highlighting-a-category", + "Boxplot and Pareto: Highlighting a Category", + { "depth": 79, "slug": 1242, "text": 1243 }, + "boxplot-and-pareto-adding-a-text-note", + "Boxplot and Pareto: Adding a Text Note", + { "depth": 79, "slug": 1245, "text": 1246 }, + "i-chart-adding-a-free-floating-text-note", + "I-Chart: Adding a Free-Floating Text Note", + { "depth": 79, "slug": 1248, "text": 1249 }, + "clearing-all-annotations", + "Clearing All Annotations", + { "depth": 79, "slug": 1251, "text": 1252 }, + "important-behavior", + "Important Behavior", + { "depth": 33, "slug": 1254, "text": 1255 }, + "point-selection-brushing", + "Point Selection (Brushing)", + { "depth": 79, "slug": 1257, "text": 1258 }, + "how-to-select", + "How to Select", + { "depth": 79, "slug": 1260, "text": 1261 }, + "create-factor-workflow", + "Create Factor Workflow", + { "depth": 33, "slug": 1263, "text": 1264 }, + "tips--tricks", + "Tips & Tricks", + { "depth": 33, "slug": 1266, "text": 1267 }, + "troubleshooting--faq", + "Troubleshooting / FAQ", + { "depth": 79, "slug": 1269, "text": 1270 }, + "data-issues", + "Data Issues", + { "depth": 79, "slug": 1272, "text": 1273 }, + "charts", + "Charts", + { "depth": 79, "slug": 1275, "text": 1276 }, + "offline-use", + "Offline Use", + { "depth": 79, "slug": 1278, "text": 1279 }, + "export", + "Export", + [], + [], + { "title": 1114 }, + [], + "03-features/specifications", + { "id": 1284, "data": 1286, "body": 1291, "filePath": 1292, "digest": 1293, "rendered": 1294 }, + { + "title": 1287, + "editUrl": 16, + "head": 1288, + "template": 18, + "sidebar": 1289, + "pagefind": 16, + "draft": 20 + }, + "VariScout — Product Spec", + [], + { "hidden": 20, "attrs": 1290 }, + {}, + "# VariScout — Product Spec\n\n**Version:** 1.0 \n**Date:** December 2024 \n**Status:** Draft\n\n---\n\n## What Is It?\n\nA lightweight, offline variation analysis tool for quality professionals. No AI, no API keys — just fast, linked charts that reveal hidden variation.\n\n**Tagline:** _\"Cut through your watermelons — without the cloud.\"_\n\n---\n\n## Target Users\n\n| User | Context | Why Lite works |\n| ------------------------ | ----------------------------------- | --------------------------------------------- |\n| **Quality Champions** | SMEs in developing countries | Know statistics, need better tools than Excel |\n| **Experienced analysts** | Already know what to look for | Don't need AI guidance |\n| **Trainers / educators** | Teaching variation analysis | Clean demo tool, no AI unpredictability |\n| **LSS Trainers** | Green Belt / Black Belt courses | Minitab replacement with zero installation |\n| **Offline environments** | Factory floor, limited connectivity | 100% local, no internet needed |\n\n---\n\n## Core Features\n\n### 1. Data Import\n\n- CSV and Excel (.xlsx)\n- **Data Mapping Stage**: Interstitial screen to confirm/select Outcome (Y) and Factors (X) before analysis\n- **Smart Auto-Mapping**: Keyword-based column detection (e.g., \"weight\" → outcome, \"shift\" → factor)\n- **Data Validation**: Informational validation showing excluded rows (missing/non-numeric values)\n - DataQualityBanner shows valid/excluded row counts\n - \"View Excluded Rows\" opens Data Table filtered to issues\n - Analysis proceeds with valid rows only\n- **Separate Pareto**: Optional upload of pre-aggregated count data (not linked to filters)\n- Date/time column detection for time series\n- Manual override if needed\n\n### 2. Three-Chart Dashboard\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ I-CHART (time series) │\n│ ────────────────────────────────────────────────────────── │\n│ USL ═══════════════════════════════════════════════════ 🔴 │\n│ ● ● ● │\n│ UCL - - - - - - - - - - - - - - - - - - - - - - - - - - - │\n│ ● ● ● ● ● ● ● ● ● ● ● ● ● │\n│ CL ─────────────────────────────────────────────────── │\n│ ● ● ● ● ● ● │\n│ LCL - - - - - - - - - - - - - - - - - - - - - - - - - - - │\n│ ● │\n│ LSL ═══════════════════════════════════════════════════ 🔴 │\n├─────────────────────────────┬───────────────────────────────┤\n│ BOXPLOT (factor compare) │ PARETO (categories) │\n│ [Violin Mode: density] │ │\n│ │ │\n│ ┌─┐ │ ████████████ Station 3 │\n│ ──┼─┼── ┌─┐ │ ████████ Operator B │\n│ └─┘ ──┼─┼── ┌─┐ │ █████ Material X │\n│ └─┘ ──┼─┼── │ ███ Other │\n│ └─┘ │ │\n│ Shift 1 Shift 2 Shift 3 │ │\n└─────────────────────────────┴───────────────────────────────┘\n\nLegend:\n ═══ Specification limits (USL/LSL) — user-defined, red\n - - Control limits (UCL/LCL) — calculated from data, gray\n ─── Center line (CL) — mean, solid\n```\n\n**Specification Limits (optional):**\n\n- User inputs USL, LSL, and/or Target\n- Shown as distinct colored lines\n- Points colored by pass/fail status\n- Enables conformance summary calculations\n\n**Staged I-Chart (optional):**\n\n- Select a categorical column as \"Stage Column\" to divide chart into phases\n- Each stage calculates its own control limits (UCL, Mean, LCL)\n- Data automatically sorted by stage (all Stage A points, then Stage B, etc.)\n- Stage order modes: Auto-detect, First occurrence, Alphabetical\n- Vertical dividers mark stage boundaries\n- Points colored based on their stage's control limits\n- Use cases: before/after process improvements, comparing batches, equipment changes\n\n### 3. Interactive Analysis (Multi-Vari)\n\n- **Outcome Selection**: Switch primary metric (Y) directly from I-Chart header\n- **Factor Selection**: Segmented pill-button control for factor selection\n - Blue highlight shows selected factor\n - Amber dot indicator when filter active on that factor\n - Clicking chart element syncs both Boxplot and Pareto to same factor\n- **Click-to-Edit Axes**: Click Y-axis to manually set Min/Max or reset to Auto\n - **Scale Mode**: Auto (fit to data), Start at Zero, or Manual\n - **Control Limits Visibility**: Toggle UCL/Mean/LCL display in Settings\n- **Boxplot Display Options** (via SlidersHorizontal icon in card header):\n - Violin mode (KDE density overlay)\n - Contribution labels (category impact %)\n - Category sorting: by Name (alphabetical), Mean, or Spread (IQR); ascending/descending\n- **Linked Filtering with Drill-Down**:\n - Click Boxplot category → filters to that factor level\n - Click Pareto bar → filters to that category\n - I-Chart point click → highlights row (no filter)\n - **Breadcrumb Trail**: Shows current filter path with navigation\n - `[🏠 All Data] > [Machine: A, B ✕] > [Shift: Day ✕] [✕ Clear All]`\n - Click breadcrumb item → navigates back to that state\n - Click × on breadcrumb segment → removes that specific filter\n - Clear All button → resets to unfiltered view\n- **Filter Chips**: Active filters shown as removable chips\n - Displays below breadcrumb in sticky navigation\n - Each chip shows factor:values with × remove button\n - \"Clear all\" button when multiple filters active\n- **\"What's selected accounts for X% of total variation\"**\n\n### 4. Statistics Panel\n\n**Two Analysis Modes (user selects):**\n\n```\n┌─────────────────────────────────────┐\n│ ANALYSIS MODE │\n│ ○ Conformance (batch pass/fail) │\n│ ● Capability (process performance) │\n└─────────────────────────────────────┘\n```\n\n**Conformance Mode** — \"Does each batch pass?\"\n| Metric | Description |\n|--------|-------------|\n| Pass count | Batches within spec |\n| Fail count | Batches outside spec |\n| Pass rate % | Overall success rate |\n| Failures by factor | Which supplier/station has problems |\n\nBest for: Incoming inspection, export certification, lot acceptance\n\n**Simple (single spec):**\n\n```\n┌─────────────────────────────────────┐\n│ CONFORMANCE SUMMARY │\n│ │\n│ ✅ Passed: 47/50 (94%) │\n│ 🔴 Rejected: 3/50 (6%) │\n│ │\n│ Spec: 9% - 13% moisture │\n│ │\n│ Failures by Supplier: │\n│ • Supplier B: 2 (67% of failures) │\n│ • Supplier A: 1 (33% of failures) │\n└─────────────────────────────────────┘\n```\n\n**Capability Mode** — \"Can our process reliably meet specs?\"\n| Metric | Description |\n|--------|-------------|\n| Mean | Central tendency |\n| Median | Midpoint value (always shown alongside Mean) |\n| Std Dev | Spread of the distribution |\n| Cp | Process capability (potential) — requires both USL and LSL |\n| Cpk | Process capability (actual, considers centering) |\n| % out of spec | Actual failure rate |\n| η² (eta-squared) | Variation explained by factor |\n\nBest for: Process improvement, ongoing monitoring, supplier qualification\n\n**Display Options (Settings → Visualization):**\n\n- Toggle Cp display (only available when both USL and LSL are defined)\n- Toggle Cpk display\n- Configurable Cpk target threshold (default: 1.33)\n - Values below target shown in warning color (yellow/amber)\n - Values at or above target shown in success color (green)\n - Configurable threshold available in Azure App; PWA uses fixed 1.33 threshold\n\n**Capability Histogram (Stats Panel → Histogram tab):**\n\n```\n┌─────────────────────────────────────┐\n│ HISTOGRAM │\n│ LSL Mean USL │\n│ │ ████ │ │ │\n│ │ ██████ │ │ │\n│ │ █████████│███ │ │\n│ │ ███████████████ │ │\n│ ──────┼───────────┼───────────┼── │\n│ 🔴 │ 🟢 │ 🟢 │ 🔴 │\n│ out of │ within │ within │out │\n│ spec │ spec │ spec │ │\n└─────────────────────────────────────┘\n```\n\n- Distribution histogram of outcome values\n- Vertical lines for USL (red dashed), LSL (red dashed), Target (green dashed), Mean (blue solid)\n- Bars colored green (within spec) or red (outside spec)\n- Visual complement to numeric Cp/Cpk values\n\n```\n┌─────────────────────────────────────┐\n│ CAPABILITY SUMMARY │\n│ │\n│ Cp: 1.42 Cpk: 0.91 ⚠️ │\n│ % out of spec: 6% │\n│ │\n│ Process is off-center (shift up) │\n│ │\n│ Variation by Factor: │\n│ • Supplier: 34% of variation │\n│ • Day: 12% of variation │\n└─────────────────────────────────────┘\n```\n\n**Specs Input (choose one):**\n\nOption A: Simple limits (continuous data)\n\n```\n┌─────────────────────────────────────┐\n│ Specification Limits │\n│ │\n│ USL: [________] (upper spec) │\n│ Target: [________] (optional) │\n│ LSL: [________] (lower spec) │\n│ │\n│ ☑ Show on I-Chart │\n│ ☑ Highlight out-of-spec points │\n└─────────────────────────────────────┘\n```\n\nWhen configured:\n\n- I-Chart shows spec lines\n- Points colored by pass/fail\n- Summary shows pass rate and conformance\n- Boxplot/Pareto filter shows impact on out-of-spec rates\n\n### Spec Discovery Flow (Progressive Disclosure)\n\nUsers can set specification limits at two points in the workflow:\n\n**1. During column mapping (optional)**\n\nThe ColumnMapping component includes a collapsible \"Set Specification Limits\" section at the bottom. It is collapsed by default — users who already know their specs can expand it and enter Target, LSL, and USL before proceeding to analysis. Values are applied automatically; no Apply button is required.\n\n```\n┌─────────────────────────────────────┐\n│ Column Mapping │\n│ ... │\n│ ▶ Set Specification Limits │ ← collapsed by default\n└─────────────────────────────────────┘\n\nExpanded:\n┌─────────────────────────────────────┐\n│ ▼ Set Specification Limits │\n│ │\n│ Target: [________] (optional) │\n│ LSL: [________] (optional) │\n│ USL: [________] (optional) │\n└─────────────────────────────────────┘\n```\n\n**2. Pencil link in the Stats Panel**\n\nThe Stats Panel shows a pencil link below the metric cards. The link text changes based on whether specs are already configured:\n\n- **No specs set:** `✏ Set spec limits` — clicking opens the SpecEditor popover where the user can enter Target, LSL, and USL.\n- **Specs exist:** `✏ Edit spec limits` — clicking opens the same SpecEditor popover, pre-populated with current values.\n\n```\n┌─────────────────────────────────────┐\n│ STATS │\n│ Mean: 12.4 Median: 12.2 │\n│ Std Dev: 0.8 Samples: 50 │\n│ │\n│ ✏ Set spec limits │\n└─────────────────────────────────────┘\n```\n\nOnce specs are saved via the SpecEditor, the capability cards (Cp, Cpk, Pass Rate) appear in the metric grid:\n\n```\n┌─────────────────────────────────────┐\n│ STATS │\n│ Pass Rate: 94% Cp: 1.42 Cpk: 0.91│\n│ Mean: 12.4 Median: 12.2 │\n│ Std Dev: 0.8 Samples: 50 │\n│ │\n│ ✏ Edit spec limits │\n└─────────────────────────────────────┘\n```\n\n**Design rationale:** A single SpecEditor popover provides a consistent spec editing experience across all entry points (Stats Panel, chart cards, header).\n\n### 5. Data Table (View/Edit Data)\n\n**Access**: Click table icon in header toolbar\n\n**Features:**\n\n- View all imported data in Excel-like table format\n- Click any cell to edit inline\n- Keyboard navigation (Tab/Enter between cells)\n- Spec status column with color coding (PASS/USL/LSL)\n- Add new rows\n- Delete rows\n- Apply changes to update analysis\n\n**Validation Features:**\n\n- \"Show Excluded Only\" toggle to filter to problem rows\n- Amber background highlighting for excluded rows\n- Warning icon with tooltip showing exclusion reason per row\n- Accessible from DataQualityBanner via \"View Excluded Rows\"\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│ Data Table [X] │\n├─────────────────────────────────────────────────────────────────┤\n│ 50 rows [+ Add Row] │\n├─────────────────────────────────────────────────────────────────┤\n│ # │ Farm │ Batch │ Weight │ Status │ Actions │\n│─────┼─────────┼────────┼────────┼────────┼───────── │\n│ 1 │ Farm A │ B001 │ 12.5 │ ✓ PASS │ [Delete] │\n│ 2 │ Farm A │ B002 │ 14.2 │ ✗ USL │ [Delete] │\n│ 3 │ Farm B │ B003 │ 11.8 │ ✓ PASS │ [Delete] │\n│ ... (scrollable, click to edit) │\n├─────────────────────────────────────────────────────────────────┤\n│ [Cancel] [Apply Changes] │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n### 6. Save & Load Analysis (Azure App)\n\n> Save/load and .vrs files are **Azure App only**. The PWA is session-only — data is cleared on refresh.\n\n**Save Analysis (.vrs file):**\n\n```\n┌─────────────────────────────────────┐\n│ Save Analysis │\n│ │\n│ Name: [Shift 2 Investigation ] │\n│ Location: [Documents/VaRiScout ▼] │\n│ │\n│ Includes: │\n│ ☑ Data (embedded) │\n│ ☑ Column configuration │\n│ ☑ Specifications (USL/LSL/Target) │\n│ ☑ Current filters │\n│ ☑ Chart settings │\n│ │\n│ [Cancel] [Save] │\n└─────────────────────────────────────┘\n```\n\n**File contains:**\n\n```json\n{\n \"version\": \"1.0\",\n \"name\": \"Shift 2 Investigation\",\n \"created\": \"2024-12-28T10:30:00Z\",\n \"modified\": \"2024-12-28T14:45:00Z\",\n \"data\": {\n /* embedded CSV data */\n },\n \"config\": {\n \"outcome\": \"CycleTime\",\n \"factors\": [\"Shift\", \"Station\", \"Operator\"],\n \"timeColumn\": \"Timestamp\",\n \"specs\": { \"usl\": 50, \"lsl\": 40, \"target\": 45 }\n },\n \"state\": {\n \"filters\": [{ \"column\": \"Shift\", \"values\": [\"2\"] }],\n \"boxplotFactor\": \"Station\",\n \"paretoColumn\": \"DefectType\"\n }\n}\n```\n\n**Load Analysis (Azure App):**\n\n- File → Open (or drag-drop .vrs file)\n- Recent analyses list on home screen\n- Double-click .vrs file opens in VariScout\n\n**Home Screen (PWA):**\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ VariScout │\n├─────────────────────────────────────────────────────────────┤\n│ │\n│ Try a Sample Dataset: │\n│ │\n│ [☕ Coffee] [🏭 Bottleneck] [🏥 Hospital] [📦 Packaging] │\n│ │\n│ ───────────────────────────────────────────────────────── │\n│ │\n│ [ Paste from Excel ] (primary action) │\n│ │\n│ Or enter data manually │\n│ │\n└─────────────────────────────────────────────────────────────┘\n```\n\n### 7. Chart Annotations\n\nAnalysts can add text annotations and (on Boxplot/Pareto) highlight colors to charts for reporting. Annotation behavior varies by chart type.\n\n#### Boxplot and Pareto: Right-Click Context Menu\n\nRight-click any boxplot box or pareto bar to open the annotation context menu:\n\n```\n┌────────────────────────┐\n│ ● Red highlight │\n│ ● Amber highlight │\n│ ● Green highlight │\n│ ○ Clear highlight │\n│ ───────────────── │\n│ + Add note │\n└────────────────────────┘\n```\n\n- **Highlight colors**: Mark categories with red, amber, or green fill\n- **Add note**: Creates a text annotation anchored to that category\n- **Clear highlight**: Removes the highlight color\n- Left-click always does drill-down (unchanged)\n\nText notes are **category-anchored**: they follow the named group (e.g., \"Shift 2\") and are hidden when that category is filtered out.\n\n**Data Change Behavior (Boxplot/Pareto):**\n\n- Filter, sort, or drill-down → annotation offsets reset to (0, 0) (snap back to anchor)\n- Hidden if anchor category is filtered out\n\n#### I-Chart: Free-Floating Text Notes\n\nRight-click anywhere in the I-Chart area to place a text note at that position. There is no intermediate context menu — the note appears immediately at the click location.\n\n- Notes are **free-floating**: anchored to a percentage position within the chart area (not to a data point)\n- Notes stay at their visual position when data is filtered or the time range changes\n- **No highlight colors** on I-Chart dots — dot color carries semantic meaning (blue = in-control, red = violation) and must not be overridden\n\n#### Text Note Editing (All Charts)\n\n- Click text to edit (contentEditable)\n- Drag body to reposition\n- Drag right edge to resize width\n- Hover to reveal delete button (×)\n- Click outside to deselect\n\n#### Clear All\n\n- Small × button in chart card header (visible when annotations exist for that chart)\n- Clears all text annotations (and highlights, where applicable) for the specific chart\n\n**Available in:** Both PWA and Azure App. Annotations appear in PNG exports (html-to-image).\n\n### 8. Export\n\n**Implemented:**\n\n- PNG (individual charts or dashboard, includes annotations)\n- CSV (with spec status column)\n- .vrs project files (JSON format)\n\n### 9. Branding (Implemented)\n\n**Chart Footer Source Bar:**\n\n```\n┌─────────────────────────────────────┐\n│ [chart content] │\n├─────────────────────────────────────┤\n│ ▌VariScout Lite n=50 │\n└─────────────────────────────────────┘\n```\n\n- Blue accent bar (3px) + branding text on left\n- Sample size (n=count) on right\n- Semi-transparent slate background\n- Visible in free tier\n- Hidden for paid tiers (`isPaidTier()` from `@variscout/core/tier`)\n\n### 10. Statistical Tooltips\n\nComprehensive hover tooltips explain statistical terms throughout the app. Hover over any metric label or the help icon (?) to see a plain-language explanation.\n\n**Coverage:**\n\n| Component | Terms Explained |\n| ---------------- | -------------------------------------- |\n| Stats Panel | Pass Rate, Rejected %, Cp, Cpk |\n| ANOVA Results | p-value, F-statistic, η² (eta-squared) |\n| Dashboard | UCL, LCL, Mean (control limits) |\n| Regression Panel | R², p-value, slope |\n\n**Example Tooltips:**\n\n```\nCpk: \"Process Capability Index. Measures how centered your process\n is within spec limits. ≥1.33 is typically required.\"\n\np-value: \"Probability the observed difference happened by chance.\n p \u003C 0.05 means the groups are statistically different.\"\n\nUCL: \"Upper Control Limit. Points above this indicate special cause\n variation (something changed in the process).\"\n```\n\n**Design:** Tooltips appear on hover/tap with minimal delay. Uses HelpCircle icon next to terms. No clutter when not engaged.\n\n### 11. Control Violation Explanations & Special Cause Education\n\n**Purpose:** Help users understand why points are flagged red (special cause variation) in control charts, supporting the core analysis learning journey from common vs. special cause distinction.\n\n**Implementation:**\n\n#### Enhanced I-Chart Tooltips\n\nHover tooltips on I-Chart data points now explain violation types:\n\n```\n#42 ← Point number\nValue: 45.2 ← Measurement value\n⚠️ Special Cause: Above UCL ← Color-coded status (red for control, factual signal)\n```\n\n**Violation Types:**\n\n- **Special Cause (Red)**: Control limit violations (Above/Below UCL/LCL) + Nelson Rule 2\n- **Out-of-Spec (Orange)**: Specification limit violations (Above/Below USL/LSL)\n- **In-Control (Blue)**: Normal random variation - no action needed\n\n#### Data Window Row Annotations\n\nThe Data Panel (side table) shows violation icons next to row numbers:\n\n- 🟡 **AlertTriangle** (amber) = Data quality issues (missing/non-numeric values)\n- 🔴 **AlertCircle** (red) = Control violations (special cause)\n\n**Hover tooltip shows specific reasons:**\n\n- \"Special Cause: Above UCL\"\n- \"Special Cause: Below LCL\"\n- \"Special Cause: Nelson Rule 2 (9 consecutive points on same side of mean)\"\n- \"Above USL\" (spec violation)\n- \"Below LSL\" (spec violation)\n\nMultiple violations can appear for a single point (e.g., both control and spec limits).\n\n#### Educational Glossary Terms\n\nNew glossary terms support deeper learning (accessed via HelpTooltip icons):\n\n| Term | Definition | Category | Learn More Path |\n| ------------- | ------------------------------------------------------- | ----------- | ----------------- |\n| Special Cause | Variation due to unusual events requiring investigation | Methodology | /learn/two-voices |\n| Common Cause | Random variation inherent to stable processes | Methodology | /learn/two-voices |\n| Nelson Rule 2 | 9+ consecutive points on same side of mean (shift) | Methodology | /tools/i-chart |\n| In-Control | Stable process with only common cause variation | Methodology | /learn/two-voices |\n\n**Pedagogical Goal:** Users learn the core concept of **Special Cause vs Common Cause** variation:\n\n- **Blue dots** = Common cause (random, inherent) → No action, process is predictable\n- **Red dots** = Special cause (assignable, unusual) → Investigate and correct\n- This prevents both **tampering** (fixing common cause) and **under-reaction** (ignoring special cause)\n\n**Design Philosophy:**\n\n- Use \"Special Cause\" terminology consistently (industry standard)\n- Contrast with \"Common Cause\" to reinforce the distinction\n- **Factual language**: State the signal clearly without prescriptive action (VariScout finds WHERE to focus; user applies domain knowledge to determine WHY)\n- Progressive disclosure: Quick tooltip → Glossary definition → Website learning content\n- Aligns with philosophy doc: \"VariScout identifies factors driving variation, not 'root causes'\"\n\n**Industry Benchmark Alignment:**\nMatches Minitab, QI Macros, and Six Sigma tool patterns:\n\n- Visual indicators (red dots)\n- Hover tooltips with rule explanations\n- Data table annotations\n- Pattern highlighting for Nelson rules\n\n### 12. Embed Mode & Deep Linking\n\nThe PWA supports URL parameters for embedding in website case studies or sharing specific analyses.\n\n**URL Parameters:**\n\n| Parameter | Purpose | Example |\n| -------------- | ----------------------------- | --------------------------------- |\n| `sample=\u003Ckey>` | Auto-load a sample dataset | `?sample=mango-export` |\n| `embed=true` | Hide header/footer for iframe | `?sample=mango-export&embed=true` |\n\n**Available Sample Keys:**\n\n| Key | Dataset | Learning Focus |\n| ------------------- | ------------------------- | ---------------------------- |\n| `mango-export` | Agri-Food: Mango Export | Factor identification, ANOVA |\n| `textiles-strength` | Textiles: Fabric Strength | Process capability, Cpk |\n| `coffee-defects` | Coffee: Defect Analysis | Pareto, defect analysis |\n\n**Embed Example:**\n\n```html\n\u003Ciframe\n src=\"https://app.variscout.com?sample=mango-export&embed=true\"\n title=\"VariScout Interactive Analysis\"\n width=\"100%\"\n height=\"600\"\n frameborder=\"0\"\n>\u003C/iframe>\n```\n\n**Use Cases:**\n\n- Website case study pages with guided exploration\n- Embedding in training materials or documentation\n- Sharing pre-configured analyses via link\n\n---\n\n## UI Design Principles\n\n### Scrollable Dashboard Layout\n\nThe dashboard uses a scrollable layout with minimum chart heights for comfortable analysis:\n\n| Chart | Minimum Height | Purpose |\n| ------- | -------------- | --------------------------------------- |\n| I-Chart | 400px | Primary chart needs good vertical space |\n| Boxplot | 280px | Enough for readable axes |\n| Pareto | 280px | Enough for readable axes |\n\n**Sticky Navigation**: Breadcrumb trail and tab bar remain visible at top while scrolling.\n\n### Dashboard Structure\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ 🏠 All Data > Machine: A [Clear All] (sticky header) │\n│ [Analysis] [Regression] │\n├─────────────────────────────────────────────────────────────┤\n│ I-Chart [Outcome ▼] │\n│ │\n│ (scrollable content) │\n│ │\n├─────────────────────────────────────────────────────────────┤\n│ Boxplot │ Pareto │ Summary │\n│ [Factor ▼] │ [Category ▼] │ [Prob] [Cap] │\n│ │ │ │\n└───────────────┴───────────────┴─────────────────────────────┘\n```\n\n### Independent Panel Selections\n\nEach panel has its own data selector and operates independently:\n\n| Panel | Selection | Required |\n| ------- | ----------------------------- | --------- |\n| I-Chart | Outcome (numeric column) | Yes |\n| Boxplot | Factor (categorical column) | No |\n| Pareto | Category (categorical column) | No |\n| Summary | Uses Outcome | Automatic |\n\n### Empty State Behavior\n\nWhen no data is selected for a panel, it displays a dropdown prompt rather than hiding or rearranging the layout. This keeps the interface consistent and learnable.\n\n### Header & Workspace Layout\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│ 📂 Project Name data.csv (1,247 rows) [Copy ▼] [⚙]│\n├─────────────────────────────────────────────────────────────────┤\n│ I-Chart ... │\n```\n\n| Element | Description |\n| ------------ | ------------------------------- |\n| Project name | Editable, user-defined |\n| Data file | Shows source file and row count |\n| Copy menu | Copy All, Copy Chart options |\n| Settings | Gear icon for preferences |\n\n### Presentation Mode\n\nFullscreen distraction-free view for stakeholder presentations:\n\n- Access via **View → Presentation Mode**\n- Displays all charts in optimized layout:\n - I-Chart on top (~60% height)\n - Boxplot, Pareto, Stats Panel in bottom row\n- Hides header, footer, tabs, and breadcrumbs\n- Press **Escape** to exit\n- Subtle \"Press Escape to exit\" hint in bottom right\n\n### Filter State Display\n\nAlways show current filter state so users know what subset of data they're viewing:\n\n**No filters (default):**\n\n```\n│ 📂 Cycle Time Reduction n = 1,247 rows │\n```\n\n**Filters active:**\n\n```\n│ 📂 Cycle Time Reduction │\n│ Shift = Night ✕ → Machine = Oven B ✕ [Clear] n = 47 │\n```\n\n| Action | Result |\n| ---------------------- | ---------------------- |\n| Click boxplot category | Adds filter |\n| Click pareto bar | Adds filter |\n| Click ✕ on filter chip | Removes that filter |\n| Click \"Clear All\" | Resets to full dataset |\n\n### Copy & Export Workflow\n\n| Option | Description |\n| ---------- | ------------------------------------------------------- |\n| Copy All | Entire dashboard view as single image |\n| Copy Chart | Individual chart (I-Chart, Boxplot, Pareto, or Summary) |\n| Copy Stats | Summary statistics as formatted text |\n\nCharts are copied to clipboard as PNG — paste directly into PowerPoint, Word, Google Slides, or email.\n\n### Design Principles Summary\n\n| Principle | Implementation |\n| ---------------------- | -------------------------------------------- |\n| Scrollable layout | Charts have comfortable min-heights |\n| Sticky navigation | Breadcrumb and tabs visible while scrolling |\n| Consistent layout | Same structure regardless of data selections |\n| Independent selections | Each panel has its own data selector |\n| Empty state = prompt | Shows dropdown when no data selected |\n| Presentation mode | Fullscreen view for stakeholder meetings |\n\n---\n\n## What's NOT Included\n\n| Feature | Why excluded |\n| ----------------------------------------- | ---------------------------- |\n| AI recommendations | Requires LLM, ongoing costs |\n| Natural language insights | AI-dependent |\n| Intent modes (Explore/Hypothesis/Monitor) | Adds complexity |\n| Investigation lifecycle | Overkill for simple analysis |\n| Playbooks / guided workflows | AI-dependent |\n| Cloud sync | Offline-first design |\n| Multi-user / collaboration | Single-user tool |\n\n**Philosophy:** Lite users know what they're doing. They need visualization, not guidance.\n\n---\n\n## Technical Architecture\n\n```\n┌─────────────────────────────────────────┐\n│ Progressive Web App (PWA) │\n├─────────────────────────────────────────┤\n│ React Frontend │\n│ ├── Visx charts (I-Chart, Box, Pareto) │\n│ ├── Filter state management │\n│ └── Export handlers │\n├─────────────────────────────────────────┤\n│ Local Processing │\n│ ├── CSV/Excel parser │\n│ ├── Statistics engine (JS) │\n│ └── Control limit calculations │\n├─────────────────────────────────────────┤\n│ Browser APIs │\n│ ├── IndexedDB (project storage) │\n│ ├── Service Worker (offline) │\n│ └── File API (import/export) │\n└─────────────────────────────────────────┘\n\nNO backend. NO API calls. Works offline after first visit.\n```\n\n**Deployment:**\n\n- Vercel, Netlify, or any static host\n- Users access via URL\n- Service Worker enables offline use after first visit\n\n---\n\n## Products & Pricing\n\n| Product | Distribution | Pricing | Status |\n| -------------- | ----------------- | -------------------------------------------------- | ----------- |\n| Azure Standard | Azure Marketplace | €99/month (full analysis, local files) | **PRIMARY** |\n| Azure Team | Azure Marketplace | €299/month (+ Teams, OneDrive, SharePoint, mobile) | **PRIMARY** |\n| PWA | Public URL | FREE (forever, training & education) | Production |\n\n### Free (PWA)\n\n- All core chart types (I-Chart, Boxplot, Pareto, Capability, Regression, ANOVA)\n- Copy-paste data input + sample datasets\n- VariScout branding on charts\n- Session-only storage (no save)\n\n### Standard (Azure App — €99/month)\n\n- All features, unlimited users\n- EasyAuth (Microsoft SSO), file upload, save/persistence\n- Performance Mode (multi-channel analysis)\n- Watermark-free exports, custom theming\n- Managed Application deployment via Azure Marketplace\n\n### Team (Azure App — €299/month)\n\n- Everything in Standard, plus:\n- Teams integration (channel tabs, SSO)\n- OneDrive and SharePoint sync\n- Mobile access via Teams app\n- Photo evidence with EXIF stripping\n\n**Build Commands:**\n\n```bash\npnpm build # Build all packages and apps\n```\n\n---\n\n## Build Estimate\n\n| Component | Effort | Notes |\n| --------------------- | ------ | --------------------------------------------- |\n| Chart components | Done | Already built |\n| Linked filtering | Done | Already built |\n| Statistics engine | Done | Cp/Cpk, conformance |\n| Data import | Done | CSV + Excel parsing |\n| Save/Load (.vrs) | Done | JSON serialization + file handling |\n| Export (PNG/CSV) | Done | DOM-based capture, CSV generation |\n| Edition config | Done | Watermark + branding |\n| Manual Entry | Done | Touch-optimized data entry |\n| Data Table | Done | Inline editing |\n| Shared charts package | Done | @variscout/charts with props-based components |\n| **Completed** | ✓ | Core features implemented |\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ---------------------- | ---------------------------------------- |\n| Downloads | 500 in first year |\n| Active users | 100 monthly |\n| Conversion to Licensed | 5% of active users |\n| Support tickets | \u003C 10/month (simple tool = few questions) |\n\n---\n\n## Planned Features (Green Belt Training)\n\nFor complete Green Belt training coverage, two features are planned.\n\n### Feature Summary\n\n| Feature | Type | Effort | Purpose |\n| ------------------- | ----------- | ------ | -------------------------------------------------- |\n| ANOVA under Boxplot | Enhancement | Small | Statistical confirmation of group differences |\n| Regression Tab | New Tab | Medium | Multi-factor comparison with auto-fit intelligence |\n\n### ANOVA Integration\n\nAdd ANOVA calculations below the existing boxplot visualization:\n\n- Group means, sample sizes, and standard deviations\n- F-ratio and p-value\n- Plain-language interpretation: \"Different? YES (p = 0.003)\"\n- No separate t-test needed (2-group ANOVA is mathematically equivalent)\n\n### Regression Tab\n\nA new tab with 2×2 grid of scatter plots:\n\n- Each plot shows one X-Y relationship with regression line\n- R² value with star rating (★★★★★ for > 0.9)\n- Auto-fit intelligence (recommends quadratic when appropriate)\n- Summary ranking: \"Temperature → Speed → Pressure\" by R² strength\n\n---\n\n## Competitive Positioning\n\n### vs Minitab\n\n| Aspect | Minitab | VaRiScout |\n| -------------- | ---------------- | ---------------------- |\n| Price | $1,000+/year | From €99/month or free |\n| Installation | Desktop software | Browser (no install) |\n| Learning curve | Steep | Minimal |\n| Feature depth | Deep (30 years) | Focused (essentials) |\n| Target | Statisticians | Everyone |\n\n### vs Excel\n\n| Aspect | Excel | VaRiScout |\n| ---------------- | ------------------ | ------------ |\n| Setup | Build from scratch | Ready to use |\n| Control limits | Manual calculation | Automatic |\n| Linked filtering | Complex | One click |\n| Export quality | Varies | Consistent |\n\n### Positioning Statement\n\n> \"VaRiScout is for practitioners who need answers, not statisticians who need tools. Simple enough for anyone. Rigorous enough for experts.\"\n\n---\n\n## Success Metrics\n\n### Product Metrics\n\n| Metric | Target |\n| --------------------------- | ------------- |\n| Time to first chart | \u003C 2 minutes |\n| Free → Paid conversion | 5-10% |\n| Monthly active users (free) | 1,000+ |\n| Paid subscribers | 100+ (Year 1) |\n\n### Business Metrics\n\n| Metric | Year 1 Target |\n| -------------------- | ------------- |\n| ARR (PWA + Excel) | €25,000 |\n| Support tickets/user | \u003C 0.1 |\n| Churn rate | \u003C 20% |\n\n---\n\n## Summary\n\n> **VariScout** is a fast, offline variation analysis tool for people who know what they're doing but need better tools than Excel. No AI, no subscriptions, no complexity — just linked charts that reveal hidden variation.\n>\n> Perfect for quality professionals and LSS trainers: distribute freely, zero ongoing costs, clean licensing.", + "src/content/docs/03-features/specifications.md", + "a46c5f1b13e868ea", + { "html": 1295, "metadata": 1296 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"variscout--product-spec\">VariScout — Product Spec\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#variscout--product-spec\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout — Product Spec”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Version:\u003C/strong> 1.0\u003Cbr>\n\u003Cstrong>Date:\u003C/strong> December 2024\u003Cbr>\n\u003Cstrong>Status:\u003C/strong> Draft\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-is-it\">What Is It?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-is-it\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Is It?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A lightweight, offline variation analysis tool for quality professionals. No AI, no API keys — just fast, linked charts that reveal hidden variation.\u003C/p>\n\u003Cp>\u003Cstrong>Tagline:\u003C/strong> \u003Cem>“Cut through your watermelons — without the cloud.”\u003C/em>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-users\">Target Users\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-users\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Users”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>User\u003C/th>\u003Cth>Context\u003C/th>\u003Cth>Why Lite works\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Quality Champions\u003C/strong>\u003C/td>\u003Ctd>SMEs in developing countries\u003C/td>\u003Ctd>Know statistics, need better tools than Excel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Experienced analysts\u003C/strong>\u003C/td>\u003Ctd>Already know what to look for\u003C/td>\u003Ctd>Don’t need AI guidance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Trainers / educators\u003C/strong>\u003C/td>\u003Ctd>Teaching variation analysis\u003C/td>\u003Ctd>Clean demo tool, no AI unpredictability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>LSS Trainers\u003C/strong>\u003C/td>\u003Ctd>Green Belt / Black Belt courses\u003C/td>\u003Ctd>Minitab replacement with zero installation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Offline environments\u003C/strong>\u003C/td>\u003Ctd>Factory floor, limited connectivity\u003C/td>\u003Ctd>100% local, no internet needed\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-features\">Core Features\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-data-import\">1. Data Import\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-data-import\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Data Import”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>CSV and Excel (.xlsx)\u003C/li>\n\u003Cli>\u003Cstrong>Data Mapping Stage\u003C/strong>: Interstitial screen to confirm/select Outcome (Y) and Factors (X) before analysis\u003C/li>\n\u003Cli>\u003Cstrong>Smart Auto-Mapping\u003C/strong>: Keyword-based column detection (e.g., “weight” → outcome, “shift” → factor)\u003C/li>\n\u003Cli>\u003Cstrong>Data Validation\u003C/strong>: Informational validation showing excluded rows (missing/non-numeric values)\n\u003Cul>\n\u003Cli>DataQualityBanner shows valid/excluded row counts\u003C/li>\n\u003Cli>“View Excluded Rows” opens Data Table filtered to issues\u003C/li>\n\u003Cli>Analysis proceeds with valid rows only\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Separate Pareto\u003C/strong>: Optional upload of pre-aggregated count data (not linked to filters)\u003C/li>\n\u003Cli>Date/time column detection for time series\u003C/li>\n\u003Cli>Manual override if needed\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-three-chart-dashboard\">2. Three-Chart Dashboard\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-three-chart-dashboard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Three-Chart Dashboard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ I-CHART (time series) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ────────────────────────────────────────────────────────── │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ USL ═══════════════════════════════════════════════════ 🔴 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ● ● ● │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ UCL - - - - - - - - - - - - - - - - - - - - - - - - - - - │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ● ● ● ● ● ● ● ● ● ● ● ● ● │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CL ─────────────────────────────────────────────────── │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ● ● ● ● ● ● │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ LCL - - - - - - - - - - - - - - - - - - - - - - - - - - - │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ● │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ LSL ═══════════════════════════════════════════════════ 🔴 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────┬───────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ BOXPLOT (factor compare) │ PARETO (categories) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Violin Mode: density] │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌─┐ │ ████████████ Station 3 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ──┼─┼── ┌─┐ │ ████████ Operator B │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └─┘ ──┼─┼── ┌─┐ │ █████ Material X │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └─┘ ──┼─┼── │ ███ Other │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └─┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Shift 1 Shift 2 Shift 3 │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────┴───────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Legend:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">═══ Specification limits (USL/LSL) — user-defined, red\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- - Control limits (UCL/LCL) — calculated from data, gray\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">─── Center line (CL) — mean, solid\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────┐│ I-CHART (time series) ││ ────────────────────────────────────────────────────────── ││ USL ═══════════════════════════════════════════════════ 🔴 ││ ● ● ● ││ UCL - - - - - - - - - - - - - - - - - - - - - - - - - - - ││ ● ● ● ● ● ● ● ● ● ● ● ● ● ││ CL ─────────────────────────────────────────────────── ││ ● ● ● ● ● ● ││ LCL - - - - - - - - - - - - - - - - - - - - - - - - - - - ││ ● ││ LSL ═══════════════════════════════════════════════════ 🔴 │├─────────────────────────────┬───────────────────────────────┤│ BOXPLOT (factor compare) │ PARETO (categories) ││ [Violin Mode: density] │ ││ │ ││ ┌─┐ │ ████████████ Station 3 ││ ──┼─┼── ┌─┐ │ ████████ Operator B ││ └─┘ ──┼─┼── ┌─┐ │ █████ Material X ││ └─┘ ──┼─┼── │ ███ Other ││ └─┘ │ ││ Shift 1 Shift 2 Shift 3 │ │└─────────────────────────────┴───────────────────────────────┘Legend: ═══ Specification limits (USL/LSL) — user-defined, red - - Control limits (UCL/LCL) — calculated from data, gray ─── Center line (CL) — mean, solid\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Specification Limits (optional):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>User inputs USL, LSL, and/or Target\u003C/li>\n\u003Cli>Shown as distinct colored lines\u003C/li>\n\u003Cli>Points colored by pass/fail status\u003C/li>\n\u003Cli>Enables conformance summary calculations\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Staged I-Chart (optional):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Select a categorical column as “Stage Column” to divide chart into phases\u003C/li>\n\u003Cli>Each stage calculates its own control limits (UCL, Mean, LCL)\u003C/li>\n\u003Cli>Data automatically sorted by stage (all Stage A points, then Stage B, etc.)\u003C/li>\n\u003Cli>Stage order modes: Auto-detect, First occurrence, Alphabetical\u003C/li>\n\u003Cli>Vertical dividers mark stage boundaries\u003C/li>\n\u003Cli>Points colored based on their stage’s control limits\u003C/li>\n\u003Cli>Use cases: before/after process improvements, comparing batches, equipment changes\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-interactive-analysis-multi-vari\">3. Interactive Analysis (Multi-Vari)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-interactive-analysis-multi-vari\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Interactive Analysis (Multi-Vari)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Outcome Selection\u003C/strong>: Switch primary metric (Y) directly from I-Chart header\u003C/li>\n\u003Cli>\u003Cstrong>Factor Selection\u003C/strong>: Segmented pill-button control for factor selection\n\u003Cul>\n\u003Cli>Blue highlight shows selected factor\u003C/li>\n\u003Cli>Amber dot indicator when filter active on that factor\u003C/li>\n\u003Cli>Clicking chart element syncs both Boxplot and Pareto to same factor\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Click-to-Edit Axes\u003C/strong>: Click Y-axis to manually set Min/Max or reset to Auto\n\u003Cul>\n\u003Cli>\u003Cstrong>Scale Mode\u003C/strong>: Auto (fit to data), Start at Zero, or Manual\u003C/li>\n\u003Cli>\u003Cstrong>Control Limits Visibility\u003C/strong>: Toggle UCL/Mean/LCL display in Settings\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot Display Options\u003C/strong> (via SlidersHorizontal icon in card header):\n\u003Cul>\n\u003Cli>Violin mode (KDE density overlay)\u003C/li>\n\u003Cli>Contribution labels (category impact %)\u003C/li>\n\u003Cli>Category sorting: by Name (alphabetical), Mean, or Spread (IQR); ascending/descending\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Linked Filtering with Drill-Down\u003C/strong>:\n\u003Cul>\n\u003Cli>Click Boxplot category → filters to that factor level\u003C/li>\n\u003Cli>Click Pareto bar → filters to that category\u003C/li>\n\u003Cli>I-Chart point click → highlights row (no filter)\u003C/li>\n\u003Cli>\u003Cstrong>Breadcrumb Trail\u003C/strong>: Shows current filter path with navigation\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">[🏠 All Data] > [Machine: A, B ✕] > [Shift: Day ✕] [✕ Clear All]\u003C/code>\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>Click breadcrumb item → navigates back to that state\u003C/li>\n\u003Cli>Click × on breadcrumb segment → removes that specific filter\u003C/li>\n\u003Cli>Clear All button → resets to unfiltered view\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Filter Chips\u003C/strong>: Active filters shown as removable chips\n\u003Cul>\n\u003Cli>Displays below breadcrumb in sticky navigation\u003C/li>\n\u003Cli>Each chip shows factor:values with × remove button\u003C/li>\n\u003Cli>“Clear all” button when multiple filters active\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>“What’s selected accounts for X% of total variation”\u003C/strong>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-statistics-panel\">4. Statistics Panel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-statistics-panel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Statistics Panel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Two Analysis Modes (user selects):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ANALYSIS MODE │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ○ Conformance (batch pass/fail) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ● Capability (process performance) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ ANALYSIS MODE ││ ○ Conformance (batch pass/fail) ││ ● Capability (process performance) │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Conformance Mode\u003C/strong> — “Does each batch pass?”\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Pass count\u003C/td>\u003Ctd>Batches within spec\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Fail count\u003C/td>\u003Ctd>Batches outside spec\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pass rate %\u003C/td>\u003Ctd>Overall success rate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Failures by factor\u003C/td>\u003Ctd>Which supplier/station has problems\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Best for: Incoming inspection, export certification, lot acceptance\u003C/p>\n\u003Cp>\u003Cstrong>Simple (single spec):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CONFORMANCE SUMMARY │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ✅ Passed: 47/50 (94%) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 🔴 Rejected: 3/50 (6%) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Spec: 9% - 13% moisture │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Failures by Supplier: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • Supplier B: 2 (67% of failures) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • Supplier A: 1 (33% of failures) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ CONFORMANCE SUMMARY ││ ││ ✅ Passed: 47/50 (94%) ││ 🔴 Rejected: 3/50 (6%) ││ ││ Spec: 9% - 13% moisture ││ ││ Failures by Supplier: ││ • Supplier B: 2 (67% of failures) ││ • Supplier A: 1 (33% of failures) │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Capability Mode\u003C/strong> — “Can our process reliably meet specs?”\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Mean\u003C/td>\u003Ctd>Central tendency\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Median\u003C/td>\u003Ctd>Midpoint value (always shown alongside Mean)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Std Dev\u003C/td>\u003Ctd>Spread of the distribution\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cp\u003C/td>\u003Ctd>Process capability (potential) — requires both USL and LSL\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cpk\u003C/td>\u003Ctd>Process capability (actual, considers centering)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>% out of spec\u003C/td>\u003Ctd>Actual failure rate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>η² (eta-squared)\u003C/td>\u003Ctd>Variation explained by factor\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Best for: Process improvement, ongoing monitoring, supplier qualification\u003C/p>\n\u003Cp>\u003Cstrong>Display Options (Settings → Visualization):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Toggle Cp display (only available when both USL and LSL are defined)\u003C/li>\n\u003Cli>Toggle Cpk display\u003C/li>\n\u003Cli>Configurable Cpk target threshold (default: 1.33)\n\u003Cul>\n\u003Cli>Values below target shown in warning color (yellow/amber)\u003C/li>\n\u003Cli>Values at or above target shown in success color (green)\u003C/li>\n\u003Cli>Configurable threshold available in Azure App; PWA uses fixed 1.33 threshold\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Capability Histogram (Stats Panel → Histogram tab):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ HISTOGRAM │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ LSL Mean USL │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ████ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ██████ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ █████████│███ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ███████████████ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ──────┼───────────┼───────────┼── │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 🔴 │ 🟢 │ 🟢 │ 🔴 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ out of │ within │ within │out │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ spec │ spec │ spec │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ HISTOGRAM ││ LSL Mean USL ││ │ ████ │ │ ││ │ ██████ │ │ ││ │ █████████│███ │ ││ │ ███████████████ │ ││ ──────┼───────────┼───────────┼── ││ 🔴 │ 🟢 │ 🟢 │ 🔴 ││ out of │ within │ within │out ││ spec │ spec │ spec │ │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cul>\n\u003Cli>Distribution histogram of outcome values\u003C/li>\n\u003Cli>Vertical lines for USL (red dashed), LSL (red dashed), Target (green dashed), Mean (blue solid)\u003C/li>\n\u003Cli>Bars colored green (within spec) or red (outside spec)\u003C/li>\n\u003Cli>Visual complement to numeric Cp/Cpk values\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CAPABILITY SUMMARY │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Cp: 1.42 Cpk: 0.91 ⚠️ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ % out of spec: 6% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Process is off-center (shift up) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Variation by Factor: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • Supplier: 34% of variation │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • Day: 12% of variation │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ CAPABILITY SUMMARY ││ ││ Cp: 1.42 Cpk: 0.91 ⚠️ ││ % out of spec: 6% ││ ││ Process is off-center (shift up) ││ ││ Variation by Factor: ││ • Supplier: 34% of variation ││ • Day: 12% of variation │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Specs Input (choose one):\u003C/strong>\u003C/p>\n\u003Cp>Option A: Simple limits (continuous data)\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Specification Limits │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ USL: [________] (upper spec) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Target: [________] (optional) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ LSL: [________] (lower spec) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☑ Show on I-Chart │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☑ Highlight out-of-spec points │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ Specification Limits ││ ││ USL: [________] (upper spec) ││ Target: [________] (optional) ││ LSL: [________] (lower spec) ││ ││ ☑ Show on I-Chart ││ ☑ Highlight out-of-spec points │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>When configured:\u003C/p>\n\u003Cul>\n\u003Cli>I-Chart shows spec lines\u003C/li>\n\u003Cli>Points colored by pass/fail\u003C/li>\n\u003Cli>Summary shows pass rate and conformance\u003C/li>\n\u003Cli>Boxplot/Pareto filter shows impact on out-of-spec rates\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"spec-discovery-flow-progressive-disclosure\">Spec Discovery Flow (Progressive Disclosure)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#spec-discovery-flow-progressive-disclosure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Spec Discovery Flow (Progressive Disclosure)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Users can set specification limits at two points in the workflow:\u003C/p>\n\u003Cp>\u003Cstrong>1. During column mapping (optional)\u003C/strong>\u003C/p>\n\u003Cp>The ColumnMapping component includes a collapsible “Set Specification Limits” section at the bottom. It is collapsed by default — users who already know their specs can expand it and enter Target, LSL, and USL before proceeding to analysis. Values are applied automatically; no Apply button is required.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Column Mapping │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ... │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▶ Set Specification Limits │ ← collapsed by default\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Expanded:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▼ Set Specification Limits │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Target: [________] (optional) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ LSL: [________] (optional) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ USL: [________] (optional) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ Column Mapping ││ ... ││ ▶ Set Specification Limits │ ← collapsed by default└─────────────────────────────────────┘Expanded:┌─────────────────────────────────────┐│ ▼ Set Specification Limits ││ ││ Target: [________] (optional) ││ LSL: [________] (optional) ││ USL: [________] (optional) │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>2. Pencil link in the Stats Panel\u003C/strong>\u003C/p>\n\u003Cp>The Stats Panel shows a pencil link below the metric cards. The link text changes based on whether specs are already configured:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>No specs set:\u003C/strong> \u003Ccode dir=\"auto\">✏ Set spec limits\u003C/code> — clicking opens the SpecEditor popover where the user can enter Target, LSL, and USL.\u003C/li>\n\u003Cli>\u003Cstrong>Specs exist:\u003C/strong> \u003Ccode dir=\"auto\">✏ Edit spec limits\u003C/code> — clicking opens the same SpecEditor popover, pre-populated with current values.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ STATS │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Mean: 12.4 Median: 12.2 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Std Dev: 0.8 Samples: 50 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ✏ Set spec limits │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ STATS ││ Mean: 12.4 Median: 12.2 ││ Std Dev: 0.8 Samples: 50 ││ ││ ✏ Set spec limits │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Once specs are saved via the SpecEditor, the capability cards (Cp, Cpk, Pass Rate) appear in the metric grid:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ STATS │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Pass Rate: 94% Cp: 1.42 Cpk: 0.91│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Mean: 12.4 Median: 12.2 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Std Dev: 0.8 Samples: 50 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ✏ Edit spec limits │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ STATS ││ Pass Rate: 94% Cp: 1.42 Cpk: 0.91││ Mean: 12.4 Median: 12.2 ││ Std Dev: 0.8 Samples: 50 ││ ││ ✏ Edit spec limits │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Design rationale:\u003C/strong> A single SpecEditor popover provides a consistent spec editing experience across all entry points (Stats Panel, chart cards, header).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"5-data-table-viewedit-data\">5. Data Table (View/Edit Data)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#5-data-table-viewedit-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Data Table (View/Edit Data)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Access\u003C/strong>: Click table icon in header toolbar\u003C/p>\n\u003Cp>\u003Cstrong>Features:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>View all imported data in Excel-like table format\u003C/li>\n\u003Cli>Click any cell to edit inline\u003C/li>\n\u003Cli>Keyboard navigation (Tab/Enter between cells)\u003C/li>\n\u003Cli>Spec status column with color coding (PASS/USL/LSL)\u003C/li>\n\u003Cli>Add new rows\u003C/li>\n\u003Cli>Delete rows\u003C/li>\n\u003Cli>Apply changes to update analysis\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Validation Features:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“Show Excluded Only” toggle to filter to problem rows\u003C/li>\n\u003Cli>Amber background highlighting for excluded rows\u003C/li>\n\u003Cli>Warning icon with tooltip showing exclusion reason per row\u003C/li>\n\u003Cli>Accessible from DataQualityBanner via “View Excluded Rows”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Data Table [X] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 50 rows [+ Add Row] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ # │ Farm │ Batch │ Weight │ Status │ Actions │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│─────┼─────────┼────────┼────────┼────────┼───────── │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 1 │ Farm A │ B001 │ 12.5 │ ✓ PASS │ [Delete] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 2 │ Farm A │ B002 │ 14.2 │ ✗ USL │ [Delete] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 3 │ Farm B │ B003 │ 11.8 │ ✓ PASS │ [Delete] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ... (scrollable, click to edit) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Cancel] [Apply Changes] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────┐│ Data Table [X] │├─────────────────────────────────────────────────────────────────┤│ 50 rows [+ Add Row] │├─────────────────────────────────────────────────────────────────┤│ # │ Farm │ Batch │ Weight │ Status │ Actions ││─────┼─────────┼────────┼────────┼────────┼───────── ││ 1 │ Farm A │ B001 │ 12.5 │ ✓ PASS │ [Delete] ││ 2 │ Farm A │ B002 │ 14.2 │ ✗ USL │ [Delete] ││ 3 │ Farm B │ B003 │ 11.8 │ ✓ PASS │ [Delete] ││ ... (scrollable, click to edit) │├─────────────────────────────────────────────────────────────────┤│ [Cancel] [Apply Changes] │└─────────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"6-save--load-analysis-azure-app\">6. Save & Load Analysis (Azure App)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#6-save--load-analysis-azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Save & Load Analysis (Azure App)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Save/load and .vrs files are \u003Cstrong>Azure App only\u003C/strong>. The PWA is session-only — data is cleared on refresh.\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Save Analysis (.vrs file):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Save Analysis │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Name: [Shift 2 Investigation ] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Location: [Documents/VaRiScout ▼] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Includes: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☑ Data (embedded) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☑ Column configuration │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☑ Specifications (USL/LSL/Target) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☑ Current filters │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☑ Chart settings │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Cancel] [Save] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ Save Analysis ││ ││ Name: [Shift 2 Investigation ] ││ Location: [Documents/VaRiScout ▼] ││ ││ Includes: ││ ☑ Data (embedded) ││ ☑ Column configuration ││ ☑ Specifications (USL/LSL/Target) ││ ☑ Current filters ││ ☑ Chart settings ││ ││ [Cancel] [Save] │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>File contains:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"version\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">1.0\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Shift 2 Investigation\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"created\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">2024-12-28T10:30:00Z\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"modified\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">2024-12-28T14:45:00Z\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"data\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* embedded CSV data */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"config\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"outcome\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">CycleTime\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"factors\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Station\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Operator\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"timeColumn\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Timestamp\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"specs\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: { \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"usl\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">50\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"lsl\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">40\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"target\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">45\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"state\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"filters\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: [{ \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"column\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"values\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">] }],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"boxplotFactor\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Station\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"paretoColumn\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">DefectType\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{ "version": "1.0", "name": "Shift 2 Investigation", "created": "2024-12-28T10:30:00Z", "modified": "2024-12-28T14:45:00Z", "data": { /* embedded CSV data */ }, "config": { "outcome": "CycleTime", "factors": ["Shift", "Station", "Operator"], "timeColumn": "Timestamp", "specs": { "usl": 50, "lsl": 40, "target": 45 } }, "state": { "filters": [{ "column": "Shift", "values": ["2"] }], "boxplotFactor": "Station", "paretoColumn": "DefectType" }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Load Analysis (Azure App):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>File → Open (or drag-drop .vrs file)\u003C/li>\n\u003Cli>Recent analyses list on home screen\u003C/li>\n\u003Cli>Double-click .vrs file opens in VariScout\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Home Screen (PWA):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ VariScout │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Try a Sample Dataset: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [☕ Coffee] [🏭 Bottleneck] [🏥 Hospital] [📦 Packaging] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ───────────────────────────────────────────────────────── │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [ Paste from Excel ] (primary action) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Or enter data manually │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────┐│ VariScout │├─────────────────────────────────────────────────────────────┤│ ││ Try a Sample Dataset: ││ ││ [☕ Coffee] [🏭 Bottleneck] [🏥 Hospital] [📦 Packaging] ││ ││ ───────────────────────────────────────────────────────── ││ ││ [ Paste from Excel ] (primary action) ││ ││ Or enter data manually ││ │└─────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"7-chart-annotations\">7. Chart Annotations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#7-chart-annotations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “7. Chart Annotations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Analysts can add text annotations and (on Boxplot/Pareto) highlight colors to charts for reporting. Annotation behavior varies by chart type.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"boxplot-and-pareto-right-click-context-menu\">Boxplot and Pareto: Right-Click Context Menu\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#boxplot-and-pareto-right-click-context-menu\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Boxplot and Pareto: Right-Click Context Menu”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Right-click any boxplot box or pareto bar to open the annotation context menu:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ● Red highlight │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ● Amber highlight │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ● Green highlight │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ○ Clear highlight │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ───────────────── │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ + Add note │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌────────────────────────┐│ ● Red highlight ││ ● Amber highlight ││ ● Green highlight ││ ○ Clear highlight ││ ───────────────── ││ + Add note │└────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Highlight colors\u003C/strong>: Mark categories with red, amber, or green fill\u003C/li>\n\u003Cli>\u003Cstrong>Add note\u003C/strong>: Creates a text annotation anchored to that category\u003C/li>\n\u003Cli>\u003Cstrong>Clear highlight\u003C/strong>: Removes the highlight color\u003C/li>\n\u003Cli>Left-click always does drill-down (unchanged)\u003C/li>\n\u003C/ul>\n\u003Cp>Text notes are \u003Cstrong>category-anchored\u003C/strong>: they follow the named group (e.g., “Shift 2”) and are hidden when that category is filtered out.\u003C/p>\n\u003Cp>\u003Cstrong>Data Change Behavior (Boxplot/Pareto):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Filter, sort, or drill-down → annotation offsets reset to (0, 0) (snap back to anchor)\u003C/li>\n\u003Cli>Hidden if anchor category is filtered out\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"i-chart-free-floating-text-notes\">I-Chart: Free-Floating Text Notes\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#i-chart-free-floating-text-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “I-Chart: Free-Floating Text Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Right-click anywhere in the I-Chart area to place a text note at that position. There is no intermediate context menu — the note appears immediately at the click location.\u003C/p>\n\u003Cul>\n\u003Cli>Notes are \u003Cstrong>free-floating\u003C/strong>: anchored to a percentage position within the chart area (not to a data point)\u003C/li>\n\u003Cli>Notes stay at their visual position when data is filtered or the time range changes\u003C/li>\n\u003Cli>\u003Cstrong>No highlight colors\u003C/strong> on I-Chart dots — dot color carries semantic meaning (blue = in-control, red = violation) and must not be overridden\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"text-note-editing-all-charts\">Text Note Editing (All Charts)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#text-note-editing-all-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Text Note Editing (All Charts)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Click text to edit (contentEditable)\u003C/li>\n\u003Cli>Drag body to reposition\u003C/li>\n\u003Cli>Drag right edge to resize width\u003C/li>\n\u003Cli>Hover to reveal delete button (×)\u003C/li>\n\u003Cli>Click outside to deselect\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"clear-all\">Clear All\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#clear-all\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Clear All”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Small × button in chart card header (visible when annotations exist for that chart)\u003C/li>\n\u003Cli>Clears all text annotations (and highlights, where applicable) for the specific chart\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Available in:\u003C/strong> Both PWA and Azure App. Annotations appear in PNG exports (html-to-image).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"8-export\">8. Export\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#8-export\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “8. Export”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Implemented:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>PNG (individual charts or dashboard, includes annotations)\u003C/li>\n\u003Cli>CSV (with spec status column)\u003C/li>\n\u003Cli>.vrs project files (JSON format)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"9-branding-implemented\">9. Branding (Implemented)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#9-branding-implemented\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “9. Branding (Implemented)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Chart Footer Source Bar:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [chart content] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▌VariScout Lite n=50 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ [chart content] │├─────────────────────────────────────┤│ ▌VariScout Lite n=50 │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cul>\n\u003Cli>Blue accent bar (3px) + branding text on left\u003C/li>\n\u003Cli>Sample size (n=count) on right\u003C/li>\n\u003Cli>Semi-transparent slate background\u003C/li>\n\u003Cli>Visible in free tier\u003C/li>\n\u003Cli>Hidden for paid tiers (\u003Ccode dir=\"auto\">isPaidTier()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core/tier\u003C/code>)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"10-statistical-tooltips\">10. Statistical Tooltips\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#10-statistical-tooltips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “10. Statistical Tooltips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Comprehensive hover tooltips explain statistical terms throughout the app. Hover over any metric label or the help icon (?) to see a plain-language explanation.\u003C/p>\n\u003Cp>\u003Cstrong>Coverage:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Terms Explained\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Stats Panel\u003C/td>\u003Ctd>Pass Rate, Rejected %, Cp, Cpk\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ANOVA Results\u003C/td>\u003Ctd>p-value, F-statistic, η² (eta-squared)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Dashboard\u003C/td>\u003Ctd>UCL, LCL, Mean (control limits)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regression Panel\u003C/td>\u003Ctd>R², p-value, slope\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Example Tooltips:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cpk: \"Process Capability Index. Measures how centered your process\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">is within spec limits. ≥1.33 is typically required.\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">p-value: \"Probability the observed difference happened by chance.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">p < 0.05 means the groups are statistically different.\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">UCL: \"Upper Control Limit. Points above this indicate special cause\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">variation (something changed in the process).\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Cpk: "Process Capability Index. Measures how centered your process is within spec limits. ≥1.33 is typically required."p-value: "Probability the observed difference happened by chance. p \u003C 0.05 means the groups are statistically different."UCL: "Upper Control Limit. Points above this indicate special cause variation (something changed in the process)."\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Design:\u003C/strong> Tooltips appear on hover/tap with minimal delay. Uses HelpCircle icon next to terms. No clutter when not engaged.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"11-control-violation-explanations--special-cause-education\">11. Control Violation Explanations & Special Cause Education\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#11-control-violation-explanations--special-cause-education\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “11. Control Violation Explanations & Special Cause Education”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Purpose:\u003C/strong> Help users understand why points are flagged red (special cause variation) in control charts, supporting the core analysis learning journey from common vs. special cause distinction.\u003C/p>\n\u003Cp>\u003Cstrong>Implementation:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"enhanced-i-chart-tooltips\">Enhanced I-Chart Tooltips\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#enhanced-i-chart-tooltips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Enhanced I-Chart Tooltips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Hover tooltips on I-Chart data points now explain violation types:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">#42 ← Point number\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Value: 45.2 ← Measurement value\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">⚠️ Special Cause: Above UCL ← Color-coded status (red for control, factual signal)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"#42 ← Point numberValue: 45.2 ← Measurement value⚠️ Special Cause: Above UCL ← Color-coded status (red for control, factual signal)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Violation Types:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Special Cause (Red)\u003C/strong>: Control limit violations (Above/Below UCL/LCL) + Nelson Rule 2\u003C/li>\n\u003Cli>\u003Cstrong>Out-of-Spec (Orange)\u003C/strong>: Specification limit violations (Above/Below USL/LSL)\u003C/li>\n\u003Cli>\u003Cstrong>In-Control (Blue)\u003C/strong>: Normal random variation - no action needed\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"data-window-row-annotations\">Data Window Row Annotations\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#data-window-row-annotations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Window Row Annotations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Data Panel (side table) shows violation icons next to row numbers:\u003C/p>\n\u003Cul>\n\u003Cli>🟡 \u003Cstrong>AlertTriangle\u003C/strong> (amber) = Data quality issues (missing/non-numeric values)\u003C/li>\n\u003Cli>🔴 \u003Cstrong>AlertCircle\u003C/strong> (red) = Control violations (special cause)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Hover tooltip shows specific reasons:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“Special Cause: Above UCL”\u003C/li>\n\u003Cli>“Special Cause: Below LCL”\u003C/li>\n\u003Cli>“Special Cause: Nelson Rule 2 (9 consecutive points on same side of mean)”\u003C/li>\n\u003Cli>“Above USL” (spec violation)\u003C/li>\n\u003Cli>“Below LSL” (spec violation)\u003C/li>\n\u003C/ul>\n\u003Cp>Multiple violations can appear for a single point (e.g., both control and spec limits).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"educational-glossary-terms\">Educational Glossary Terms\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#educational-glossary-terms\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Educational Glossary Terms”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>New glossary terms support deeper learning (accessed via HelpTooltip icons):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Term\u003C/th>\u003Cth>Definition\u003C/th>\u003Cth>Category\u003C/th>\u003Cth>Learn More Path\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Special Cause\u003C/td>\u003Ctd>Variation due to unusual events requiring investigation\u003C/td>\u003Ctd>Methodology\u003C/td>\u003Ctd>/learn/two-voices\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Common Cause\u003C/td>\u003Ctd>Random variation inherent to stable processes\u003C/td>\u003Ctd>Methodology\u003C/td>\u003Ctd>/learn/two-voices\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Nelson Rule 2\u003C/td>\u003Ctd>9+ consecutive points on same side of mean (shift)\u003C/td>\u003Ctd>Methodology\u003C/td>\u003Ctd>/tools/i-chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>In-Control\u003C/td>\u003Ctd>Stable process with only common cause variation\u003C/td>\u003Ctd>Methodology\u003C/td>\u003Ctd>/learn/two-voices\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Pedagogical Goal:\u003C/strong> Users learn the core concept of \u003Cstrong>Special Cause vs Common Cause\u003C/strong> variation:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Blue dots\u003C/strong> = Common cause (random, inherent) → No action, process is predictable\u003C/li>\n\u003Cli>\u003Cstrong>Red dots\u003C/strong> = Special cause (assignable, unusual) → Investigate and correct\u003C/li>\n\u003Cli>This prevents both \u003Cstrong>tampering\u003C/strong> (fixing common cause) and \u003Cstrong>under-reaction\u003C/strong> (ignoring special cause)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Design Philosophy:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Use “Special Cause” terminology consistently (industry standard)\u003C/li>\n\u003Cli>Contrast with “Common Cause” to reinforce the distinction\u003C/li>\n\u003Cli>\u003Cstrong>Factual language\u003C/strong>: State the signal clearly without prescriptive action (VariScout finds WHERE to focus; user applies domain knowledge to determine WHY)\u003C/li>\n\u003Cli>Progressive disclosure: Quick tooltip → Glossary definition → Website learning content\u003C/li>\n\u003Cli>Aligns with philosophy doc: “VariScout identifies factors driving variation, not ‘root causes’”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Industry Benchmark Alignment:\u003C/strong>\nMatches Minitab, QI Macros, and Six Sigma tool patterns:\u003C/p>\n\u003Cul>\n\u003Cli>Visual indicators (red dots)\u003C/li>\n\u003Cli>Hover tooltips with rule explanations\u003C/li>\n\u003Cli>Data table annotations\u003C/li>\n\u003Cli>Pattern highlighting for Nelson rules\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"12-embed-mode--deep-linking\">12. Embed Mode & Deep Linking\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#12-embed-mode--deep-linking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “12. Embed Mode & Deep Linking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA supports URL parameters for embedding in website case studies or sharing specific analyses.\u003C/p>\n\u003Cp>\u003Cstrong>URL Parameters:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Example\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">sample=<key>\u003C/code>\u003C/td>\u003Ctd>Auto-load a sample dataset\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">?sample=mango-export\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">embed=true\u003C/code>\u003C/td>\u003Ctd>Hide header/footer for iframe\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">?sample=mango-export&embed=true\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Available Sample Keys:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Key\u003C/th>\u003Cth>Dataset\u003C/th>\u003Cth>Learning Focus\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">mango-export\u003C/code>\u003C/td>\u003Ctd>Agri-Food: Mango Export\u003C/td>\u003Ctd>Factor identification, ANOVA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">textiles-strength\u003C/code>\u003C/td>\u003Ctd>Textiles: Fabric Strength\u003C/td>\u003Ctd>Process capability, Cpk\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">coffee-defects\u003C/code>\u003C/td>\u003Ctd>Coffee: Defect Analysis\u003C/td>\u003Ctd>Pareto, defect analysis\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Embed Example:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">iframe\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">src\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://app.variscout.com?sample=mango-export&embed=true\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">title\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">VariScout Interactive Analysis\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">100%\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">600\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">frameborder\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">0\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\">></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">iframe\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ciframe src="https://app.variscout.com?sample=mango-export&embed=true" title="VariScout Interactive Analysis" width="100%" height="600" frameborder="0">\u003C/iframe>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Use Cases:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Website case study pages with guided exploration\u003C/li>\n\u003Cli>Embedding in training materials or documentation\u003C/li>\n\u003Cli>Sharing pre-configured analyses via link\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ui-design-principles\">UI Design Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ui-design-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “UI Design Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"scrollable-dashboard-layout\">Scrollable Dashboard Layout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#scrollable-dashboard-layout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scrollable Dashboard Layout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The dashboard uses a scrollable layout with minimum chart heights for comfortable analysis:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Minimum Height\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>I-Chart\u003C/td>\u003Ctd>400px\u003C/td>\u003Ctd>Primary chart needs good vertical space\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>280px\u003C/td>\u003Ctd>Enough for readable axes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto\u003C/td>\u003Ctd>280px\u003C/td>\u003Ctd>Enough for readable axes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Sticky Navigation\u003C/strong>: Breadcrumb trail and tab bar remain visible at top while scrolling.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"dashboard-structure\">Dashboard Structure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#dashboard-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dashboard Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 🏠 All Data > Machine: A [Clear All] (sticky header) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Analysis] [Regression] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ I-Chart [Outcome ▼] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (scrollable content) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Boxplot │ Pareto │ Summary │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Factor ▼] │ [Category ▼] │ [Prob] [Cap] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───────────────┴───────────────┴─────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────┐│ 🏠 All Data > Machine: A [Clear All] (sticky header) ││ [Analysis] [Regression] │├─────────────────────────────────────────────────────────────┤│ I-Chart [Outcome ▼] ││ ││ (scrollable content) ││ │├─────────────────────────────────────────────────────────────┤│ Boxplot │ Pareto │ Summary ││ [Factor ▼] │ [Category ▼] │ [Prob] [Cap] ││ │ │ │└───────────────┴───────────────┴─────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"independent-panel-selections\">Independent Panel Selections\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#independent-panel-selections\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Independent Panel Selections”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each panel has its own data selector and operates independently:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Panel\u003C/th>\u003Cth>Selection\u003C/th>\u003Cth>Required\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>I-Chart\u003C/td>\u003Ctd>Outcome (numeric column)\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Factor (categorical column)\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto\u003C/td>\u003Ctd>Category (categorical column)\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Summary\u003C/td>\u003Ctd>Uses Outcome\u003C/td>\u003Ctd>Automatic\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"empty-state-behavior\">Empty State Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#empty-state-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Empty State Behavior”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When no data is selected for a panel, it displays a dropdown prompt rather than hiding or rearranging the layout. This keeps the interface consistent and learnable.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"header--workspace-layout\">Header & Workspace Layout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#header--workspace-layout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Header & Workspace Layout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 📂 Project Name data.csv (1,247 rows) [Copy ▼] [⚙]│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ I-Chart ... │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────┐│ 📂 Project Name data.csv (1,247 rows) [Copy ▼] [⚙]│├─────────────────────────────────────────────────────────────────┤│ I-Chart ... │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Project name\u003C/td>\u003Ctd>Editable, user-defined\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data file\u003C/td>\u003Ctd>Shows source file and row count\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Copy menu\u003C/td>\u003Ctd>Copy All, Copy Chart options\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Settings\u003C/td>\u003Ctd>Gear icon for preferences\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"presentation-mode\">Presentation Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#presentation-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Presentation Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Fullscreen distraction-free view for stakeholder presentations:\u003C/p>\n\u003Cul>\n\u003Cli>Access via \u003Cstrong>View → Presentation Mode\u003C/strong>\u003C/li>\n\u003Cli>Displays all charts in optimized layout:\n\u003Cul>\n\u003Cli>I-Chart on top (~60% height)\u003C/li>\n\u003Cli>Boxplot, Pareto, Stats Panel in bottom row\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>Hides header, footer, tabs, and breadcrumbs\u003C/li>\n\u003Cli>Press \u003Cstrong>Escape\u003C/strong> to exit\u003C/li>\n\u003Cli>Subtle “Press Escape to exit” hint in bottom right\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filter-state-display\">Filter State Display\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filter-state-display\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter State Display”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Always show current filter state so users know what subset of data they’re viewing:\u003C/p>\n\u003Cp>\u003Cstrong>No filters (default):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 📂 Cycle Time Reduction n = 1,247 rows │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"│ 📂 Cycle Time Reduction n = 1,247 rows │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Filters active:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 📂 Cycle Time Reduction │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Shift = Night ✕ → Machine = Oven B ✕ [Clear] n = 47 │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"│ 📂 Cycle Time Reduction ││ Shift = Night ✕ → Machine = Oven B ✕ [Clear] n = 47 │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>Result\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Click boxplot category\u003C/td>\u003Ctd>Adds filter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Click pareto bar\u003C/td>\u003Ctd>Adds filter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Click ✕ on filter chip\u003C/td>\u003Ctd>Removes that filter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Click “Clear All”\u003C/td>\u003Ctd>Resets to full dataset\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"copy--export-workflow\">Copy & Export Workflow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#copy--export-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Copy & Export Workflow”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Option\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Copy All\u003C/td>\u003Ctd>Entire dashboard view as single image\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Copy Chart\u003C/td>\u003Ctd>Individual chart (I-Chart, Boxplot, Pareto, or Summary)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Copy Stats\u003C/td>\u003Ctd>Summary statistics as formatted text\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Charts are copied to clipboard as PNG — paste directly into PowerPoint, Word, Google Slides, or email.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"design-principles-summary\">Design Principles Summary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#design-principles-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Principles Summary”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Principle\u003C/th>\u003Cth>Implementation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Scrollable layout\u003C/td>\u003Ctd>Charts have comfortable min-heights\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sticky navigation\u003C/td>\u003Ctd>Breadcrumb and tabs visible while scrolling\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Consistent layout\u003C/td>\u003Ctd>Same structure regardless of data selections\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Independent selections\u003C/td>\u003Ctd>Each panel has its own data selector\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Empty state = prompt\u003C/td>\u003Ctd>Shows dropdown when no data selected\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Presentation mode\u003C/td>\u003Ctd>Fullscreen view for stakeholder meetings\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whats-not-included\">What’s NOT Included\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whats-not-included\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What’s NOT Included”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Why excluded\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>AI recommendations\u003C/td>\u003Ctd>Requires LLM, ongoing costs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Natural language insights\u003C/td>\u003Ctd>AI-dependent\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Intent modes (Explore/Hypothesis/Monitor)\u003C/td>\u003Ctd>Adds complexity\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Investigation lifecycle\u003C/td>\u003Ctd>Overkill for simple analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Playbooks / guided workflows\u003C/td>\u003Ctd>AI-dependent\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cloud sync\u003C/td>\u003Ctd>Offline-first design\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multi-user / collaboration\u003C/td>\u003Ctd>Single-user tool\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Philosophy:\u003C/strong> Lite users know what they’re doing. They need visualization, not guidance.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-architecture\">Technical Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Progressive Web App (PWA) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ React Frontend │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Visx charts (I-Chart, Box, Pareto) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Filter state management │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Export handlers │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Local Processing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── CSV/Excel parser │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Statistics engine (JS) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Control limit calculations │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Browser APIs │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── IndexedDB (project storage) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Service Worker (offline) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── File API (import/export) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">NO backend. NO API calls. Works offline after first visit.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────┐│ Progressive Web App (PWA) │├─────────────────────────────────────────┤│ React Frontend ││ ├── Visx charts (I-Chart, Box, Pareto) ││ ├── Filter state management ││ └── Export handlers │├─────────────────────────────────────────┤│ Local Processing ││ ├── CSV/Excel parser ││ ├── Statistics engine (JS) ││ └── Control limit calculations │├─────────────────────────────────────────┤│ Browser APIs ││ ├── IndexedDB (project storage) ││ ├── Service Worker (offline) ││ └── File API (import/export) │└─────────────────────────────────────────┘NO backend. NO API calls. Works offline after first visit.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Deployment:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Vercel, Netlify, or any static host\u003C/li>\n\u003Cli>Users access via URL\u003C/li>\n\u003Cli>Service Worker enables offline use after first visit\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"products--pricing\">Products & Pricing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#products--pricing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Products & Pricing”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth>Distribution\u003C/th>\u003Cth>Pricing\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Azure Standard\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>€99/month (full analysis, local files)\u003C/td>\u003Ctd>\u003Cstrong>PRIMARY\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure Team\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>€299/month (+ Teams, OneDrive, SharePoint, mobile)\u003C/td>\u003Ctd>\u003Cstrong>PRIMARY\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PWA\u003C/td>\u003Ctd>Public URL\u003C/td>\u003Ctd>FREE (forever, training & education)\u003C/td>\u003Ctd>Production\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"free-pwa\">Free (PWA)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#free-pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Free (PWA)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>All core chart types (I-Chart, Boxplot, Pareto, Capability, Regression, ANOVA)\u003C/li>\n\u003Cli>Copy-paste data input + sample datasets\u003C/li>\n\u003Cli>VariScout branding on charts\u003C/li>\n\u003Cli>Session-only storage (no save)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-azure-app--99month\">Standard (Azure App — €99/month)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-azure-app--99month\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard (Azure App — €99/month)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>All features, unlimited users\u003C/li>\n\u003Cli>EasyAuth (Microsoft SSO), file upload, save/persistence\u003C/li>\n\u003Cli>Performance Mode (multi-channel analysis)\u003C/li>\n\u003Cli>Watermark-free exports, custom theming\u003C/li>\n\u003Cli>Managed Application deployment via Azure Marketplace\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"team-azure-app--299month\">Team (Azure App — €299/month)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#team-azure-app--299month\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Team (Azure App — €299/month)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Everything in Standard, plus:\u003C/li>\n\u003Cli>Teams integration (channel tabs, SSO)\u003C/li>\n\u003Cli>OneDrive and SharePoint sync\u003C/li>\n\u003Cli>Mobile access via Teams app\u003C/li>\n\u003Cli>Photo evidence with EXIF stripping\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Build Commands:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build all packages and apps\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm build # Build all packages and apps\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"build-estimate\">Build Estimate\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#build-estimate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Build Estimate”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Effort\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Chart components\u003C/td>\u003Ctd>Done\u003C/td>\u003Ctd>Already built\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Linked filtering\u003C/td>\u003Ctd>Done\u003C/td>\u003Ctd>Already built\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Statistics engine\u003C/td>\u003Ctd>Done\u003C/td>\u003Ctd>Cp/Cpk, conformance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data import\u003C/td>\u003Ctd>Done\u003C/td>\u003Ctd>CSV + Excel parsing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Save/Load (.vrs)\u003C/td>\u003Ctd>Done\u003C/td>\u003Ctd>JSON serialization + file handling\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Export (PNG/CSV)\u003C/td>\u003Ctd>Done\u003C/td>\u003Ctd>DOM-based capture, CSV generation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Edition config\u003C/td>\u003Ctd>Done\u003C/td>\u003Ctd>Watermark + branding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Manual Entry\u003C/td>\u003Ctd>Done\u003C/td>\u003Ctd>Touch-optimized data entry\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data Table\u003C/td>\u003Ctd>Done\u003C/td>\u003Ctd>Inline editing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shared charts package\u003C/td>\u003Ctd>Done\u003C/td>\u003Ctd>@variscout/charts with props-based components\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Completed\u003C/strong>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>Core features implemented\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Downloads\u003C/td>\u003Ctd>500 in first year\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Active users\u003C/td>\u003Ctd>100 monthly\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Conversion to Licensed\u003C/td>\u003Ctd>5% of active users\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Support tickets\u003C/td>\u003Ctd>< 10/month (simple tool = few questions)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"planned-features-green-belt-training\">Planned Features (Green Belt Training)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#planned-features-green-belt-training\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Planned Features (Green Belt Training)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For complete Green Belt training coverage, two features are planned.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"feature-summary\">Feature Summary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#feature-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Summary”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Effort\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>ANOVA under Boxplot\u003C/td>\u003Ctd>Enhancement\u003C/td>\u003Ctd>Small\u003C/td>\u003Ctd>Statistical confirmation of group differences\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regression Tab\u003C/td>\u003Ctd>New Tab\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Multi-factor comparison with auto-fit intelligence\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"anova-integration\">ANOVA Integration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#anova-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ANOVA Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Add ANOVA calculations below the existing boxplot visualization:\u003C/p>\n\u003Cul>\n\u003Cli>Group means, sample sizes, and standard deviations\u003C/li>\n\u003Cli>F-ratio and p-value\u003C/li>\n\u003Cli>Plain-language interpretation: “Different? YES (p = 0.003)”\u003C/li>\n\u003Cli>No separate t-test needed (2-group ANOVA is mathematically equivalent)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"regression-tab\">Regression Tab\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#regression-tab\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Regression Tab”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A new tab with 2×2 grid of scatter plots:\u003C/p>\n\u003Cul>\n\u003Cli>Each plot shows one X-Y relationship with regression line\u003C/li>\n\u003Cli>R² value with star rating (★★★★★ for > 0.9)\u003C/li>\n\u003Cli>Auto-fit intelligence (recommends quadratic when appropriate)\u003C/li>\n\u003Cli>Summary ranking: “Temperature → Speed → Pressure” by R² strength\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-positioning\">Competitive Positioning\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-positioning\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Positioning”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"vs-minitab\">vs Minitab\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#vs-minitab\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “vs Minitab”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Minitab\u003C/th>\u003Cth>VaRiScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Price\u003C/td>\u003Ctd>$1,000+/year\u003C/td>\u003Ctd>From €99/month or free\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Installation\u003C/td>\u003Ctd>Desktop software\u003C/td>\u003Ctd>Browser (no install)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Learning curve\u003C/td>\u003Ctd>Steep\u003C/td>\u003Ctd>Minimal\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Feature depth\u003C/td>\u003Ctd>Deep (30 years)\u003C/td>\u003Ctd>Focused (essentials)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Target\u003C/td>\u003Ctd>Statisticians\u003C/td>\u003Ctd>Everyone\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"vs-excel\">vs Excel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#vs-excel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “vs Excel”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Excel\u003C/th>\u003Cth>VaRiScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Setup\u003C/td>\u003Ctd>Build from scratch\u003C/td>\u003Ctd>Ready to use\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Control limits\u003C/td>\u003Ctd>Manual calculation\u003C/td>\u003Ctd>Automatic\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Linked filtering\u003C/td>\u003Ctd>Complex\u003C/td>\u003Ctd>One click\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Export quality\u003C/td>\u003Ctd>Varies\u003C/td>\u003Ctd>Consistent\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"positioning-statement\">Positioning Statement\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#positioning-statement\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Positioning Statement”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“VaRiScout is for practitioners who need answers, not statisticians who need tools. Simple enough for anyone. Rigorous enough for experts.”\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics-1\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"product-metrics\">Product Metrics\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#product-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Time to first chart\u003C/td>\u003Ctd>< 2 minutes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Free → Paid conversion\u003C/td>\u003Ctd>5-10%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Monthly active users (free)\u003C/td>\u003Ctd>1,000+\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Paid subscribers\u003C/td>\u003Ctd>100+ (Year 1)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"business-metrics\">Business Metrics\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#business-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Business Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Year 1 Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>ARR (PWA + Excel)\u003C/td>\u003Ctd>€25,000\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Support tickets/user\u003C/td>\u003Ctd>< 0.1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Churn rate\u003C/td>\u003Ctd>< 20%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"summary\">Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>VariScout\u003C/strong> is a fast, offline variation analysis tool for people who know what they’re doing but need better tools than Excel. No AI, no subscriptions, no complexity — just linked charts that reveal hidden variation.\u003C/p>\n\u003Cp>Perfect for quality professionals and LSS trainers: distribute freely, zero ongoing costs, clean licensing.\u003C/p>\n\u003C/blockquote>", + { + "headings": 1297, + "localImagePaths": 1452, + "remoteImagePaths": 1453, + "frontmatter": 1454, + "imagePaths": 1455 + }, + [ + 1298, 1300, 1303, 1304, 1307, 1310, 1313, 1316, 1319, 1322, 1325, 1328, 1331, 1334, 1337, 1340, + 1343, 1346, 1349, 1352, 1355, 1358, 1361, 1364, 1367, 1370, 1373, 1376, 1379, 1382, 1385, 1388, + 1391, 1394, 1397, 1400, 1403, 1404, 1407, 1410, 1413, 1416, 1419, 1422, 1425, 1428, 1431, 1432, + 1435, 1438, 1441, 1443, 1446, 1449 + ], + { "depth": 30, "slug": 1299, "text": 1287 }, + "variscout--product-spec", + { "depth": 33, "slug": 1301, "text": 1302 }, + "what-is-it", + "What Is It?", + { "depth": 33, "slug": 995, "text": 996 }, + { "depth": 33, "slug": 1305, "text": 1306 }, + "core-features", + "Core Features", + { "depth": 79, "slug": 1308, "text": 1309 }, + "1-data-import", + "1. Data Import", + { "depth": 79, "slug": 1311, "text": 1312 }, + "2-three-chart-dashboard", + "2. Three-Chart Dashboard", + { "depth": 79, "slug": 1314, "text": 1315 }, + "3-interactive-analysis-multi-vari", + "3. Interactive Analysis (Multi-Vari)", + { "depth": 79, "slug": 1317, "text": 1318 }, + "4-statistics-panel", + "4. Statistics Panel", + { "depth": 79, "slug": 1320, "text": 1321 }, + "spec-discovery-flow-progressive-disclosure", + "Spec Discovery Flow (Progressive Disclosure)", + { "depth": 79, "slug": 1323, "text": 1324 }, + "5-data-table-viewedit-data", + "5. Data Table (View/Edit Data)", + { "depth": 79, "slug": 1326, "text": 1327 }, + "6-save--load-analysis-azure-app", + "6. Save & Load Analysis (Azure App)", + { "depth": 79, "slug": 1329, "text": 1330 }, + "7-chart-annotations", + "7. Chart Annotations", + { "depth": 621, "slug": 1332, "text": 1333 }, + "boxplot-and-pareto-right-click-context-menu", + "Boxplot and Pareto: Right-Click Context Menu", + { "depth": 621, "slug": 1335, "text": 1336 }, + "i-chart-free-floating-text-notes", + "I-Chart: Free-Floating Text Notes", + { "depth": 621, "slug": 1338, "text": 1339 }, + "text-note-editing-all-charts", + "Text Note Editing (All Charts)", + { "depth": 621, "slug": 1341, "text": 1342 }, + "clear-all", + "Clear All", + { "depth": 79, "slug": 1344, "text": 1345 }, + "8-export", + "8. Export", + { "depth": 79, "slug": 1347, "text": 1348 }, + "9-branding-implemented", + "9. Branding (Implemented)", + { "depth": 79, "slug": 1350, "text": 1351 }, + "10-statistical-tooltips", + "10. Statistical Tooltips", + { "depth": 79, "slug": 1353, "text": 1354 }, + "11-control-violation-explanations--special-cause-education", + "11. Control Violation Explanations & Special Cause Education", + { "depth": 621, "slug": 1356, "text": 1357 }, + "enhanced-i-chart-tooltips", + "Enhanced I-Chart Tooltips", + { "depth": 621, "slug": 1359, "text": 1360 }, + "data-window-row-annotations", + "Data Window Row Annotations", + { "depth": 621, "slug": 1362, "text": 1363 }, + "educational-glossary-terms", + "Educational Glossary Terms", + { "depth": 79, "slug": 1365, "text": 1366 }, + "12-embed-mode--deep-linking", + "12. Embed Mode & Deep Linking", + { "depth": 33, "slug": 1368, "text": 1369 }, + "ui-design-principles", + "UI Design Principles", + { "depth": 79, "slug": 1371, "text": 1372 }, + "scrollable-dashboard-layout", + "Scrollable Dashboard Layout", + { "depth": 79, "slug": 1374, "text": 1375 }, + "dashboard-structure", + "Dashboard Structure", + { "depth": 79, "slug": 1377, "text": 1378 }, + "independent-panel-selections", + "Independent Panel Selections", + { "depth": 79, "slug": 1380, "text": 1381 }, + "empty-state-behavior", + "Empty State Behavior", + { "depth": 79, "slug": 1383, "text": 1384 }, + "header--workspace-layout", + "Header & Workspace Layout", + { "depth": 79, "slug": 1386, "text": 1387 }, + "presentation-mode", + "Presentation Mode", + { "depth": 79, "slug": 1389, "text": 1390 }, + "filter-state-display", + "Filter State Display", + { "depth": 79, "slug": 1392, "text": 1393 }, + "copy--export-workflow", + "Copy & Export Workflow", + { "depth": 79, "slug": 1395, "text": 1396 }, + "design-principles-summary", + "Design Principles Summary", + { "depth": 33, "slug": 1398, "text": 1399 }, + "whats-not-included", + "What’s NOT Included", + { "depth": 33, "slug": 1401, "text": 1402 }, + "technical-architecture", + "Technical Architecture", + { "depth": 33, "slug": 43, "text": 44 }, + { "depth": 79, "slug": 1405, "text": 1406 }, + "free-pwa", + "Free (PWA)", + { "depth": 79, "slug": 1408, "text": 1409 }, + "standard-azure-app--99month", + "Standard (Azure App — €99/month)", + { "depth": 79, "slug": 1411, "text": 1412 }, + "team-azure-app--299month", + "Team (Azure App — €299/month)", + { "depth": 33, "slug": 1414, "text": 1415 }, + "build-estimate", + "Build Estimate", + { "depth": 33, "slug": 1417, "text": 1418 }, + "success-metrics", + "Success Metrics", + { "depth": 33, "slug": 1420, "text": 1421 }, + "planned-features-green-belt-training", + "Planned Features (Green Belt Training)", + { "depth": 79, "slug": 1423, "text": 1424 }, + "feature-summary", + "Feature Summary", + { "depth": 79, "slug": 1426, "text": 1427 }, + "anova-integration", + "ANOVA Integration", + { "depth": 79, "slug": 1429, "text": 1430 }, + "regression-tab", + "Regression Tab", + { "depth": 33, "slug": 815, "text": 816 }, + { "depth": 79, "slug": 1433, "text": 1434 }, + "vs-minitab", + "vs Minitab", + { "depth": 79, "slug": 1436, "text": 1437 }, + "vs-excel", + "vs Excel", + { "depth": 79, "slug": 1439, "text": 1440 }, + "positioning-statement", + "Positioning Statement", + { "depth": 33, "slug": 1442, "text": 1418 }, + "success-metrics-1", + { "depth": 79, "slug": 1444, "text": 1445 }, + "product-metrics", + "Product Metrics", + { "depth": 79, "slug": 1447, "text": 1448 }, + "business-metrics", + "Business Metrics", + { "depth": 33, "slug": 1450, "text": 1451 }, + "summary", + "Summary", + [], + [], + { "title": 1287 }, + [], + "05-technical/architecture", + { "id": 1456, "data": 1458, "body": 1463, "filePath": 1464, "digest": 1465, "rendered": 1466 }, + { + "title": 1459, + "editUrl": 16, + "head": 1460, + "template": 18, + "sidebar": 1461, + "pagefind": 16, + "draft": 20 + }, + "VariScout: Architecture Overview", + [], + { "hidden": 20, "attrs": 1462 }, + {}, + "# VariScout: Architecture Overview\n\nVariScout Lite is designed as a **browser-first**, **offline-capable** Progressive Web App (PWA) for manufacturing variation analysis. It prioritizes data privacy (no cloud) and works on any device.\n\n## 1. Repository Structure\n\nVariScout Lite uses a **pnpm workspaces monorepo** to support multiple applications from shared code:\n\n```\nvariscout-lite/\n├── packages/\n│ ├── core/ # @variscout/core - Pure logic (stats, parser, tier, glossary)\n│ ├── charts/ # @variscout/charts - Props-based Visx chart components\n│ ├── data/ # @variscout/data - Sample datasets with pre-computed chart data\n│ ├── hooks/ # @variscout/hooks - Shared React hooks (filter navigation, scale, tracking)\n│ └── ui/ # @variscout/ui - Shared UI components, colors, and hooks\n├── apps/\n│ ├── pwa/ # PWA website (React + Vite + PWA)\n│ ├── azure/ # Azure Team App (EasyAuth + OneDrive sync)\n│ └── website/ # Marketing website (Astro + React Islands)\n├── docs/\n│ ├── 01-vision/ # Product philosophy, Four Lenses, Two Voices\n│ ├── 02-journeys/ # User research, personas, flows\n│ ├── 03-features/ # Feature documentation (analysis, workflows, data, navigation)\n│ ├── 04-cases/ # Case studies with demo data\n│ ├── 05-technical/ # Technical architecture and implementation\n│ ├── 06-design-system/ # Design tokens, components, charts\n│ ├── 07-decisions/ # Architecture Decision Records\n│ └── 08-products/ # Product specs (Azure, PWA, Website)\n├── pnpm-workspace.yaml # Workspace configuration\n├── tsconfig.base.json # Shared TypeScript config\n└── package.json # Root scripts\n```\n\n> **Detailed monorepo documentation:** [Monorepo Architecture](architecture/monorepo.md)\n\n## 2. High-Level Stack\n\n- **Runtime**: Progressive Web App (PWA) with Service Worker\n- **Frontend**: [React](https://react.dev/) + [TypeScript](https://www.typescriptlang.org/) + [Vite](https://vitejs.dev/)\n- **Styling**: [Tailwind CSS](https://tailwindcss.com/) (Utility-first)\n- **Visualization**: [Visx](https://airbnb.io/visx/) (Low-level D3 primitives for React) via `@variscout/charts`\n- **Shared Logic**: `@variscout/core` package (stats, parser, tier, glossary)\n- **Persistence**: IndexedDB + OneDrive sync (Azure App), session-only (PWA)\n- **PWA**: [vite-plugin-pwa](https://vite-pwa-org.netlify.app/) with Workbox\n- **Marketing Website**: [Astro 5](https://astro.build/) with React Islands (chart demos)\n- **Package Manager**: [pnpm](https://pnpm.io/) with workspaces\n\n## 3. Package Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│ APPS │\n├─────────────────────────────────────────────────────────────────────────────┤\n│ @variscout/pwa │ @variscout/azure-app │\n│ (apps/pwa/) │ (apps/azure/) │\n│ ┌──────────┐ ┌──────┐ ┌────────┐ │ ┌──────────┐ ┌────────┐ ┌─────────┐ │\n│ │Components│ │Context│ │Session │ │ │Components│ │EasyAuth│ │Sync(IDB)│ │\n│ │(Mobile) │ │(Data) │ │ only │ │ │(Editor) │ │(SSO) │ │+OneDrive│ │\n│ └────┬─────┘ └───┬───┘ └───┬────┘ │ └────┬─────┘ └───┬────┘ └────┬────┘ │\n│ └───────────┼─────────┘ │ └───────────┼───────────┘ │\n│ │ │ │ │\n└───────────────────┼─────────────────┴────────────────────┼───────────────────┘\n │ │\n ▼ ▼\n┌─────────────────────────────────────────────────────────────────────────────┐\n│ PACKAGES │\n├─────────────────────────────────────┬───────────────────────────────────────┤\n│ @variscout/charts │ @variscout/core │\n│ (packages/charts/) │ (packages/core/) │\n│ │ │\n│ IChart │ Boxplot │ ParetoChart │ stats/ │ parser/ │ tier.ts │\n│ CapabilityHistogram │ responsive │ glossary │ export.ts │ types.ts │\n├─────────────────────────────────────┼───────────────────────────────────────┤\n│ @variscout/hooks │ @variscout/data │\n│ (packages/hooks/) │ (packages/data/) │\n│ │ │\n│ useChartScale │ useFilterNavigation│ coffee │ journey │ bottleneck │\n│ useVariationTracking │ useTier │ sachets │ pre-computed chart data │\n├─────────────────────────────────────┼───────────────────────────────────────┤\n│ @variscout/ui │\n│ (packages/ui/) │\n│ AnovaResults │ FilterBreadcrumb │ FilterChipDropdown │ RegressionPanel │\n│ PerformanceSetupPanel │ VariationBar │ YAxisPopover │ TierBadge │\n│ UpgradePrompt │ ChartCard │ ColumnMapping │ HelpTooltip │ colors │\n└─────────────────────────────────────────────────────────────────────────────┘\n\n```\n\n### @variscout/core\n\nPure TypeScript logic with no React dependencies:\n\n| Module | Purpose |\n| --------------- | -------------------------------------------------------------------------- |\n| `stats/` | Mean, StdDev, UCL/LCL, Cp, Cpk, conformance, factor grouping, staged stats |\n| `parser/` | CSV/Excel file parsing, validation, keyword detection |\n| `tier.ts` | Tier configuration (Azure Marketplace licensing, channel limits) |\n| `navigation.ts` | Navigation types and utilities (FilterAction, BreadcrumbItem) |\n| `variation/` | Cumulative variation tracking (η² cascading, drill suggestions) |\n| `glossary/` | Glossary terms and type definitions for help tooltips |\n| `export.ts` | CSV export utilities |\n| `types.ts` | Shared TypeScript interfaces (StatsResult, LicenseTier, etc.) |\n\n### @variscout/charts\n\nProps-based React components using Visx for data visualization:\n\n| Module | Purpose |\n| ------------------------- | --------------------------------------------------------------- |\n| `IChart.tsx` | Individual control chart with `IChartBase` export |\n| `Boxplot.tsx` | Factor comparison with `BoxplotBase` export (`showViolin` prop) |\n| `ParetoChart.tsx` | Frequency analysis with `ParetoChartBase` export |\n| `CapabilityHistogram.tsx` | Distribution histogram with spec limits |\n| `ProbabilityPlot.tsx` | Normal probability plot with CI bands |\n| `ChartSourceBar.tsx` | Branding footer component |\n| `responsive.ts` | `getResponsiveMargins`, `getResponsiveFonts` |\n| `types.ts` | Chart prop interfaces, `calculateBoxplotStats()` |\n\n### @variscout/data\n\nPre-computed sample datasets for the marketing website's React Islands. Provides ready-to-render chart data without runtime computation.\n\n| Module | Purpose |\n| -------------- | -------------------------------------------------------- |\n| `samples/*.ts` | Individual sample datasets (coffee, journey, bottleneck) |\n| `types.ts` | SampleDataset interface definition |\n| `index.ts` | `getSample()` helper and sample registry |\n\nEach sample exports:\n\n- `rawData` - Original records\n- `stats` - Pre-calculated StatsResult\n- `specs` - USL/LSL/Target\n- `ichartData` - Pre-formatted IChartPoint[]\n- `boxplotData` - Pre-calculated BoxplotGroup[]\n- `paretoData` - Pre-aggregated ParetoItem[]\n\n**Usage:**\n\n```typescript\nimport { getSample } from '@variscout/data';\n\nconst sample = getSample('coffee');\n// Use sample.ichartData, sample.boxplotData, etc.\n```\n\n### @variscout/ui\n\nShared UI component library for PWA and Azure apps.\n\n- **Stack**: React + Tailwind CSS + Radix UI + Lucide React.\n- **Goal**: Ensure consistent design system implementation across web properties.\n- **Components**: `AnovaResults`, `FilterBreadcrumb`, `FilterChipDropdown`, `PerformanceSetupPanelBase`, `RegressionPanelBase`, `VariationBar`, `YAxisPopover`, `ChartCard`, `ColumnMapping`, `MeasureColumnSelector`, `PerformanceDetectedModal`, `DataQualityBanner`, `HelpTooltip`, `SelectionPanel`, `CreateFactorModal`, `TierBadge`, `UpgradePrompt`.\n- **Hooks**: `useIsMobile`, `useGlossary`.\n- **Services**: `errorService`.\n\n### @variscout/hooks\n\nShared React hooks for cross-platform functionality:\n\n| Hook | Purpose |\n| --------------------------- | ------------------------------------------------------------- |\n| `useChartScale` | Calculate Y-axis range from data, specs, and axis settings |\n| `useFilterNavigation` | Filter navigation with multi-select and filter chip support |\n| `useVariationTracking` | Cumulative η² tracking + filter chip data with contribution % |\n| `useKeyboardNavigation` | Arrow key navigation and focus management |\n| `useResponsiveChartMargins` | Dynamic chart margins based on container width |\n| `useDataState` | Shared DataContext state management |\n| `useDataIngestion` | File upload and data parsing |\n| `useTier` | License tier state and limits (Azure Marketplace) |\n| `useAvailableOutcomes` | Available outcome columns for analysis |\n| `useAvailableStageColumns` | Available stage columns for staged analysis |\n| `useChartNavigation` | Chart tab navigation and ordering |\n| `useClipboardCopy` | Clipboard copy with feedback |\n| `useColumnClassification` | Column type classification for regression |\n| `useRegressionState` | Regression analysis mode and state management |\n\n**Key types:**\n\n| Type | Purpose |\n| --------------------------- | -------------------------------------------------------------- |\n| `FilterChipData` | Filter chip data with contribution % and available values |\n| `UseFilterNavigationReturn` | Return type including `updateFilterValues()`, `removeFilter()` |\n| `VariationTrackingResult` | Return type including `filterChipData` |\n| `UseTierResult` | Tier info, validation functions, warning messages |\n\n**Usage:**\n\n```typescript\nimport {\n useFilterNavigation,\n useVariationTracking,\n useChartScale,\n useTier,\n type FilterChipData,\n} from '@variscout/hooks';\n```\n\n### Internationalization (i18n)\n\nImplemented using `i18next` and `react-i18next`.\n\n- **Strategy**: Per-app configuration (isolated/bundled JSON files).\n- **Languages**: English (`en`), Finnish (`fi`).\n- **Detection**: Browser language detection with fallback to English.\n\n### @variscout/pwa\n\nReact application with PWA capabilities:\n\n| Module | Purpose |\n| --------------------------------- | ------------------------------- |\n| `context/DataContext.tsx` | Centralized state management |\n| `components/Dashboard.tsx` | Main 3-chart layout |\n| `components/FilterBreadcrumb.tsx` | Breadcrumb navigation component |\n| `components/Mobile*.tsx` | Mobile-optimized components |\n| `hooks/useFilterNavigation.ts` | Filter navigation hook |\n| `lib/persistence.ts` | IndexedDB + localStorage |\n| `hooks/useResponsive*.ts` | Responsive sizing hooks |\n\n### @variscout/azure-app\n\nCloud-connected team application:\n\n| Module | Purpose |\n| ------------------------- | -------------------------------------- |\n| `src/auth/easyAuth.ts` | App Service EasyAuth helper (SSO) |\n| `src/services/storage.ts` | Offline-first storage + OneDrive sync |\n| `src/context/DataContext` | Central state management (mirrors PWA) |\n| `src/components/Editor` | Main editor with data panel + charts |\n\n### @variscout/website\n\nMarketing and education website (Astro 5 + React 19 Islands):\n\n| Module | Purpose |\n| ------------------------------ | ---------------------------------------------------- |\n| `src/data/toolsData.ts` | 7 tool page definitions (slug, lens, content) |\n| `src/data/learnData.ts` | 11 learn topic definitions with visual sections |\n| `src/data/glossaryData.ts` | ~26 glossary terms extending @variscout/core |\n| `src/i18n/ui.ts` | Translation strings for 5 languages (en/de/es/fr/pt) |\n| `src/i18n/utils.ts` | getLangFromUrl(), useTranslations() |\n| `src/components/islands/` | 9 React islands (chart demos, hydrated on scroll) |\n| `src/layouts/BaseLayout.astro` | SEO meta, OG tags, Schema.org structured data |\n\nStatic HTML generated by Astro; React only loads for interactive chart demos via `client:visible` hydration. Content managed through TypeScript data files (no CMS). Generates 379 pages across 5 languages.\n\n## 4. Core Modules\n\n### 4.1 Data Context (`apps/pwa/src/context/DataContext.tsx`)\n\nThe application uses a centralized React Context to manage the entire analysis state.\n\n- **State (`filteredData`)**: Derived from `rawData` based on active global filters.\n- **Performance**: Uses `useMemo` extensively to prevent re-calculating statistics on every render.\n- **Persistence**: Azure App exposes methods for IndexedDB save/load. PWA is session-only.\n- **Flow**: Import → `setRawData` → `detectColumns` → `DataContext` Updates → Charts Render.\n\n### 4.2 Statistics Engine (`packages/core/src/stats.ts`)\n\nA tailored math library that computes quality control metrics on the fly.\n\n- **Metrics**: Mean, StdDev, UCL/LCL (3-sigma), Cp, Cpk, Out-of-Spec %.\n- **Logic**: Handles both standard (USL & LSL) and one-sided (USL or LSL only) specifications.\n\n**Staged Statistics** (for staged I-Charts):\n\n| Function | Purpose |\n| ------------------------- | ----------------------------------------------- |\n| `determineStageOrder()` | Auto-detect numeric patterns for stage sorting |\n| `sortDataByStage()` | Stable sort data by stage order |\n| `calculateStatsByStage()` | Calculate per-stage statistics (UCL, Mean, LCL) |\n| `getStageBoundaries()` | Get X boundaries for chart rendering |\n\n### 4.3 Visualization Layer (`apps/pwa/src/components/charts/`)\n\nBuilt with Visx to ensure complete control over rendering behavior and interactions.\n\n- **I-Chart**: Time-series visualization with dynamic control limit overlays.\n- **Boxplot**: Distribution analysis showing quartiles and outliers.\n- **Pareto**: Factor frequency analysis.\n\n### 4.4 Persistence Layer (`apps/pwa/src/lib/persistence.ts`)\n\nHandles all data storage operations in the browser.\n\n- **Analysis Storage**: Named analyses saved to IndexedDB via explicit save/load actions.\n- **File Export/Import**: Download/upload `.vrs` JSON files for portability.\n\n## 5. Data Persistence\n\n### Azure App\n\n- Named analyses saved to IndexedDB + synced to OneDrive\n- .vrs file export/import for portability across devices/browsers\n- List, load, rename, delete operations\n- App starts on HomeScreen with recent analyses list\n\n### PWA (Free)\n\n- Session-only — data lives in React state, cleared on refresh\n- No save, no IndexedDB projects, no .vrs files\n- Users paste data or load samples each session\n- CSV/PNG export available during session\n\n## 6. Directory Structure\n\n```\nvariscout-lite/\n├── packages/\n│ ├── core/ # @variscout/core\n│ │ ├── src/\n│ │ │ ├── index.ts # Barrel export\n│ │ │ ├── stats/ # Statistics calculations (13 domain modules)\n│ │ │ ├── parser/ # File parsing (csv, excel, detection, validation)\n│ │ │ ├── variation/ # Variation tracking (drill, contributions, suggestions)\n│ │ │ ├── tier.ts # Tier configuration (Azure Marketplace)\n│ │ │ ├── glossary/ # Glossary terms and types\n│ │ │ ├── export.ts # CSV export\n│ │ │ └── types.ts # Shared interfaces\n│ │ ├── package.json\n│ │ └── tsconfig.json\n│ │\n│ ├── charts/ # @variscout/charts\n│ │ ├── src/\n│ │ │ ├── index.ts # Barrel export\n│ │ │ ├── IChart.tsx # I-Chart component\n│ │ │ ├── Boxplot.tsx # Boxplot component\n│ │ │ ├── ParetoChart.tsx # Pareto chart component\n│ │ │ ├── CapabilityHistogram.tsx\n│ │ │ ├── ProbabilityPlot.tsx\n│ │ │ ├── ChartSourceBar.tsx\n│ │ │ ├── responsive.ts # Responsive utilities\n│ │ │ └── types.ts # Chart interfaces\n│ │ ├── package.json\n│ │ └── tsconfig.json\n│ │\n│ ├── hooks/ # @variscout/hooks\n│ │ ├── src/\n│ │ │ ├── index.ts # Barrel export\n│ │ │ ├── useChartScale.ts # Y-axis scale calculation\n│ │ │ ├── useFilterNavigation.ts # Filter navigation\n│ │ │ ├── useVariationTracking.ts # Cumulative Total SS tracking\n│ │ │ ├── useKeyboardNavigation.ts # Keyboard navigation\n│ │ │ ├── useResponsiveChartMargins.ts # Responsive margins\n│ │ │ ├── useResponsiveChartFonts.ts # Responsive font sizes\n│ │ │ ├── useResponsiveTickCount.ts # Responsive tick counts\n│ │ │ ├── useResponsiveBreakpoints.ts # Responsive breakpoints\n│ │ │ ├── useDataState.ts # Shared DataContext state\n│ │ │ ├── useDataIngestion.ts # File upload and parsing\n│ │ │ ├── useTier.ts # Tier state and limits\n│ │ │ ├── useColumnClassification.ts # Column type classification\n│ │ │ ├── useDrillPath.ts # Drill path state\n│ │ │ ├── useMindmapState.ts # Mindmap state management\n│ │ │ ├── useBoxplotData.ts # Shared d3 boxplot computation\n│ │ │ ├── useIChartData.ts # Shared I-Chart data transform\n│ │ │ ├── useAnnotations.ts # Chart annotation state\n│ │ │ ├── useThemeState.ts # Theme state (light/dark/system)\n│ │ │ ├── useControlViolations.ts # Control/spec violation computation\n│ │ │ ├── useFocusedChartNav.ts # Keyboard chart focus navigation\n│ │ │ ├── useHighlightFade.ts # Highlight fade animation\n│ │ │ ├── useResizablePanel.ts # Resizable panel state\n│ │ │ └── useDataTablePagination.ts # Data table pagination\n│ │ ├── package.json\n│ │ └── tsconfig.json\n│ │\n│ └── ui/ # @variscout/ui\n│ ├── src/\n│ │ ├── index.ts # Barrel export\n│ │ ├── colors.ts # UI color constants (statusColors)\n│ │ ├── hooks/ # useMediaQuery, useGlossary\n│ │ ├── services/ # errorService\n│ │ ├── styles/ # theme.css, components.css\n│ │ ├── components/ # Shared UI components\n│ │ │ ├── AnovaResults/\n│ │ │ ├── FilterBreadcrumb/\n│ │ │ ├── FilterChipDropdown/\n│ │ │ ├── FilterContextBar/\n│ │ │ ├── PerformanceSetupPanel/\n│ │ │ ├── VariationBar/\n│ │ │ ├── YAxisPopover/\n│ │ │ ├── UpgradePrompt/\n│ │ │ ├── ChartCard/\n│ │ │ ├── ColumnMapping/\n│ │ │ ├── HelpTooltip/\n│ │ │ ├── DashboardBase/ # FocusedViewOverlay, FocusedChartCard,\n│ │ │ │ # DashboardChartCard, DashboardGrid\n│ │ │ ├── StatsPanelBase/\n│ │ │ ├── MindmapWindow/\n│ │ │ ├── MindmapPanel/\n│ │ │ ├── WhatIfSimulator/\n│ │ │ ├── WhatIfPage/\n│ │ │ ├── ErrorBoundary/\n│ │ │ ├── AxisEditor/\n│ │ │ ├── FactorSelector/\n│ │ │ ├── SpecsPopover/\n│ │ │ ├── SpecEditor/\n│ │ │ ├── CapabilityHistogram/\n│ │ │ ├── ProbabilityPlot/\n│ │ │ ├── BoxplotDisplayToggle/\n│ │ │ ├── ChartAnnotationLayer/\n│ │ │ ├── AnnotationContextMenu/\n│ │ │ ├── DataTable/\n│ │ │ ├── ChartDownloadMenu/\n│ │ │ ├── SelectionPanel/\n│ │ │ ├── CreateFactorModal/\n│ │ │ ├── PasteScreen/\n│ │ │ ├── ManualEntry/\n│ │ │ ├── Slider/\n│ │ │ └── ...\n│ │ └── lib/utils.ts # Utility functions (cn)\n│ ├── package.json\n│ └── tsconfig.json\n│\n├── apps/\n│ ├── pwa/ # @variscout/pwa\n│ │ ├── public/ # Static assets, PWA icons\n│ │ ├── src/\n│ │ │ ├── components/ # UI Components\n│ │ │ │ ├── Dashboard.tsx\n│ │ │ │ ├── MobileDashboard.tsx\n│ │ │ │ ├── MobileStatsPanel.tsx\n│ │ │ │ ├── MobileMenu.tsx\n│ │ │ │ ├── views/ # Extracted view components\n│ │ │ │ └── charts/ # Chart wrappers (use @variscout/charts)\n│ │ │ ├── context/ # DataContext\n│ │ │ ├── lib/ # PWA utilities (persistence)\n│ │ │ ├── hooks/ # Custom hooks\n│ │ │ ├── App.tsx\n│ │ │ └── main.tsx\n│ │ ├── index.html\n│ │ ├── vite.config.ts\n│ │ ├── package.json\n│ │ └── dist/ # PWA build output (gitignored)\n│ │\n│ └── azure/ # @variscout/azure-app\n│ ├── src/\n│ │ ├── components/ # UI components (Editor, FilterBreadcrumb, etc.)\n│ │ ├── context/ # DataContext (mirrors PWA)\n│ │ ├── services/ # Offline-first storage + OneDrive sync\n│ │ ├── auth/ # EasyAuth configuration\n│ │ └── lib/ # Utilities\n│ ├── vite.config.ts\n│ └── package.json\n│\n├── docs/ # Documentation\n│ ├── 01-vision/ # Product philosophy, Four Lenses, Two Voices\n│ ├── 02-journeys/ # User research, personas, flows\n│ ├── 03-features/ # Feature documentation\n│ ├── 04-cases/ # Case studies with demo data\n│ ├── 05-technical/ # Technical architecture and implementation\n│ ├── 06-design-system/ # Design tokens, components, charts\n│ ├── 07-decisions/ # Architecture Decision Records\n│ └── 08-products/ # Product specs (Azure, Excel, PWA, Website)\n├── pnpm-workspace.yaml\n├── tsconfig.base.json\n└── package.json # Root scripts\n```\n\n## 7. PWA & Offline Capability\n\nThe app uses `vite-plugin-pwa` to generate a Service Worker that:\n\n- **Precaches** all static assets (JS, CSS, HTML, icons)\n- **Enables offline use** after the first visit\n- **Auto-updates** when new versions are deployed\n\nThe PWA runs as a browser-only tool (no installation). See [ADR-012](../07-decisions/adr-012-pwa-browser-only.md).\n\n## 8. Responsive Architecture\n\nThe app supports screens from 320px to desktop with a comprehensive responsive system:\n\n### Mobile Components\n\n| Component | File | Purpose |\n| ------------------ | ---------------------------------------------- | ------------------------------------------------------- |\n| `MobileDashboard` | `apps/pwa/src/components/MobileDashboard.tsx` | Tab-based chart view with swipe navigation |\n| `MobileStatsPanel` | `apps/pwa/src/components/MobileStatsPanel.tsx` | Full-screen stats with Summary/Histogram/Prob Plot tabs |\n| `MobileMenu` | `apps/pwa/src/components/MobileMenu.tsx` | Dropdown menu for overflow toolbar actions |\n\n### Responsive Hooks\n\n| Hook | Package / Location | Purpose |\n| --------------------------- | ------------------ | ---------------------------------------------- |\n| `useResponsiveChartMargins` | `@variscout/hooks` | Dynamic chart margins based on container width |\n| `useResponsiveChartFonts` | `@variscout/hooks` | Scaled font sizes for chart labels |\n| `useResponsiveTickCount` | `@variscout/hooks` | Optimal tick count for axis length |\n| `useMediaQuery` | `@variscout/ui` | Generic media query hook |\n| `useIsMobile` | `@variscout/ui` | Mobile breakpoint detection (\u003C 640px) |\n\n### Layout Detection\n\nComponents use `window.innerWidth` with resize listeners to conditionally render:\n\n- `Dashboard.tsx`: Renders `MobileDashboard` below 640px\n- `SpecEditor.tsx`: Renders as bottom sheet below 640px\n- `AppHeader.tsx`: Shows mobile menu button below 640px\n\n## 9. Theme System\n\nVariScout supports light/dark theming for paid tiers via a coordinated system:\n\n### Theme Detection\n\nTheme is controlled via the `data-theme` attribute on `\u003Chtml>`:\n\n- `data-theme=\"dark\"` - Dark mode (default for free tier)\n- `data-theme=\"light\"` - Light mode (paid tiers: Individual/Team/Enterprise)\n\n### Chart Theme Hook\n\nCharts use `useChartTheme` from `@variscout/charts` to get theme-aware colors:\n\n```typescript\nimport { useChartTheme } from '@variscout/charts';\n\nconst MyChart = () => {\n const { isDark, chrome, fontScale } = useChartTheme();\n\n // chrome.gridLine, chrome.axisPrimary, etc. adjust automatically\n};\n```\n\n### Color Architecture\n\n| Layer | Location | Purpose |\n| ------------- | --------------------------------------- | ------------------------- |\n| Theme Context | `apps/pwa/src/context/ThemeContext.tsx` | User preference storage |\n| Tier Gate | `packages/core/src/tier.ts` | `isPaidTier()` check |\n| Chart Colors | `packages/charts/src/colors.ts` | `getChromeColors(isDark)` |\n| Theme Hook | `packages/charts/src/useChartTheme.ts` | Reactive theme state |\n\n### Chrome Colors\n\nUI chrome (axes, labels, grid lines) uses theme-aware colors via `getChromeColors()`:\n\n| Property | Dark | Light |\n| -------------- | --------- | --------- |\n| `gridLine` | `#1e293b` | `#f1f5f9` |\n| `axisPrimary` | `#94a3b8` | `#64748b` |\n| `labelPrimary` | `#cbd5e1` | `#334155` |\n\nData colors (`chartColors.pass`, `chartColors.fail`, etc.) remain constant across themes.\n\n## 10. Building & Deployment\n\nAll apps build as static sites. See [Deployment Guide](implementation/deployment.md) for build commands, environment variables, publication processes, and per-platform deployment targets.\n\n## 11. Variation Tracking Architecture\n\nVariScout implements **cumulative variation tracking** to help users identify the most impactful factors during drill-down analysis. This feature is shared across all platforms.\n\n### Core Concept\n\nWhen drilling down through factors, variation percentages (η² / eta-squared) are **multiplied** to show the cumulative impact. For example:\n\n- Root: 100% of variation\n- Drill to \"Night Shift\" (65% η²): 65% of total variation explained\n- Drill to \"Machine C\" (71% η²): 65% × 71% = 46% cumulative\n\n### Shared Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│ @variscout/core │\n│ ┌──────────────────────────────────────────────────────────────────────┐ │\n│ │ variation/ │ │\n│ │ ├─ calculateDrillVariation() → cumulative η² through drill path │ │\n│ │ ├─ calculateFactorVariations() → η² for each factor (suggestions) │ │\n│ │ ├─ shouldHighlightDrill() → threshold check (≥50%) │ │\n│ │ └─ applyFilters() → utility for filtering data │ │\n│ └──────────────────────────────────────────────────────────────────────┘ │\n│ ┌──────────────────────────────────────────────────────────────────────┐ │\n│ │ navigation.ts │ │\n│ │ ├─ VARIATION_THRESHOLDS → 50% high, 30% moderate │ │\n│ │ ├─ getVariationImpactLevel() → 'high' | 'moderate' | 'low' │ │\n│ │ └─ getVariationInsight() → plain-language insight text │ │\n│ └──────────────────────────────────────────────────────────────────────┘ │\n└──────────────────────────────────────────────────────────────────────────────┘\n │\n ┌───────────────────────────┼───────────────────────────┐\n ▼ ▼ ▼\n┌───────────────────────────┐ ┌───────────────────────────┐\n│ PWA │ │ Azure App │\n│ │ │ │\n│ useVariationTracking │ │ useVariationTracking │\n│ ↓ │ │ ↓ │\n│ FilterBreadcrumb │ │ FilterBreadcrumb │\n│ (cumulative %) │ │ (cumulative %) │\n└───────────────────────────┘ └───────────────────────────┘\n```\n\n### Platform-Specific Implementation\n\n| Platform | Feature | Implementation |\n| --------- | --------------------------------- | ------------------------------------------------ |\n| **PWA** | Full breadcrumb with cumulative % | `useVariationTracking` hook → `FilterBreadcrumb` |\n| **PWA** | Filter suggestions on boxplot | `factorVariations` → `Boxplot.tsx` |\n| **Azure** | Full breadcrumb with cumulative % | `useVariationTracking` hook → `FilterBreadcrumb` |\n\n### Visual Indicators\n\n| Variation | Color | Meaning |\n| --------- | ------ | ------------------------------------- |\n| ≥50% | Red | High impact - \"drill here\" suggestion |\n| 30-50% | Yellow | Moderate impact - worth investigating |\n| \u003C30% | Gray | Low impact - consider other factors |\n\n### Boxplot Integration\n\nThe `@variscout/charts` `BoxplotBase` component accepts optional `variationPct` prop:\n\n- Displays factor name + percentage on x-axis label\n- Shows \"↓ drill here\" indicator when `variationPct ≥ variationThreshold`\n- Red highlighting for high-impact factors\n\n## 12. Teams SDK Integration (Azure App)\n\nThe Azure app detects whether it's running inside Microsoft Teams and adapts behavior:\n\n```\napp.initialize() → app.getContext()\n├── Success → Teams mode (isTeams: true)\n│ ├── channelTab → show channel name in header\n│ ├── personalTab → personal tab UX\n│ └── SSO token via authentication.getAuthToken()\n└── Failure → Browser mode (existing EasyAuth flow)\n```\n\n### Context Detection\n\n**Key module**: `apps/azure/src/teams/teamsContext.ts`\n\n| Concept | Implementation |\n| ------------------- | ---------------------------------------------------------------- |\n| Context detection | `initTeams()` — called on app startup, caches result |\n| React hook | `useTeamsContext()` — provides context + loading state |\n| SSO token | `getTeamsSsoToken()` — client-side token (not Graph-ready) |\n| Tab configuration | `TeamsTabConfig.tsx` — shown when adding channel tab |\n| Manifest generation | `AdminTeamsSetup.tsx` — generates `.zip` with `configurableTabs` |\n\n**Plan gating**: `VITE_VARISCOUT_PLAN` env var (`'standard'` or `'team'`) controls feature availability. The Teams SDK initializes regardless of plan (the app works as a tab in either), but Team-plan-only features (channel storage, photos) check `isTeamPlan()` from `@variscout/core/tier`.\n\n**CSP**: `frame-ancestors` updated in `server.js` to allow Teams iframe embedding (`teams.microsoft.com`, `*.teams.microsoft.com`, `*.skype.com`).\n\n### OBO Token Exchange\n\n`apps/azure/src/auth/graphToken.ts` implements a token exchange chain for Graph API access:\n\n```\nTeams SSO token → Azure Function OBO exchange → Graph API token\n ↓ (if fails)\n EasyAuth redirect fallback\n```\n\nThe Azure Function (`infra/functions/token-exchange/index.js`) is a single-purpose token exchange with no stored state. Scopes: `User.Read` + `Files.ReadWrite.All`.\n\n### Channel Drive Resolution\n\n`apps/azure/src/teams/channelDrive.ts` resolves the SharePoint document library for a channel:\n\n- Graph API call: `GET /teams/{teamId}/channels/{channelId}/filesFolder`\n- Returns drive ID + root folder path\n- Result cached in IndexedDB to avoid repeated Graph calls\n- `StorageLocation` type (`'personal' | 'team'`) routes to correct storage\n\n### Photo Pipeline\n\nClient-side photo processing chain:\n\n| Module | Purpose |\n| --------------------- | ------------------------------------------------- |\n| `photoProcessing.ts` | Camera capture and image preprocessing |\n| `exifStrip.ts` | Byte-level EXIF/GPS metadata stripping (23 tests) |\n| `photoUpload.ts` | Upload to OneDrive or SharePoint via Graph API |\n| `usePhotoComments.ts` | React hook for photo attachment state in findings |\n\nPhotos are immutable once uploaded (no edit/delete). Thumbnails (~50KB base64) embedded in `.vrs` files for cross-user visibility.\n\n### Deep Links and Sharing\n\n| Module | Purpose |\n| ------------------ | ------------------------------------------------------- |\n| `deepLinks.ts` | Build and parse deep link URLs for charts/findings |\n| `useTeamsShare.ts` | Wraps `sharing.shareWebContent` + `pages.shareDeepLink` |\n| `shareContent.ts` | Finding/chart payload builders for share dialog |\n\n### User Identity\n\n`getCurrentUser.ts` extracts user identity from the Teams JWT (UPN claim) with EasyAuth fallback. Enables author tracking on findings and comments.\n\nSee [ADR-016](../07-decisions/adr-016-teams-integration.md) for the full Teams integration design.\n\n## 13. Performance Budget\n\n| Metric | Budget |\n| ------------------- | --------------- |\n| Initial bundle | \u003C 200KB gzipped |\n| Total app size | \u003C 700KB |\n| LCP | \u003C 2.5s |\n| FID | \u003C 100ms |\n| CLS | \u003C 0.1 |\n| Time to Interactive | \u003C 3s |\n\n## 14. Browser Support\n\n| Browser | Minimum Version |\n| ------- | --------------- |\n| Chrome | 90+ |\n| Firefox | 90+ |\n| Safari | 14+ |\n| Edge | 90+ |\n\n### Required APIs\n\n- IndexedDB (analysis storage)\n- Service Workers (offline capability)\n- ES2020+", + "src/content/docs/05-technical/architecture.md", + "53b51a3b2e46c40d", + { "html": 1467, "metadata": 1468 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"variscout-architecture-overview\">VariScout: Architecture Overview\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-architecture-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout: Architecture Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout Lite is designed as a \u003Cstrong>browser-first\u003C/strong>, \u003Cstrong>offline-capable\u003C/strong> Progressive Web App (PWA) for manufacturing variation analysis. It prioritizes data privacy (no cloud) and works on any device.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"1-repository-structure\">1. Repository Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#1-repository-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Repository Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout Lite uses a \u003Cstrong>pnpm workspaces monorepo\u003C/strong> to support multiple applications from shared code:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">variscout-lite/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── packages/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── core/ # @variscout/core - Pure logic (stats, parser, tier, glossary)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── charts/ # @variscout/charts - Props-based Visx chart components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── data/ # @variscout/data - Sample datasets with pre-computed chart data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── hooks/ # @variscout/hooks - Shared React hooks (filter navigation, scale, tracking)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── ui/ # @variscout/ui - Shared UI components, colors, and hooks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── apps/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── pwa/ # PWA website (React + Vite + PWA)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── azure/ # Azure Team App (EasyAuth + OneDrive sync)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── website/ # Marketing website (Astro + React Islands)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── docs/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 01-vision/ # Product philosophy, Four Lenses, Two Voices\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 02-journeys/ # User research, personas, flows\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 03-features/ # Feature documentation (analysis, workflows, data, navigation)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 04-cases/ # Case studies with demo data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 05-technical/ # Technical architecture and implementation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 06-design-system/ # Design tokens, components, charts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 07-decisions/ # Architecture Decision Records\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── 08-products/ # Product specs (Azure, PWA, Website)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── pnpm-workspace.yaml # Workspace configuration\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── tsconfig.base.json # Shared TypeScript config\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── package.json # Root scripts\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"variscout-lite/├── packages/│ ├── core/ # @variscout/core - Pure logic (stats, parser, tier, glossary)│ ├── charts/ # @variscout/charts - Props-based Visx chart components│ ├── data/ # @variscout/data - Sample datasets with pre-computed chart data│ ├── hooks/ # @variscout/hooks - Shared React hooks (filter navigation, scale, tracking)│ └── ui/ # @variscout/ui - Shared UI components, colors, and hooks├── apps/│ ├── pwa/ # PWA website (React + Vite + PWA)│ ├── azure/ # Azure Team App (EasyAuth + OneDrive sync)│ └── website/ # Marketing website (Astro + React Islands)├── docs/│ ├── 01-vision/ # Product philosophy, Four Lenses, Two Voices│ ├── 02-journeys/ # User research, personas, flows│ ├── 03-features/ # Feature documentation (analysis, workflows, data, navigation)│ ├── 04-cases/ # Case studies with demo data│ ├── 05-technical/ # Technical architecture and implementation│ ├── 06-design-system/ # Design tokens, components, charts│ ├── 07-decisions/ # Architecture Decision Records│ └── 08-products/ # Product specs (Azure, PWA, Website)├── pnpm-workspace.yaml # Workspace configuration├── tsconfig.base.json # Shared TypeScript config└── package.json # Root scripts\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Detailed monorepo documentation:\u003C/strong> \u003Ca href=\"architecture/monorepo.md\">Monorepo Architecture\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"2-high-level-stack\">2. High-Level Stack\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#2-high-level-stack\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. High-Level Stack”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Runtime\u003C/strong>: Progressive Web App (PWA) with Service Worker\u003C/li>\n\u003Cli>\u003Cstrong>Frontend\u003C/strong>: \u003Ca href=\"https://react.dev/\">React\u003C/a> + \u003Ca href=\"https://www.typescriptlang.org/\">TypeScript\u003C/a> + \u003Ca href=\"https://vitejs.dev/\">Vite\u003C/a>\u003C/li>\n\u003Cli>\u003Cstrong>Styling\u003C/strong>: \u003Ca href=\"https://tailwindcss.com/\">Tailwind CSS\u003C/a> (Utility-first)\u003C/li>\n\u003Cli>\u003Cstrong>Visualization\u003C/strong>: \u003Ca href=\"https://airbnb.io/visx/\">Visx\u003C/a> (Low-level D3 primitives for React) via \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Shared Logic\u003C/strong>: \u003Ccode dir=\"auto\">@variscout/core\u003C/code> package (stats, parser, tier, glossary)\u003C/li>\n\u003Cli>\u003Cstrong>Persistence\u003C/strong>: IndexedDB + OneDrive sync (Azure App), session-only (PWA)\u003C/li>\n\u003Cli>\u003Cstrong>PWA\u003C/strong>: \u003Ca href=\"https://vite-pwa-org.netlify.app/\">vite-plugin-pwa\u003C/a> with Workbox\u003C/li>\n\u003Cli>\u003Cstrong>Marketing Website\u003C/strong>: \u003Ca href=\"https://astro.build/\">Astro 5\u003C/a> with React Islands (chart demos)\u003C/li>\n\u003Cli>\u003Cstrong>Package Manager\u003C/strong>: \u003Ca href=\"https://pnpm.io/\">pnpm\u003C/a> with workspaces\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"3-package-architecture\">3. Package Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#3-package-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Package Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ APPS │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ @variscout/pwa │ @variscout/azure-app │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (apps/pwa/) │ (apps/azure/) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌──────────┐ ┌──────┐ ┌────────┐ │ ┌──────────┐ ┌────────┐ ┌─────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │Components│ │Context│ │Session │ │ │Components│ │EasyAuth│ │Sync(IDB)│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │(Mobile) │ │(Data) │ │ only │ │ │(Editor) │ │(SSO) │ │+OneDrive│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └────┬─────┘ └───┬───┘ └───┬────┘ │ └────┬─────┘ └───┬────┘ └────┬────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────────┼─────────┘ │ └───────────┼───────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───────────────────┼─────────────────┴────────────────────┼───────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ PACKAGES │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────┬───────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ @variscout/charts │ @variscout/core │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (packages/charts/) │ (packages/core/) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ IChart │ Boxplot │ ParetoChart │ stats/ │ parser/ │ tier.ts │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CapabilityHistogram │ responsive │ glossary │ export.ts │ types.ts │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────┼───────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ @variscout/hooks │ @variscout/data │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (packages/hooks/) │ (packages/data/) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ useChartScale │ useFilterNavigation│ coffee │ journey │ bottleneck │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ useVariationTracking │ useTier │ sachets │ pre-computed chart data │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────┼───────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ @variscout/ui │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (packages/ui/) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ AnovaResults │ FilterBreadcrumb │ FilterChipDropdown │ RegressionPanel │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ PerformanceSetupPanel │ VariationBar │ YAxisPopover │ TierBadge │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ UpgradePrompt │ ChartCard │ ColumnMapping │ HelpTooltip │ colors │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────────────────┐│ APPS │├─────────────────────────────────────────────────────────────────────────────┤│ @variscout/pwa │ @variscout/azure-app ││ (apps/pwa/) │ (apps/azure/) ││ ┌──────────┐ ┌──────┐ ┌────────┐ │ ┌──────────┐ ┌────────┐ ┌─────────┐ ││ │Components│ │Context│ │Session │ │ │Components│ │EasyAuth│ │Sync(IDB)│ ││ │(Mobile) │ │(Data) │ │ only │ │ │(Editor) │ │(SSO) │ │+OneDrive│ ││ └────┬─────┘ └───┬───┘ └───┬────┘ │ └────┬─────┘ └───┬────┘ └────┬────┘ ││ └───────────┼─────────┘ │ └───────────┼───────────┘ ││ │ │ │ │└───────────────────┼─────────────────┴────────────────────┼───────────────────┘ │ │ ▼ ▼┌─────────────────────────────────────────────────────────────────────────────┐│ PACKAGES │├─────────────────────────────────────┬───────────────────────────────────────┤│ @variscout/charts │ @variscout/core ││ (packages/charts/) │ (packages/core/) ││ │ ││ IChart │ Boxplot │ ParetoChart │ stats/ │ parser/ │ tier.ts ││ CapabilityHistogram │ responsive │ glossary │ export.ts │ types.ts │├─────────────────────────────────────┼───────────────────────────────────────┤│ @variscout/hooks │ @variscout/data ││ (packages/hooks/) │ (packages/data/) ││ │ ││ useChartScale │ useFilterNavigation│ coffee │ journey │ bottleneck ││ useVariationTracking │ useTier │ sachets │ pre-computed chart data │├─────────────────────────────────────┼───────────────────────────────────────┤│ @variscout/ui ││ (packages/ui/) ││ AnovaResults │ FilterBreadcrumb │ FilterChipDropdown │ RegressionPanel ││ PerformanceSetupPanel │ VariationBar │ YAxisPopover │ TierBadge ││ UpgradePrompt │ ChartCard │ ColumnMapping │ HelpTooltip │ colors │└─────────────────────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutcore\">@variscout/core\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutcore\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/core”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pure TypeScript logic with no React dependencies:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Module\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stats/\u003C/code>\u003C/td>\u003Ctd>Mean, StdDev, UCL/LCL, Cp, Cpk, conformance, factor grouping, staged stats\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">parser/\u003C/code>\u003C/td>\u003Ctd>CSV/Excel file parsing, validation, keyword detection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">tier.ts\u003C/code>\u003C/td>\u003Ctd>Tier configuration (Azure Marketplace licensing, channel limits)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">navigation.ts\u003C/code>\u003C/td>\u003Ctd>Navigation types and utilities (FilterAction, BreadcrumbItem)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">variation/\u003C/code>\u003C/td>\u003Ctd>Cumulative variation tracking (η² cascading, drill suggestions)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">glossary/\u003C/code>\u003C/td>\u003Ctd>Glossary terms and type definitions for help tooltips\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">export.ts\u003C/code>\u003C/td>\u003Ctd>CSV export utilities\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">types.ts\u003C/code>\u003C/td>\u003Ctd>Shared TypeScript interfaces (StatsResult, LicenseTier, etc.)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutcharts\">@variscout/charts\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutcharts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Props-based React components using Visx for data visualization:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Module\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">IChart.tsx\u003C/code>\u003C/td>\u003Ctd>Individual control chart with \u003Ccode dir=\"auto\">IChartBase\u003C/code> export\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Boxplot.tsx\u003C/code>\u003C/td>\u003Ctd>Factor comparison with \u003Ccode dir=\"auto\">BoxplotBase\u003C/code> export (\u003Ccode dir=\"auto\">showViolin\u003C/code> prop)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ParetoChart.tsx\u003C/code>\u003C/td>\u003Ctd>Frequency analysis with \u003Ccode dir=\"auto\">ParetoChartBase\u003C/code> export\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">CapabilityHistogram.tsx\u003C/code>\u003C/td>\u003Ctd>Distribution histogram with spec limits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ProbabilityPlot.tsx\u003C/code>\u003C/td>\u003Ctd>Normal probability plot with CI bands\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChartSourceBar.tsx\u003C/code>\u003C/td>\u003Ctd>Branding footer component\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">responsive.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getResponsiveMargins\u003C/code>, \u003Ccode dir=\"auto\">getResponsiveFonts\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">types.ts\u003C/code>\u003C/td>\u003Ctd>Chart prop interfaces, \u003Ccode dir=\"auto\">calculateBoxplotStats()\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutdata\">@variscout/data\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutdata\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pre-computed sample datasets for the marketing website’s React Islands. Provides ready-to-render chart data without runtime computation.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Module\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">samples/*.ts\u003C/code>\u003C/td>\u003Ctd>Individual sample datasets (coffee, journey, bottleneck)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">types.ts\u003C/code>\u003C/td>\u003Ctd>SampleDataset interface definition\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">index.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getSample()\u003C/code> helper and sample registry\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Each sample exports:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">rawData\u003C/code> - Original records\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">stats\u003C/code> - Pre-calculated StatsResult\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">specs\u003C/code> - USL/LSL/Target\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">ichartData\u003C/code> - Pre-formatted IChartPoint[]\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">boxplotData\u003C/code> - Pre-calculated BoxplotGroup[]\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">paretoData\u003C/code> - Pre-aggregated ParetoItem[]\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Usage:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { getSample } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/data\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sample\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getSample\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">coffee\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Use sample.ichartData, sample.boxplotData, etc.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { getSample } from '@variscout/data';const sample = getSample('coffee');// Use sample.ichartData, sample.boxplotData, etc.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutui\">@variscout/ui\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutui\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/ui”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shared UI component library for PWA and Azure apps.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Stack\u003C/strong>: React + Tailwind CSS + Radix UI + Lucide React.\u003C/li>\n\u003Cli>\u003Cstrong>Goal\u003C/strong>: Ensure consistent design system implementation across web properties.\u003C/li>\n\u003Cli>\u003Cstrong>Components\u003C/strong>: \u003Ccode dir=\"auto\">AnovaResults\u003C/code>, \u003Ccode dir=\"auto\">FilterBreadcrumb\u003C/code>, \u003Ccode dir=\"auto\">FilterChipDropdown\u003C/code>, \u003Ccode dir=\"auto\">PerformanceSetupPanelBase\u003C/code>, \u003Ccode dir=\"auto\">RegressionPanelBase\u003C/code>, \u003Ccode dir=\"auto\">VariationBar\u003C/code>, \u003Ccode dir=\"auto\">YAxisPopover\u003C/code>, \u003Ccode dir=\"auto\">ChartCard\u003C/code>, \u003Ccode dir=\"auto\">ColumnMapping\u003C/code>, \u003Ccode dir=\"auto\">MeasureColumnSelector\u003C/code>, \u003Ccode dir=\"auto\">PerformanceDetectedModal\u003C/code>, \u003Ccode dir=\"auto\">DataQualityBanner\u003C/code>, \u003Ccode dir=\"auto\">HelpTooltip\u003C/code>, \u003Ccode dir=\"auto\">SelectionPanel\u003C/code>, \u003Ccode dir=\"auto\">CreateFactorModal\u003C/code>, \u003Ccode dir=\"auto\">TierBadge\u003C/code>, \u003Ccode dir=\"auto\">UpgradePrompt\u003C/code>.\u003C/li>\n\u003Cli>\u003Cstrong>Hooks\u003C/strong>: \u003Ccode dir=\"auto\">useIsMobile\u003C/code>, \u003Ccode dir=\"auto\">useGlossary\u003C/code>.\u003C/li>\n\u003Cli>\u003Cstrong>Services\u003C/strong>: \u003Ccode dir=\"auto\">errorService\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscouthooks\">@variscout/hooks\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscouthooks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/hooks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shared React hooks for cross-platform functionality:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Hook\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useChartScale\u003C/code>\u003C/td>\u003Ctd>Calculate Y-axis range from data, specs, and axis settings\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useFilterNavigation\u003C/code>\u003C/td>\u003Ctd>Filter navigation with multi-select and filter chip support\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code>\u003C/td>\u003Ctd>Cumulative η² tracking + filter chip data with contribution %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useKeyboardNavigation\u003C/code>\u003C/td>\u003Ctd>Arrow key navigation and focus management\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useResponsiveChartMargins\u003C/code>\u003C/td>\u003Ctd>Dynamic chart margins based on container width\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useDataState\u003C/code>\u003C/td>\u003Ctd>Shared DataContext state management\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useDataIngestion\u003C/code>\u003C/td>\u003Ctd>File upload and data parsing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useTier\u003C/code>\u003C/td>\u003Ctd>License tier state and limits (Azure Marketplace)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useAvailableOutcomes\u003C/code>\u003C/td>\u003Ctd>Available outcome columns for analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useAvailableStageColumns\u003C/code>\u003C/td>\u003Ctd>Available stage columns for staged analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useChartNavigation\u003C/code>\u003C/td>\u003Ctd>Chart tab navigation and ordering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useClipboardCopy\u003C/code>\u003C/td>\u003Ctd>Clipboard copy with feedback\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useColumnClassification\u003C/code>\u003C/td>\u003Ctd>Column type classification for regression\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useRegressionState\u003C/code>\u003C/td>\u003Ctd>Regression analysis mode and state management\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key types:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FilterChipData\u003C/code>\u003C/td>\u003Ctd>Filter chip data with contribution % and available values\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">UseFilterNavigationReturn\u003C/code>\u003C/td>\u003Ctd>Return type including \u003Ccode dir=\"auto\">updateFilterValues()\u003C/code>, \u003Ccode dir=\"auto\">removeFilter()\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">VariationTrackingResult\u003C/code>\u003C/td>\u003Ctd>Return type including \u003Ccode dir=\"auto\">filterChipData\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">UseTierResult\u003C/code>\u003C/td>\u003Ctd>Tier info, validation functions, warning messages\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Usage:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useFilterNavigation,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useVariationTracking,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useChartScale,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useTier,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FilterChipData,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/hooks\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useFilterNavigation, useVariationTracking, useChartScale, useTier, type FilterChipData,} from '@variscout/hooks';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"internationalization-i18n\">Internationalization (i18n)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#internationalization-i18n\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Internationalization (i18n)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Implemented using \u003Ccode dir=\"auto\">i18next\u003C/code> and \u003Ccode dir=\"auto\">react-i18next\u003C/code>.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Strategy\u003C/strong>: Per-app configuration (isolated/bundled JSON files).\u003C/li>\n\u003Cli>\u003Cstrong>Languages\u003C/strong>: English (\u003Ccode dir=\"auto\">en\u003C/code>), Finnish (\u003Ccode dir=\"auto\">fi\u003C/code>).\u003C/li>\n\u003Cli>\u003Cstrong>Detection\u003C/strong>: Browser language detection with fallback to English.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutpwa\">@variscout/pwa\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutpwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/pwa”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>React application with PWA capabilities:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Module\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">context/DataContext.tsx\u003C/code>\u003C/td>\u003Ctd>Centralized state management\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">components/Dashboard.tsx\u003C/code>\u003C/td>\u003Ctd>Main 3-chart layout\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">components/FilterBreadcrumb.tsx\u003C/code>\u003C/td>\u003Ctd>Breadcrumb navigation component\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">components/Mobile*.tsx\u003C/code>\u003C/td>\u003Ctd>Mobile-optimized components\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">hooks/useFilterNavigation.ts\u003C/code>\u003C/td>\u003Ctd>Filter navigation hook\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">lib/persistence.ts\u003C/code>\u003C/td>\u003Ctd>IndexedDB + localStorage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">hooks/useResponsive*.ts\u003C/code>\u003C/td>\u003Ctd>Responsive sizing hooks\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutazure-app\">@variscout/azure-app\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutazure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/azure-app”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Cloud-connected team application:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Module\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/auth/easyAuth.ts\u003C/code>\u003C/td>\u003Ctd>App Service EasyAuth helper (SSO)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/services/storage.ts\u003C/code>\u003C/td>\u003Ctd>Offline-first storage + OneDrive sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/context/DataContext\u003C/code>\u003C/td>\u003Ctd>Central state management (mirrors PWA)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/components/Editor\u003C/code>\u003C/td>\u003Ctd>Main editor with data panel + charts\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutwebsite\">@variscout/website\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutwebsite\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/website”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Marketing and education website (Astro 5 + React 19 Islands):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Module\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/data/toolsData.ts\u003C/code>\u003C/td>\u003Ctd>7 tool page definitions (slug, lens, content)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/data/learnData.ts\u003C/code>\u003C/td>\u003Ctd>11 learn topic definitions with visual sections\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/data/glossaryData.ts\u003C/code>\u003C/td>\u003Ctd>~26 glossary terms extending @variscout/core\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/i18n/ui.ts\u003C/code>\u003C/td>\u003Ctd>Translation strings for 5 languages (en/de/es/fr/pt)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/i18n/utils.ts\u003C/code>\u003C/td>\u003Ctd>getLangFromUrl(), useTranslations()\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/components/islands/\u003C/code>\u003C/td>\u003Ctd>9 React islands (chart demos, hydrated on scroll)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">src/layouts/BaseLayout.astro\u003C/code>\u003C/td>\u003Ctd>SEO meta, OG tags, Schema.org structured data\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Static HTML generated by Astro; React only loads for interactive chart demos via \u003Ccode dir=\"auto\">client:visible\u003C/code> hydration. Content managed through TypeScript data files (no CMS). Generates 379 pages across 5 languages.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-core-modules\">4. Core Modules\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-core-modules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Core Modules”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"41-data-context-appspwasrccontextdatacontexttsx\">4.1 Data Context (\u003Ccode dir=\"auto\">apps/pwa/src/context/DataContext.tsx\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#41-data-context-appspwasrccontextdatacontexttsx\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4.1 Data Context (apps/pwa/src/context/DataContext.tsx)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The application uses a centralized React Context to manage the entire analysis state.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>State (\u003Ccode dir=\"auto\">filteredData\u003C/code>)\u003C/strong>: Derived from \u003Ccode dir=\"auto\">rawData\u003C/code> based on active global filters.\u003C/li>\n\u003Cli>\u003Cstrong>Performance\u003C/strong>: Uses \u003Ccode dir=\"auto\">useMemo\u003C/code> extensively to prevent re-calculating statistics on every render.\u003C/li>\n\u003Cli>\u003Cstrong>Persistence\u003C/strong>: Azure App exposes methods for IndexedDB save/load. PWA is session-only.\u003C/li>\n\u003Cli>\u003Cstrong>Flow\u003C/strong>: Import → \u003Ccode dir=\"auto\">setRawData\u003C/code> → \u003Ccode dir=\"auto\">detectColumns\u003C/code> → \u003Ccode dir=\"auto\">DataContext\u003C/code> Updates → Charts Render.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"42-statistics-engine-packagescoresrcstatsts\">4.2 Statistics Engine (\u003Ccode dir=\"auto\">packages/core/src/stats.ts\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#42-statistics-engine-packagescoresrcstatsts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4.2 Statistics Engine (packages/core/src/stats.ts)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A tailored math library that computes quality control metrics on the fly.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Metrics\u003C/strong>: Mean, StdDev, UCL/LCL (3-sigma), Cp, Cpk, Out-of-Spec %.\u003C/li>\n\u003Cli>\u003Cstrong>Logic\u003C/strong>: Handles both standard (USL & LSL) and one-sided (USL or LSL only) specifications.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Staged Statistics\u003C/strong> (for staged I-Charts):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Function\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">determineStageOrder()\u003C/code>\u003C/td>\u003Ctd>Auto-detect numeric patterns for stage sorting\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">sortDataByStage()\u003C/code>\u003C/td>\u003Ctd>Stable sort data by stage order\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">calculateStatsByStage()\u003C/code>\u003C/td>\u003Ctd>Calculate per-stage statistics (UCL, Mean, LCL)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">getStageBoundaries()\u003C/code>\u003C/td>\u003Ctd>Get X boundaries for chart rendering\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"43-visualization-layer-appspwasrccomponentscharts\">4.3 Visualization Layer (\u003Ccode dir=\"auto\">apps/pwa/src/components/charts/\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#43-visualization-layer-appspwasrccomponentscharts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4.3 Visualization Layer (apps/pwa/src/components/charts/)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Built with Visx to ensure complete control over rendering behavior and interactions.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: Time-series visualization with dynamic control limit overlays.\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Distribution analysis showing quartiles and outliers.\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong>: Factor frequency analysis.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"44-persistence-layer-appspwasrclibpersistencets\">4.4 Persistence Layer (\u003Ccode dir=\"auto\">apps/pwa/src/lib/persistence.ts\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#44-persistence-layer-appspwasrclibpersistencets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4.4 Persistence Layer (apps/pwa/src/lib/persistence.ts)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Handles all data storage operations in the browser.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Analysis Storage\u003C/strong>: Named analyses saved to IndexedDB via explicit save/load actions.\u003C/li>\n\u003Cli>\u003Cstrong>File Export/Import\u003C/strong>: Download/upload \u003Ccode dir=\"auto\">.vrs\u003C/code> JSON files for portability.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"5-data-persistence\">5. Data Persistence\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#5-data-persistence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Data Persistence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-app\">Azure App\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Named analyses saved to IndexedDB + synced to OneDrive\u003C/li>\n\u003Cli>.vrs file export/import for portability across devices/browsers\u003C/li>\n\u003Cli>List, load, rename, delete operations\u003C/li>\n\u003Cli>App starts on HomeScreen with recent analyses list\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-free\">PWA (Free)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-free\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA (Free)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Session-only — data lives in React state, cleared on refresh\u003C/li>\n\u003Cli>No save, no IndexedDB projects, no .vrs files\u003C/li>\n\u003Cli>Users paste data or load samples each session\u003C/li>\n\u003Cli>CSV/PNG export available during session\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"6-directory-structure\">6. Directory Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#6-directory-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Directory Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">variscout-lite/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── packages/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── core/ # @variscout/core\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── index.ts # Barrel export\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── stats/ # Statistics calculations (13 domain modules)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── parser/ # File parsing (csv, excel, detection, validation)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── variation/ # Variation tracking (drill, contributions, suggestions)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── tier.ts # Tier configuration (Azure Marketplace)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── glossary/ # Glossary terms and types\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── export.ts # CSV export\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ └── types.ts # Shared interfaces\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── package.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── tsconfig.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── charts/ # @variscout/charts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── index.ts # Barrel export\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── IChart.tsx # I-Chart component\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── Boxplot.tsx # Boxplot component\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── ParetoChart.tsx # Pareto chart component\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── CapabilityHistogram.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── ProbabilityPlot.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── ChartSourceBar.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── responsive.ts # Responsive utilities\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ └── types.ts # Chart interfaces\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── package.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── tsconfig.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── hooks/ # @variscout/hooks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── index.ts # Barrel export\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useChartScale.ts # Y-axis scale calculation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useFilterNavigation.ts # Filter navigation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useVariationTracking.ts # Cumulative Total SS tracking\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useKeyboardNavigation.ts # Keyboard navigation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useResponsiveChartMargins.ts # Responsive margins\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useResponsiveChartFonts.ts # Responsive font sizes\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useResponsiveTickCount.ts # Responsive tick counts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useResponsiveBreakpoints.ts # Responsive breakpoints\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useDataState.ts # Shared DataContext state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useDataIngestion.ts # File upload and parsing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useTier.ts # Tier state and limits\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useColumnClassification.ts # Column type classification\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useDrillPath.ts # Drill path state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useMindmapState.ts # Mindmap state management\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useBoxplotData.ts # Shared d3 boxplot computation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useIChartData.ts # Shared I-Chart data transform\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useAnnotations.ts # Chart annotation state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useThemeState.ts # Theme state (light/dark/system)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useControlViolations.ts # Control/spec violation computation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useFocusedChartNav.ts # Keyboard chart focus navigation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useHighlightFade.ts # Highlight fade animation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── useResizablePanel.ts # Resizable panel state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ └── useDataTablePagination.ts # Data table pagination\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── package.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── tsconfig.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── ui/ # @variscout/ui\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── index.ts # Barrel export\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── colors.ts # UI color constants (statusColors)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── hooks/ # useMediaQuery, useGlossary\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── services/ # errorService\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── styles/ # theme.css, components.css\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── components/ # Shared UI components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── AnovaResults/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── FilterBreadcrumb/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── FilterChipDropdown/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── FilterContextBar/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── PerformanceSetupPanel/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── VariationBar/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── YAxisPopover/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── UpgradePrompt/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── ChartCard/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── ColumnMapping/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── HelpTooltip/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── DashboardBase/ # FocusedViewOverlay, FocusedChartCard,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ # DashboardChartCard, DashboardGrid\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── StatsPanelBase/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── MindmapWindow/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── MindmapPanel/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── WhatIfSimulator/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── WhatIfPage/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── ErrorBoundary/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── AxisEditor/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── FactorSelector/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── SpecsPopover/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── SpecEditor/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── CapabilityHistogram/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── ProbabilityPlot/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── BoxplotDisplayToggle/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── ChartAnnotationLayer/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── AnnotationContextMenu/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── DataTable/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── ChartDownloadMenu/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── SelectionPanel/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── CreateFactorModal/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── PasteScreen/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── ManualEntry/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── Slider/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ └── ...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── lib/utils.ts # Utility functions (cn)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── package.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── tsconfig.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── apps/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── pwa/ # @variscout/pwa\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── public/ # Static assets, PWA icons\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── components/ # UI Components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ ├── Dashboard.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ ├── MobileDashboard.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ ├── MobileStatsPanel.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ ├── MobileMenu.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ ├── views/ # Extracted view components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ └── charts/ # Chart wrappers (use @variscout/charts)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── context/ # DataContext\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── lib/ # PWA utilities (persistence)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── hooks/ # Custom hooks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ├── App.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ └── main.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── index.html\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── vite.config.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── package.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── dist/ # PWA build output (gitignored)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── azure/ # @variscout/azure-app\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── components/ # UI components (Editor, FilterBreadcrumb, etc.)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── context/ # DataContext (mirrors PWA)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── services/ # Offline-first storage + OneDrive sync\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── auth/ # EasyAuth configuration\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── lib/ # Utilities\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── vite.config.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── package.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── docs/ # Documentation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 01-vision/ # Product philosophy, Four Lenses, Two Voices\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 02-journeys/ # User research, personas, flows\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 03-features/ # Feature documentation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 04-cases/ # Case studies with demo data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 05-technical/ # Technical architecture and implementation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 06-design-system/ # Design tokens, components, charts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── 07-decisions/ # Architecture Decision Records\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── 08-products/ # Product specs (Azure, Excel, PWA, Website)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── pnpm-workspace.yaml\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── tsconfig.base.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── package.json # Root scripts\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"variscout-lite/├── packages/│ ├── core/ # @variscout/core│ │ ├── src/│ │ │ ├── index.ts # Barrel export│ │ │ ├── stats/ # Statistics calculations (13 domain modules)│ │ │ ├── parser/ # File parsing (csv, excel, detection, validation)│ │ │ ├── variation/ # Variation tracking (drill, contributions, suggestions)│ │ │ ├── tier.ts # Tier configuration (Azure Marketplace)│ │ │ ├── glossary/ # Glossary terms and types│ │ │ ├── export.ts # CSV export│ │ │ └── types.ts # Shared interfaces│ │ ├── package.json│ │ └── tsconfig.json│ ││ ├── charts/ # @variscout/charts│ │ ├── src/│ │ │ ├── index.ts # Barrel export│ │ │ ├── IChart.tsx # I-Chart component│ │ │ ├── Boxplot.tsx # Boxplot component│ │ │ ├── ParetoChart.tsx # Pareto chart component│ │ │ ├── CapabilityHistogram.tsx│ │ │ ├── ProbabilityPlot.tsx│ │ │ ├── ChartSourceBar.tsx│ │ │ ├── responsive.ts # Responsive utilities│ │ │ └── types.ts # Chart interfaces│ │ ├── package.json│ │ └── tsconfig.json│ ││ ├── hooks/ # @variscout/hooks│ │ ├── src/│ │ │ ├── index.ts # Barrel export│ │ │ ├── useChartScale.ts # Y-axis scale calculation│ │ │ ├── useFilterNavigation.ts # Filter navigation│ │ │ ├── useVariationTracking.ts # Cumulative Total SS tracking│ │ │ ├── useKeyboardNavigation.ts # Keyboard navigation│ │ │ ├── useResponsiveChartMargins.ts # Responsive margins│ │ │ ├── useResponsiveChartFonts.ts # Responsive font sizes│ │ │ ├── useResponsiveTickCount.ts # Responsive tick counts│ │ │ ├── useResponsiveBreakpoints.ts # Responsive breakpoints│ │ │ ├── useDataState.ts # Shared DataContext state│ │ │ ├── useDataIngestion.ts # File upload and parsing│ │ │ ├── useTier.ts # Tier state and limits│ │ │ ├── useColumnClassification.ts # Column type classification│ │ │ ├── useDrillPath.ts # Drill path state│ │ │ ├── useMindmapState.ts # Mindmap state management│ │ │ ├── useBoxplotData.ts # Shared d3 boxplot computation│ │ │ ├── useIChartData.ts # Shared I-Chart data transform│ │ │ ├── useAnnotations.ts # Chart annotation state│ │ │ ├── useThemeState.ts # Theme state (light/dark/system)│ │ │ ├── useControlViolations.ts # Control/spec violation computation│ │ │ ├── useFocusedChartNav.ts # Keyboard chart focus navigation│ │ │ ├── useHighlightFade.ts # Highlight fade animation│ │ │ ├── useResizablePanel.ts # Resizable panel state│ │ │ └── useDataTablePagination.ts # Data table pagination│ │ ├── package.json│ │ └── tsconfig.json│ ││ └── ui/ # @variscout/ui│ ├── src/│ │ ├── index.ts # Barrel export│ │ ├── colors.ts # UI color constants (statusColors)│ │ ├── hooks/ # useMediaQuery, useGlossary│ │ ├── services/ # errorService│ │ ├── styles/ # theme.css, components.css│ │ ├── components/ # Shared UI components│ │ │ ├── AnovaResults/│ │ │ ├── FilterBreadcrumb/│ │ │ ├── FilterChipDropdown/│ │ │ ├── FilterContextBar/│ │ │ ├── PerformanceSetupPanel/│ │ │ ├── VariationBar/│ │ │ ├── YAxisPopover/│ │ │ ├── UpgradePrompt/│ │ │ ├── ChartCard/│ │ │ ├── ColumnMapping/│ │ │ ├── HelpTooltip/│ │ │ ├── DashboardBase/ # FocusedViewOverlay, FocusedChartCard,│ │ │ │ # DashboardChartCard, DashboardGrid│ │ │ ├── StatsPanelBase/│ │ │ ├── MindmapWindow/│ │ │ ├── MindmapPanel/│ │ │ ├── WhatIfSimulator/│ │ │ ├── WhatIfPage/│ │ │ ├── ErrorBoundary/│ │ │ ├── AxisEditor/│ │ │ ├── FactorSelector/│ │ │ ├── SpecsPopover/│ │ │ ├── SpecEditor/│ │ │ ├── CapabilityHistogram/│ │ │ ├── ProbabilityPlot/│ │ │ ├── BoxplotDisplayToggle/│ │ │ ├── ChartAnnotationLayer/│ │ │ ├── AnnotationContextMenu/│ │ │ ├── DataTable/│ │ │ ├── ChartDownloadMenu/│ │ │ ├── SelectionPanel/│ │ │ ├── CreateFactorModal/│ │ │ ├── PasteScreen/│ │ │ ├── ManualEntry/│ │ │ ├── Slider/│ │ │ └── ...│ │ └── lib/utils.ts # Utility functions (cn)│ ├── package.json│ └── tsconfig.json│├── apps/│ ├── pwa/ # @variscout/pwa│ │ ├── public/ # Static assets, PWA icons│ │ ├── src/│ │ │ ├── components/ # UI Components│ │ │ │ ├── Dashboard.tsx│ │ │ │ ├── MobileDashboard.tsx│ │ │ │ ├── MobileStatsPanel.tsx│ │ │ │ ├── MobileMenu.tsx│ │ │ │ ├── views/ # Extracted view components│ │ │ │ └── charts/ # Chart wrappers (use @variscout/charts)│ │ │ ├── context/ # DataContext│ │ │ ├── lib/ # PWA utilities (persistence)│ │ │ ├── hooks/ # Custom hooks│ │ │ ├── App.tsx│ │ │ └── main.tsx│ │ ├── index.html│ │ ├── vite.config.ts│ │ ├── package.json│ │ └── dist/ # PWA build output (gitignored)│ ││ └── azure/ # @variscout/azure-app│ ├── src/│ │ ├── components/ # UI components (Editor, FilterBreadcrumb, etc.)│ │ ├── context/ # DataContext (mirrors PWA)│ │ ├── services/ # Offline-first storage + OneDrive sync│ │ ├── auth/ # EasyAuth configuration│ │ └── lib/ # Utilities│ ├── vite.config.ts│ └── package.json│├── docs/ # Documentation│ ├── 01-vision/ # Product philosophy, Four Lenses, Two Voices│ ├── 02-journeys/ # User research, personas, flows│ ├── 03-features/ # Feature documentation│ ├── 04-cases/ # Case studies with demo data│ ├── 05-technical/ # Technical architecture and implementation│ ├── 06-design-system/ # Design tokens, components, charts│ ├── 07-decisions/ # Architecture Decision Records│ └── 08-products/ # Product specs (Azure, Excel, PWA, Website)├── pnpm-workspace.yaml├── tsconfig.base.json└── package.json # Root scripts\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"7-pwa--offline-capability\">7. PWA & Offline Capability\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#7-pwa--offline-capability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “7. PWA & Offline Capability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The app uses \u003Ccode dir=\"auto\">vite-plugin-pwa\u003C/code> to generate a Service Worker that:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Precaches\u003C/strong> all static assets (JS, CSS, HTML, icons)\u003C/li>\n\u003Cli>\u003Cstrong>Enables offline use\u003C/strong> after the first visit\u003C/li>\n\u003Cli>\u003Cstrong>Auto-updates\u003C/strong> when new versions are deployed\u003C/li>\n\u003C/ul>\n\u003Cp>The PWA runs as a browser-only tool (no installation). See \u003Ca href=\"../07-decisions/adr-012-pwa-browser-only.md\">ADR-012\u003C/a>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"8-responsive-architecture\">8. Responsive Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#8-responsive-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “8. Responsive Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The app supports screens from 320px to desktop with a comprehensive responsive system:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mobile-components\">Mobile Components\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Components”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>File\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">MobileDashboard\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/MobileDashboard.tsx\u003C/code>\u003C/td>\u003Ctd>Tab-based chart view with swipe navigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">MobileStatsPanel\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/MobileStatsPanel.tsx\u003C/code>\u003C/td>\u003Ctd>Full-screen stats with Summary/Histogram/Prob Plot tabs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">MobileMenu\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/MobileMenu.tsx\u003C/code>\u003C/td>\u003Ctd>Dropdown menu for overflow toolbar actions\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"responsive-hooks\">Responsive Hooks\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#responsive-hooks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Responsive Hooks”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Hook\u003C/th>\u003Cth>Package / Location\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useResponsiveChartMargins\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003Ctd>Dynamic chart margins based on container width\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useResponsiveChartFonts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003Ctd>Scaled font sizes for chart labels\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useResponsiveTickCount\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003Ctd>Optimal tick count for axis length\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useMediaQuery\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Generic media query hook\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useIsMobile\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Mobile breakpoint detection (< 640px)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layout-detection\">Layout Detection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layout-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layout Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Components use \u003Ccode dir=\"auto\">window.innerWidth\u003C/code> with resize listeners to conditionally render:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">Dashboard.tsx\u003C/code>: Renders \u003Ccode dir=\"auto\">MobileDashboard\u003C/code> below 640px\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">SpecEditor.tsx\u003C/code>: Renders as bottom sheet below 640px\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">AppHeader.tsx\u003C/code>: Shows mobile menu button below 640px\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"9-theme-system\">9. Theme System\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#9-theme-system\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “9. Theme System”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout supports light/dark theming for paid tiers via a coordinated system:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"theme-detection\">Theme Detection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#theme-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theme Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Theme is controlled via the \u003Ccode dir=\"auto\">data-theme\u003C/code> attribute on \u003Ccode dir=\"auto\"><html>\u003C/code>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">data-theme=\"dark\"\u003C/code> - Dark mode (default for free tier)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">data-theme=\"light\"\u003C/code> - Light mode (paid tiers: Individual/Team/Enterprise)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"chart-theme-hook\">Chart Theme Hook\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#chart-theme-hook\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Theme Hook”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Charts use \u003Ccode dir=\"auto\">useChartTheme\u003C/code> from \u003Ccode dir=\"auto\">@variscout/charts\u003C/code> to get theme-aware colors:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useChartTheme } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">MyChart\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isDark\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fontScale\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chrome.gridLine, chrome.axisPrimary, etc. adjust automatically\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useChartTheme } from '@variscout/charts';const MyChart = () => { const { isDark, chrome, fontScale } = useChartTheme(); // chrome.gridLine, chrome.axisPrimary, etc. adjust automatically};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"color-architecture\">Color Architecture\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#color-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color Architecture”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Layer\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Theme Context\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/context/ThemeContext.tsx\u003C/code>\u003C/td>\u003Ctd>User preference storage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tier Gate\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/tier.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">isPaidTier()\u003C/code> check\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Chart Colors\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/charts/src/colors.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getChromeColors(isDark)\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Theme Hook\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/charts/src/useChartTheme.ts\u003C/code>\u003C/td>\u003Ctd>Reactive theme state\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"chrome-colors\">Chrome Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#chrome-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chrome Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>UI chrome (axes, labels, grid lines) uses theme-aware colors via \u003Ccode dir=\"auto\">getChromeColors()\u003C/code>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Dark\u003C/th>\u003Cth>Light\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">gridLine\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#1e293b\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f1f5f9\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">axisPrimary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">labelPrimary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#cbd5e1\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#334155\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Data colors (\u003Ccode dir=\"auto\">chartColors.pass\u003C/code>, \u003Ccode dir=\"auto\">chartColors.fail\u003C/code>, etc.) remain constant across themes.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"10-building--deployment\">10. Building & Deployment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#10-building--deployment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “10. Building & Deployment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All apps build as static sites. See \u003Ca href=\"implementation/deployment.md\">Deployment Guide\u003C/a> for build commands, environment variables, publication processes, and per-platform deployment targets.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"11-variation-tracking-architecture\">11. Variation Tracking Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#11-variation-tracking-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “11. Variation Tracking Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout implements \u003Cstrong>cumulative variation tracking\u003C/strong> to help users identify the most impactful factors during drill-down analysis. This feature is shared across all platforms.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-concept\">Core Concept\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When drilling down through factors, variation percentages (η² / eta-squared) are \u003Cstrong>multiplied\u003C/strong> to show the cumulative impact. For example:\u003C/p>\n\u003Cul>\n\u003Cli>Root: 100% of variation\u003C/li>\n\u003Cli>Drill to “Night Shift” (65% η²): 65% of total variation explained\u003C/li>\n\u003Cli>Drill to “Machine C” (71% η²): 65% × 71% = 46% cumulative\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"shared-architecture\">Shared Architecture\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#shared-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Shared Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ @variscout/core │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌──────────────────────────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ variation/ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├─ calculateDrillVariation() → cumulative η² through drill path │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├─ calculateFactorVariations() → η² for each factor (suggestions) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├─ shouldHighlightDrill() → threshold check (≥50%) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └─ applyFilters() → utility for filtering data │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └──────────────────────────────────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌──────────────────────────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ navigation.ts │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├─ VARIATION_THRESHOLDS → 50% high, 30% moderate │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├─ getVariationImpactLevel() → 'high' | 'moderate' | 'low' │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └─ getVariationInsight() → plain-language insight text │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └──────────────────────────────────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────────────────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌───────────────────────────┼───────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌───────────────────────────┐ ┌───────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ PWA │ │ Azure App │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ useVariationTracking │ │ useVariationTracking │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ↓ │ │ ↓ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ FilterBreadcrumb │ │ FilterBreadcrumb │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (cumulative %) │ │ (cumulative %) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───────────────────────────┘ └───────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────────────────┐│ @variscout/core ││ ┌──────────────────────────────────────────────────────────────────────┐ ││ │ variation/ │ ││ │ ├─ calculateDrillVariation() → cumulative η² through drill path │ ││ │ ├─ calculateFactorVariations() → η² for each factor (suggestions) │ ││ │ ├─ shouldHighlightDrill() → threshold check (≥50%) │ ││ │ └─ applyFilters() → utility for filtering data │ ││ └──────────────────────────────────────────────────────────────────────┘ ││ ┌──────────────────────────────────────────────────────────────────────┐ ││ │ navigation.ts │ ││ │ ├─ VARIATION_THRESHOLDS → 50% high, 30% moderate │ ││ │ ├─ getVariationImpactLevel() → 'high' | 'moderate' | 'low' │ ││ │ └─ getVariationInsight() → plain-language insight text │ ││ └──────────────────────────────────────────────────────────────────────┘ │└──────────────────────────────────────────────────────────────────────────────┘ │ ┌───────────────────────────┼───────────────────────────┐ ▼ ▼ ▼┌───────────────────────────┐ ┌───────────────────────────┐│ PWA │ │ Azure App ││ │ │ ││ useVariationTracking │ │ useVariationTracking ││ ↓ │ │ ↓ ││ FilterBreadcrumb │ │ FilterBreadcrumb ││ (cumulative %) │ │ (cumulative %) │└───────────────────────────┘ └───────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"platform-specific-implementation\">Platform-Specific Implementation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#platform-specific-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform-Specific Implementation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Feature\u003C/th>\u003Cth>Implementation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>PWA\u003C/strong>\u003C/td>\u003Ctd>Full breadcrumb with cumulative %\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code> hook → \u003Ccode dir=\"auto\">FilterBreadcrumb\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>PWA\u003C/strong>\u003C/td>\u003Ctd>Filter suggestions on boxplot\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">factorVariations\u003C/code> → \u003Ccode dir=\"auto\">Boxplot.tsx\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Azure\u003C/strong>\u003C/td>\u003Ctd>Full breadcrumb with cumulative %\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code> hook → \u003Ccode dir=\"auto\">FilterBreadcrumb\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"visual-indicators\">Visual Indicators\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#visual-indicators\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Indicators”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variation\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>≥50%\u003C/td>\u003Ctd>Red\u003C/td>\u003Ctd>High impact - “drill here” suggestion\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>30-50%\u003C/td>\u003Ctd>Yellow\u003C/td>\u003Ctd>Moderate impact - worth investigating\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd><30%\u003C/td>\u003Ctd>Gray\u003C/td>\u003Ctd>Low impact - consider other factors\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"boxplot-integration\">Boxplot Integration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#boxplot-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Boxplot Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">@variscout/charts\u003C/code> \u003Ccode dir=\"auto\">BoxplotBase\u003C/code> component accepts optional \u003Ccode dir=\"auto\">variationPct\u003C/code> prop:\u003C/p>\n\u003Cul>\n\u003Cli>Displays factor name + percentage on x-axis label\u003C/li>\n\u003Cli>Shows ”↓ drill here” indicator when \u003Ccode dir=\"auto\">variationPct ≥ variationThreshold\u003C/code>\u003C/li>\n\u003Cli>Red highlighting for high-impact factors\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"12-teams-sdk-integration-azure-app\">12. Teams SDK Integration (Azure App)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#12-teams-sdk-integration-azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “12. Teams SDK Integration (Azure App)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure app detects whether it’s running inside Microsoft Teams and adapts behavior:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">app.initialize() → app.getContext()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Success → Teams mode (isTeams: true)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── channelTab → show channel name in header\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── personalTab → personal tab UX\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── SSO token via authentication.getAuthToken()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Failure → Browser mode (existing EasyAuth flow)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"app.initialize() → app.getContext()├── Success → Teams mode (isTeams: true)│ ├── channelTab → show channel name in header│ ├── personalTab → personal tab UX│ └── SSO token via authentication.getAuthToken()└── Failure → Browser mode (existing EasyAuth flow)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"context-detection\">Context Detection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#context-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Key module\u003C/strong>: \u003Ccode dir=\"auto\">apps/azure/src/teams/teamsContext.ts\u003C/code>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Concept\u003C/th>\u003Cth>Implementation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Context detection\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">initTeams()\u003C/code> — called on app startup, caches result\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>React hook\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useTeamsContext()\u003C/code> — provides context + loading state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SSO token\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getTeamsSsoToken()\u003C/code> — client-side token (not Graph-ready)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tab configuration\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">TeamsTabConfig.tsx\u003C/code> — shown when adding channel tab\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Manifest generation\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">AdminTeamsSetup.tsx\u003C/code> — generates \u003Ccode dir=\"auto\">.zip\u003C/code> with \u003Ccode dir=\"auto\">configurableTabs\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Plan gating\u003C/strong>: \u003Ccode dir=\"auto\">VITE_VARISCOUT_PLAN\u003C/code> env var (\u003Ccode dir=\"auto\">'standard'\u003C/code> or \u003Ccode dir=\"auto\">'team'\u003C/code>) controls feature availability. The Teams SDK initializes regardless of plan (the app works as a tab in either), but Team-plan-only features (channel storage, photos) check \u003Ccode dir=\"auto\">isTeamPlan()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core/tier\u003C/code>.\u003C/p>\n\u003Cp>\u003Cstrong>CSP\u003C/strong>: \u003Ccode dir=\"auto\">frame-ancestors\u003C/code> updated in \u003Ccode dir=\"auto\">server.js\u003C/code> to allow Teams iframe embedding (\u003Ccode dir=\"auto\">teams.microsoft.com\u003C/code>, \u003Ccode dir=\"auto\">*.teams.microsoft.com\u003C/code>, \u003Ccode dir=\"auto\">*.skype.com\u003C/code>).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"obo-token-exchange\">OBO Token Exchange\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#obo-token-exchange\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “OBO Token Exchange”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">apps/azure/src/auth/graphToken.ts\u003C/code> implements a token exchange chain for Graph API access:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Teams SSO token → Azure Function OBO exchange → Graph API token\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓ (if fails)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">EasyAuth redirect fallback\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Teams SSO token → Azure Function OBO exchange → Graph API token ↓ (if fails) EasyAuth redirect fallback\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The Azure Function (\u003Ccode dir=\"auto\">infra/functions/token-exchange/index.js\u003C/code>) is a single-purpose token exchange with no stored state. Scopes: \u003Ccode dir=\"auto\">User.Read\u003C/code> + \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"channel-drive-resolution\">Channel Drive Resolution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#channel-drive-resolution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Channel Drive Resolution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">apps/azure/src/teams/channelDrive.ts\u003C/code> resolves the SharePoint document library for a channel:\u003C/p>\n\u003Cul>\n\u003Cli>Graph API call: \u003Ccode dir=\"auto\">GET /teams/{teamId}/channels/{channelId}/filesFolder\u003C/code>\u003C/li>\n\u003Cli>Returns drive ID + root folder path\u003C/li>\n\u003Cli>Result cached in IndexedDB to avoid repeated Graph calls\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">StorageLocation\u003C/code> type (\u003Ccode dir=\"auto\">'personal' | 'team'\u003C/code>) routes to correct storage\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"photo-pipeline\">Photo Pipeline\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#photo-pipeline\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Photo Pipeline”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Client-side photo processing chain:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Module\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">photoProcessing.ts\u003C/code>\u003C/td>\u003Ctd>Camera capture and image preprocessing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">exifStrip.ts\u003C/code>\u003C/td>\u003Ctd>Byte-level EXIF/GPS metadata stripping (23 tests)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">photoUpload.ts\u003C/code>\u003C/td>\u003Ctd>Upload to OneDrive or SharePoint via Graph API\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">usePhotoComments.ts\u003C/code>\u003C/td>\u003Ctd>React hook for photo attachment state in findings\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Photos are immutable once uploaded (no edit/delete). Thumbnails (~50KB base64) embedded in \u003Ccode dir=\"auto\">.vrs\u003C/code> files for cross-user visibility.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deep-links-and-sharing\">Deep Links and Sharing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deep-links-and-sharing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deep Links and Sharing”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Module\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">deepLinks.ts\u003C/code>\u003C/td>\u003Ctd>Build and parse deep link URLs for charts/findings\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useTeamsShare.ts\u003C/code>\u003C/td>\u003Ctd>Wraps \u003Ccode dir=\"auto\">sharing.shareWebContent\u003C/code> + \u003Ccode dir=\"auto\">pages.shareDeepLink\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">shareContent.ts\u003C/code>\u003C/td>\u003Ctd>Finding/chart payload builders for share dialog\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-identity\">User Identity\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-identity\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Identity”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">getCurrentUser.ts\u003C/code> extracts user identity from the Teams JWT (UPN claim) with EasyAuth fallback. Enables author tracking on findings and comments.\u003C/p>\n\u003Cp>See \u003Ca href=\"../07-decisions/adr-016-teams-integration.md\">ADR-016\u003C/a> for the full Teams integration design.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"13-performance-budget\">13. Performance Budget\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#13-performance-budget\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “13. Performance Budget”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Budget\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Initial bundle\u003C/td>\u003Ctd>< 200KB gzipped\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Total app size\u003C/td>\u003Ctd>< 700KB\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LCP\u003C/td>\u003Ctd>< 2.5s\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>FID\u003C/td>\u003Ctd>< 100ms\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CLS\u003C/td>\u003Ctd>< 0.1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Time to Interactive\u003C/td>\u003Ctd>< 3s\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"14-browser-support\">14. Browser Support\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#14-browser-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “14. Browser Support”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Browser\u003C/th>\u003Cth>Minimum Version\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Chrome\u003C/td>\u003Ctd>90+\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Firefox\u003C/td>\u003Ctd>90+\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Safari\u003C/td>\u003Ctd>14+\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Edge\u003C/td>\u003Ctd>90+\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"required-apis\">Required APIs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#required-apis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Required APIs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>IndexedDB (analysis storage)\u003C/li>\n\u003Cli>Service Workers (offline capability)\u003C/li>\n\u003Cli>ES2020+\u003C/li>\n\u003C/ul>", + { + "headings": 1469, + "localImagePaths": 1606, + "remoteImagePaths": 1607, + "frontmatter": 1608, + "imagePaths": 1609 + }, + [ + 1470, 1472, 1475, 1478, 1481, 1482, 1483, 1484, 1485, 1486, 1489, 1492, 1495, 1498, 1501, 1504, + 1507, 1510, 1513, 1516, 1519, 1522, 1525, 1528, 1531, 1534, 1537, 1540, 1543, 1546, 1549, 1552, + 1555, 1558, 1561, 1564, 1567, 1570, 1573, 1576, 1579, 1582, 1585, 1588, 1591, 1594, 1597, 1600, + 1603 + ], + { "depth": 30, "slug": 1471, "text": 1459 }, + "variscout-architecture-overview", + { "depth": 33, "slug": 1473, "text": 1474 }, + "1-repository-structure", + "1. Repository Structure", + { "depth": 33, "slug": 1476, "text": 1477 }, + "2-high-level-stack", + "2. High-Level Stack", + { "depth": 33, "slug": 1479, "text": 1480 }, + "3-package-architecture", + "3. Package Architecture", + { "depth": 79, "slug": 254, "text": 255 }, + { "depth": 79, "slug": 257, "text": 258 }, + { "depth": 79, "slug": 269, "text": 270 }, + { "depth": 79, "slug": 263, "text": 264 }, + { "depth": 79, "slug": 260, "text": 261 }, + { "depth": 79, "slug": 1487, "text": 1488 }, + "internationalization-i18n", + "Internationalization (i18n)", + { "depth": 79, "slug": 1490, "text": 1491 }, + "variscoutpwa", + "@variscout/pwa", + { "depth": 79, "slug": 1493, "text": 1494 }, + "variscoutazure-app", + "@variscout/azure-app", + { "depth": 79, "slug": 1496, "text": 1497 }, + "variscoutwebsite", + "@variscout/website", + { "depth": 33, "slug": 1499, "text": 1500 }, + "4-core-modules", + "4. Core Modules", + { "depth": 79, "slug": 1502, "text": 1503 }, + "41-data-context-appspwasrccontextdatacontexttsx", + "4.1 Data Context (apps/pwa/src/context/DataContext.tsx)", + { "depth": 79, "slug": 1505, "text": 1506 }, + "42-statistics-engine-packagescoresrcstatsts", + "4.2 Statistics Engine (packages/core/src/stats.ts)", + { "depth": 79, "slug": 1508, "text": 1509 }, + "43-visualization-layer-appspwasrccomponentscharts", + "4.3 Visualization Layer (apps/pwa/src/components/charts/)", + { "depth": 79, "slug": 1511, "text": 1512 }, + "44-persistence-layer-appspwasrclibpersistencets", + "4.4 Persistence Layer (apps/pwa/src/lib/persistence.ts)", + { "depth": 33, "slug": 1514, "text": 1515 }, + "5-data-persistence", + "5. Data Persistence", + { "depth": 79, "slug": 1517, "text": 1518 }, + "azure-app", + "Azure App", + { "depth": 79, "slug": 1520, "text": 1521 }, + "pwa-free", + "PWA (Free)", + { "depth": 33, "slug": 1523, "text": 1524 }, + "6-directory-structure", + "6. Directory Structure", + { "depth": 33, "slug": 1526, "text": 1527 }, + "7-pwa--offline-capability", + "7. PWA & Offline Capability", + { "depth": 33, "slug": 1529, "text": 1530 }, + "8-responsive-architecture", + "8. Responsive Architecture", + { "depth": 79, "slug": 1532, "text": 1533 }, + "mobile-components", + "Mobile Components", + { "depth": 79, "slug": 1535, "text": 1536 }, + "responsive-hooks", + "Responsive Hooks", + { "depth": 79, "slug": 1538, "text": 1539 }, + "layout-detection", + "Layout Detection", + { "depth": 33, "slug": 1541, "text": 1542 }, + "9-theme-system", + "9. Theme System", + { "depth": 79, "slug": 1544, "text": 1545 }, + "theme-detection", + "Theme Detection", + { "depth": 79, "slug": 1547, "text": 1548 }, + "chart-theme-hook", + "Chart Theme Hook", + { "depth": 79, "slug": 1550, "text": 1551 }, + "color-architecture", + "Color Architecture", + { "depth": 79, "slug": 1553, "text": 1554 }, + "chrome-colors", + "Chrome Colors", + { "depth": 33, "slug": 1556, "text": 1557 }, + "10-building--deployment", + "10. Building & Deployment", + { "depth": 33, "slug": 1559, "text": 1560 }, + "11-variation-tracking-architecture", + "11. Variation Tracking Architecture", + { "depth": 79, "slug": 1562, "text": 1563 }, + "core-concept", + "Core Concept", + { "depth": 79, "slug": 1565, "text": 1566 }, + "shared-architecture", + "Shared Architecture", + { "depth": 79, "slug": 1568, "text": 1569 }, + "platform-specific-implementation", + "Platform-Specific Implementation", + { "depth": 79, "slug": 1571, "text": 1572 }, + "visual-indicators", + "Visual Indicators", + { "depth": 79, "slug": 1574, "text": 1575 }, + "boxplot-integration", + "Boxplot Integration", + { "depth": 33, "slug": 1577, "text": 1578 }, + "12-teams-sdk-integration-azure-app", + "12. Teams SDK Integration (Azure App)", + { "depth": 79, "slug": 1580, "text": 1581 }, + "context-detection", + "Context Detection", + { "depth": 79, "slug": 1583, "text": 1584 }, + "obo-token-exchange", + "OBO Token Exchange", + { "depth": 79, "slug": 1586, "text": 1587 }, + "channel-drive-resolution", + "Channel Drive Resolution", + { "depth": 79, "slug": 1589, "text": 1590 }, + "photo-pipeline", + "Photo Pipeline", + { "depth": 79, "slug": 1592, "text": 1593 }, + "deep-links-and-sharing", + "Deep Links and Sharing", + { "depth": 79, "slug": 1595, "text": 1596 }, + "user-identity", + "User Identity", + { "depth": 33, "slug": 1598, "text": 1599 }, + "13-performance-budget", + "13. Performance Budget", + { "depth": 33, "slug": 1601, "text": 1602 }, + "14-browser-support", + "14. Browser Support", + { "depth": 79, "slug": 1604, "text": 1605 }, + "required-apis", + "Required APIs", + [], + [], + { "title": 1459 }, + [], + "05-technical/statistics-reference", + { "id": 1610, "data": 1612, "body": 1617, "filePath": 1618, "digest": 1619, "rendered": 1620 }, + { + "title": 1613, + "editUrl": 16, + "head": 1614, + "template": 18, + "sidebar": 1615, + "pagefind": 16, + "draft": 20 + }, + "Statistics & Mindmap Technical Reference", + [], + { "hidden": 20, "attrs": 1616 }, + {}, + "# Statistics & Mindmap Technical Reference\n\nExact formulas, algorithm choices, and implementation notes for the VariScout statistical engine and the Investigation Mindmap.\n\n---\n\n## Audience & Conventions\n\n**For**: developers extending the codebase, statisticians validating methods, auditors checking conformance.\n\n**Source references**: each section cites the implementation file as `package/path/file.ts`. Function signatures use TypeScript notation.\n\n**Formula notation**: LaTeX-style inline (`σ`, `Σ`, `η²`). Greek letters are spelled out in code (`sigmaWithin`, `etaSquared`).\n\n**Not covered here**: user-facing chart interactions, UI component APIs, design system colors. See `docs/03-features/analysis/` for user documentation and `docs/06-design-system/charts/` for chart component rules.\n\n---\n\n## Data Model\n\nVariScout operates on **individual measurements** (subgroup size n = 1). Every row is a single observation with:\n\n- One **outcome** column (numeric measurement)\n- Zero or more **factor** columns (categorical grouping variables)\n- Optionally a **stage** column (time period or batch identifier)\n\nData must be in **time/production order** for moving-range calculations to be meaningful. Shuffled data inflates MR-bar and overestimates σ_within.\n\n---\n\n## Part 1 — Core Statistics\n\n> Source: `packages/core/src/stats/basic.ts`\n> User docs: [I-Chart](../03-features/analysis/i-chart.md), [Capability](../03-features/analysis/capability.md)\n\n### Central Tendency\n\n| Statistic | Formula | Implementation |\n| --------- | --------------------------- | ----------------- |\n| Mean | x̄ = (1/n) Σ xᵢ | `d3.mean(data)` |\n| Median | Middle value of sorted data | `d3.median(data)` |\n\nBoth are computed from the full (unfiltered within current scope) dataset.\n\n### Dispersion — Two Sigmas\n\nVariScout maintains **two** standard deviation estimates. The choice of which to use depends on the purpose:\n\n| Sigma | Symbol | Formula | Used for |\n| --------- | ------------- | -------------------------------- | ------------------------------------------------------ |\n| σ_overall | `stdDev` | Sample std dev (n−1 denominator) | ANOVA SS decomposition, general descriptive statistics |\n| σ_within | `sigmaWithin` | MR-bar / d2 | Control limits, Cp, Cpk |\n\n**σ_overall** — computed via `d3.deviation(data)`, the unbiased sample standard deviation:\n\n```\nσ_overall = sqrt( Σ(xᵢ - x̄)² / (n - 1) )\n```\n\n**σ_within** — estimated from the mean moving range (I-MR / Individuals chart method):\n\n```\nMR_i = |x_i - x_{i-1}| for i = 2, ..., n\nMR-bar = (1/(n-1)) Σ MR_i\nσ_within = MR-bar / d2 where d2 = 1.128\n```\n\nThe constant **d2 = 1.128** is the Hartley unbiasing constant for a moving range with span 2. Since VariScout always uses individual measurements (n = 1), the span is always 2 and d2 is fixed.\n\n**Why two sigmas?** σ_within captures short-term, inherent process variation — the variation between consecutive measurements. It excludes between-subgroup shifts. This makes it the correct denominator for Shewhart control limits and capability indices (Wheeler, _Understanding Variation_). σ_overall includes all sources of variation and is used for ANOVA, where both within-group and between-group variation matter.\n\n**Edge case**: when `data.length \u003C 2`, the moving range cannot be computed. The implementation falls back to `d3.deviation(data)` for σ_within and returns `mrBar = 0`.\n\n### Control Limits (I-Chart)\n\n```\nUCL = x̄ + 3 × σ_within\nLCL = x̄ - 3 × σ_within\n```\n\nThese are the natural process limits (Shewhart 3-sigma limits). Points outside these limits signal special-cause variation. The limits use σ_within (not σ_overall) because they measure the expected range of short-term variation.\n\n### Process Capability\n\n> Source: `packages/core/src/stats/basic.ts` — `calculateStats()`\n> User docs: [Capability](../03-features/analysis/capability.md)\n\nCapability indices require user-supplied specification limits (USL, LSL, or both).\n\n**Cp** — process potential (spread vs tolerance width):\n\n```\nCp = (USL - LSL) / (6 × σ_within)\n```\n\nRequires both USL and LSL. Undefined when σ_within = 0 (all values identical).\n\n**Cpk** — process capability (centering + spread):\n\n```\nCpu = (USL - x̄) / (3 × σ_within)\nCpl = (x̄ - LSL) / (3 × σ_within)\nCpk = min(Cpu, Cpl)\n```\n\nCan be computed with only one limit (one-sided). Undefined when σ_within = 0.\n\n**Interpretation**: Cpk ≥ 1.33 is generally considered capable (AIAG standard). A process with Cpk = 1.0 has its mean exactly 3σ from the nearest limit.\n\n**Edge cases**:\n\n- σ_within = 0 → Cp and Cpk are `undefined` (not Infinity)\n- Single limit → Cp is `undefined`, Cpk is one-sided\n- Empty data → zero-filled StatsResult with no capability indices\n\n### Conformance\n\n> Source: `packages/core/src/stats/conformance.ts`\n\n```typescript\ncalculateConformance(values: number[], usl?: number, lsl?: number): ConformanceResult\n```\n\nCounts pass/fail against specification limits. USL failure takes priority — a value above USL is counted as `failUsl` even if LSL also exists. Pass rate is `(pass / total) × 100`.\n\n---\n\n## Part 2 — One-Way ANOVA\n\n> Source: `packages/core/src/stats/anova.ts`\n> User docs: [Variation Decomposition](../03-features/analysis/variation-decomposition.md)\n\n### Full SS Decomposition\n\nFor a factor with _k_ groups, each of size _nᵢ_, total sample size _N = Σ nᵢ_:\n\n```\nSS_total = Σ (x_ij - x̄)² where x̄ is the grand mean\nSS_between = Σ nᵢ × (x̄ᵢ - x̄)² between-group sum of squares\nSS_within = Σ (nᵢ - 1) × s²ᵢ within-group sum of squares\n```\n\nNote: SS_within is computed from per-group sample variances, not as SS_total − SS_between. This avoids floating-point accumulation errors.\n\n### Degrees of Freedom\n\n```\ndf_between = k - 1\ndf_within = N - k\n```\n\n### F-Statistic and p-Value\n\n```\nMS_between = SS_between / df_between\nMS_within = SS_within / df_within\nF = MS_between / MS_within\np = P(F > f | df_between, df_within) via fDistributionPValue()\n```\n\n### Eta-Squared (Effect Size)\n\n```\nη² = SS_between / (SS_between + SS_within)\n```\n\nInterpretation ranges (Cohen's conventions):\n\n- 0.01–0.06: small effect\n- 0.06–0.14: medium effect\n- \\> 0.14: large effect\n\n### Significance\n\nAlpha = 0.05 (hard-coded). `isSignificant = pValue \u003C 0.05`.\n\n### Insight Generation\n\nThe `generateAnovaInsight()` function produces a plain-English summary:\n\n- Not significant → \"No significant difference between groups\"\n- Significant + lower-is-better keywords (time, defect, error, reject, delay, cost, waste) → names the lowest-mean group as \"best\"\n- Significant + higher-is-better → names the highest-mean group as \"best\"\n\n### Guard Clauses\n\nReturns `null` when:\n\n- Fewer than 2 groups\n- Total N \u003C 3\n- df_within = 0 (every group has exactly 1 observation)\n\n---\n\n## Part 3 — Distribution Functions\n\n> Source: `packages/core/src/stats/distributions.ts` (internal, not re-exported from package)\n\nThese are used by ANOVA and probability calculations. They are not exported from `@variscout/core` — they are internal to the stats module.\n\n### Normal PDF\n\n```\nφ(x) = exp(-0.5 × x²) / √(2π)\n```\n\nStandard normal density. Used in probability plot SE calculations.\n\n### Log-Gamma (Lanczos Approximation)\n\n```\nln Γ(x) using g = 7, 9-term Lanczos series\n```\n\nFor x \u003C 0.5, uses the reflection formula: `ln(π / sin(πx)) − ln Γ(1 − x)`.\n\n### Regularized Incomplete Beta\n\n```\nI_x(a, b) = B(x; a, b) / B(a, b)\n```\n\nComputed via Lentz's continued fraction algorithm (max 200 iterations, ε = 1e-10). Near-zero values floored at 1e-30 to prevent division by zero.\n\n### F-Distribution p-Value\n\n```\nP(F > f | df1, df2) = I_x(df2/2, df1/2) where x = df2 / (df2 + df1 × f)\n```\n\nReturns 1 for f ≤ 0, returns 0 for non-finite f.\n\n### t-Distribution p-Value\n\nTwo-tailed: delegates to `fDistributionPValue(t², 1, df)` using the F-t equivalence.\n\n---\n\n## Part 4 — Normal Quantile (Inverse CDF)\n\n> Source: `packages/core/src/stats/probability.ts` — `normalQuantile()`\n\nAcklam's rational approximation — a three-region piecewise function:\n\n| Region | Range | Method |\n| ---------- | --------------------- | ---------------------------------------------- |\n| Lower tail | p \u003C 0.02425 | `q = √(-2 ln p)`, rational 6/4 polynomial in q |\n| Central | 0.02425 ≤ p ≤ 0.97575 | `r = p - 0.5`, rational 6/5 polynomial in r |\n| Upper tail | p > 0.97575 | Symmetric to lower tail via 1−p |\n\nAccuracy: ~1e-9 (sufficient for all SPC applications). Returns −∞ for p ≤ 0, +∞ for p ≥ 1, 0 for p = 0.5.\n\n---\n\n## Part 5 — Probability Plot\n\n> Source: `packages/core/src/stats/probability.ts` — `calculateProbabilityPlotData()`\n> User docs: [Probability Plot](../03-features/analysis/probability-plot.md)\n\n### Median Rank (Benard's Approximation)\n\nFor sorted data points i = 1, ..., n:\n\n```\np_i = (i - 0.3) / (n + 0.4)\n```\n\nThis is the Benard median-rank formula, the default in Minitab. It provides an unbiased estimate of the cumulative probability for each order statistic.\n\n### Z-Score\n\n```\nz_i = Φ⁻¹(p_i) via normalQuantile()\n```\n\n### Standard Error of Percentile\n\n```\nSE_i = (σ × √(p_i × (1 - p_i) / n)) / φ(z_i)\n```\n\nWhere φ is the standard normal PDF. Capped at `σ × 10` to prevent explosion at extreme percentiles where φ(z) approaches zero.\n\n### 95% Confidence Interval\n\n```\nlower_i = x_i - 1.96 × SE_i\nupper_i = x_i + 1.96 × SE_i\n```\n\n### Preprocessing\n\nNon-numeric, NaN, and Infinity values are filtered before computation. Data is sorted ascending.\n\n---\n\n## Part 6 — Nelson Rule 2\n\n> Source: `packages/core/src/stats/nelson.ts`\n> User docs: [Nelson Rules](../03-features/analysis/nelson-rules.md)\n\n### Definition\n\n**9 or more consecutive points on the same side of the center line** — a signal of systematic process shift.\n\n### Algorithm\n\nSingle-pass scan with run tracking:\n\n1. Initialize `runStart = 0`, `runSide = null`\n2. For each point, determine its side: `'above'` if value > mean, `'below'` if value \u003C mean, `null` if exactly equal\n3. If side differs from `runSide` or side is `null`: check completed run (if ≥ 9 points, record), reset run\n4. After loop, check the final run\n5. Points exactly equal to the mean break the current run (conservative interpretation)\n\n### Exports\n\nTwo functions provide different output formats:\n\n| Function | Returns | Use case |\n| --------------------------------- | --------------------------------------- | ------------------------------ |\n| `getNelsonRule2ViolationPoints()` | `Set\u003Cnumber>` of indices | Point-level violation coloring |\n| `getNelsonRule2Sequences()` | `Array\u003C{ startIndex, endIndex, side }>` | Segment highlight rendering |\n\nReturns empty results for arrays with fewer than 9 values.\n\n---\n\n## Part 7 — Boxplot Statistics\n\n> Source: `packages/core/src/stats/boxplot.ts`\n> User docs: [Boxplot](../03-features/analysis/boxplot.md)\n\n### Five-Number Summary\n\nInput values are sorted ascending. Then:\n\n| Statistic | Formula |\n| --------- | ----------------------------------------------- |\n| Median | Exact midpoint (even n) or middle value (odd n) |\n| Q1 | Linear interpolation at index `(n−1) × 0.25` |\n| Q3 | Linear interpolation at index `(n−1) × 0.75` |\n| IQR | Q3 − Q1 |\n\n### Outlier Detection (Tukey)\n\n```\nLower fence = Q1 - 1.5 × IQR\nUpper fence = Q3 + 1.5 × IQR\n```\n\nValues strictly outside the fences are classified as outliers. Whiskers extend to the fence values (not to the most extreme non-outlier).\n\n### Sorting\n\n`sortBoxplotData()` sorts an array of boxplot groups without mutation:\n\n| `sortBy` | Sort key |\n| ------------------ | -------------------------------- |\n| `'name'` (default) | `localeCompare()` — alphabetical |\n| `'mean'` | Numeric mean comparison |\n| `'spread'` | IQR comparison |\n\nDirection: `'asc'` (default) or `'desc'`.\n\n---\n\n## Part 8 — Kernel Density Estimation\n\n> Source: `packages/core/src/stats/kde.ts`\n\n### Bandwidth Selection (Silverman's Rule)\n\n```\nh = 0.9 × min(σ, IQR/1.34) × n^(-1/5)\n```\n\nThe `min(σ, IQR/1.34)` term is a robust spread estimator resistant to outliers. If only one spread measure is available, the other is used alone. Returns empty result if h ≤ 0 or n \u003C 2.\n\n### Gaussian Kernel\n\n```\nK(u) = exp(-0.5 × u²)\n```\n\nUnnormalized in the loop; the sum is divided by `n × h × √(2π)` for proper normalization.\n\n### Evaluation Grid\n\n- Default: 100 points\n- Range: `[min - 3h, max + 3h]` — extends 3 bandwidths beyond data range (matches the R/ggplot2 `cut=3` default)\n- Output format: `{ value: x, count: density }` — compatible with `@visx/stats` ViolinPlot\n\n---\n\n## Part 9 — Staged Analysis\n\n> Source: `packages/core/src/stats/staged.ts`\n> User docs: [Staged Analysis](../03-features/analysis/staged-analysis.md)\n\n### Stage Order Detection\n\n`determineStageOrder(stageValues, mode?)`:\n\n| Mode | Behavior |\n| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `'data-order'` | First-occurrence order (no sorting) |\n| `'auto'` (default) | If all values match numeric patterns (`/^\\d+(\\.\\d+)?$/` or `/^(stage\\|phase\\|batch\\|period\\|run)?\\s*\\d+$/i`), sorts numerically by embedded number. Otherwise, first-occurrence order. |\n\n### Per-Stage Statistics\n\n`calculateStatsByStage()` calls `calculateStats()` independently for each stage, producing separate UCL, LCL, Cp, Cpk per stage. Also computes `overallStats` across all values combined.\n\nReturns `null` for empty data, empty stage order, or if no stage contains any data.\n\n### Stage Boundaries\n\n`getStageBoundaries()` maps sorted chart data points to stage x-axis extents for rendering. Returns `{ name, startX, endX, stats }` per non-empty stage, using `safeMin`/`safeMax` iterative min/max (avoids `Math.min(...spread)` stack overflow on large arrays).\n\n---\n\n## Part 10 — Variation Decomposition\n\n> Source: `packages/core/src/variation/contributions.ts`\n> User docs: [Variation Decomposition](../03-features/analysis/variation-decomposition.md)\n\n### Category Total SS\n\nFor a factor with categories c₁, c₂, ..., cₖ:\n\n```\nTotal SS = Σ (x_ij - x̄)² over all observations\nCategory SS_c = Σ (x_ij - x̄)² over observations in category c\nCategory % = (Category SS_c / Total SS) × 100\n```\n\n**Design decision**: Total SS partitioning (not between-group SS) captures **both** mean shift and within-group spread. A category with high internal variation but mean near the grand mean will still show non-zero impact. This better answers \"Which categories should I focus on?\" from an improvement perspective.\n\nAll category percentages sum to 100% — variation is fully partitioned.\n\nReturns `null` if fewer than 2 rows or zero total variance.\n\n### Category Stats\n\n`getCategoryStats()` returns per-category detail: count, mean, stdDev (population), contributionPct. Sorted by contribution descending (worst performers first). Used by the What-If Simulator.\n\n---\n\n## Part 11 — Drill-Down & Cumulative Scope\n\n> Source: `packages/core/src/variation/drill.ts`, `packages/hooks/src/useDrillPath.ts`\n\n### Cumulative Scope Calculation\n\nThe drill scope is **multiplicative**, not additive. Each drill level reduces the \"window\" to a fraction of the previous level:\n\n```\ncumulativeScope = Π (localScope_i) for i = 1, ..., depth\n```\n\nExample: three levels with 80%, 70%, 60% local scope → cumulative = 0.8 × 0.7 × 0.6 = 33.6%.\n\n### Algorithm (calculateDrillVariation)\n\n1. Start with root entry: `localVariation = 100%, cumulative = 100%`\n2. For each filter in order:\n - Compute `calculateCategoryTotalSS()` on **current filtered data** (not raw data)\n - Sum contributions of selected category values → `selectedPct`\n - `cumulativePct = (cumulativePct × selectedPct) / 100`\n - Filter data down to selected values for next iteration\n - Break if fewer than 2 rows remain\n\n### Drill Path Statistics (useDrillPath hook)\n\nThe `useDrillPath` hook retrospectively computes drill path statistics by iterating the filter stack:\n\n```typescript\ninterface DrillStep {\n factor: string;\n values: (string | number)[];\n scopeFraction: number; // selected categories' Total SS fraction (0–1)\n cumulativeScope: number; // running product of all scopeFractions (0–1)\n meanBefore: number; // mean before this filter applied\n meanAfter: number; // mean after this filter applied\n cpkBefore: number | undefined;\n cpkAfter: number | undefined;\n countBefore: number;\n countAfter: number;\n}\n```\n\nFor each filter action, the hook calls `calculateCategoryTotalSS()` on the progressively filtered data and `calculateStats()` on the outcome values before and after the filter. This provides the before/after delta visible in the narrative timeline.\n\n### Total SS vs Eta-Squared\n\nThe codebase uses two different metrics for variation attribution:\n\n| Metric | Formula | Where used |\n| ------------------- | ------------------------------ | ----------------------------------------------------------------- |\n| Category Total SS % | `SS_category / SS_total × 100` | Drill scope tracking, breadcrumbs, progress bar, category popover |\n| η² (eta-squared) | `SS_between / SS_total` | Mindmap node sizing, node percentage label |\n\nTotal SS partitioning captures within-group spread. Eta-squared captures only between-group mean differences. The distinction is intentional: scope tracking uses Total SS (comprehensive), while node visual prominence uses η² (highlighting factors where category means differ most).\n\n---\n\n## Part 12 — Drill Suggestions\n\n> Source: `packages/core/src/variation/suggestions.ts`\n\n### Constants\n\n```\nDRILL_SWITCH_THRESHOLD = 5 // Minimum % variation for drill suggestions\n```\n\n### Max Category Contribution\n\n`getMaxCategoryContribution(data, factor, outcome)`: returns the highest single-category Total SS contribution for a factor, as a fraction (0–1). This metric matches the numbers visible in the category popover, making the suggestion logic transparent.\n\n### Next Drill Factor\n\n`getNextDrillFactor(factorVariations, currentFactor, minThreshold?)`: after drilling into a factor, finds the remaining factor with highest variation above `minThreshold` (default 5%). Returns factor name or `null`.\n\n### Optimal Factor Selection (Greedy)\n\n`findOptimalFactors(data, factors, outcome, targetPct?, maxFactors?)`:\n\n1. Compute η² for each factor via `getEtaSquared()`\n2. Sort factors by η² descending\n3. Greedy selection: accumulate as `remaining = remaining × (1 - η²_i)`, cumulative = `100 - remaining × 100`\n4. Stop when cumulative ≥ `targetPct` (default 70%) or `maxFactors` (default 3) reached\n\nReturns `OptimalFactorResult[]` with factor, variationPct (η² × 100), bestValue (category with highest weighted mean deviation), and cumulativePct.\n\n---\n\n## Part 13 — What-If Simulation\n\n> Source: `packages/core/src/variation/simulation.ts`\n> User docs: [Investigation to Action](../03-features/workflows/investigation-to-action.md)\n\n### Direct Adjustment\n\n`simulateDirectAdjustment(currentStats, params, specs?)`:\n\n```\nprojectedMean = currentStats.mean + meanShift\nprojectedStdDev = currentStats.stdDev × (1 - variationReduction)\n```\n\nWhere `variationReduction` is a fraction 0–1 (e.g., 0.2 = 20% reduction).\n\nProjected capability:\n\n```\nprojectedCp = (USL - LSL) / (6 × projectedStdDev)\nprojectedCpk = min((USL - projectedMean) / (3 × projectedStdDev),\n (projectedMean - LSL) / (3 × projectedStdDev))\n```\n\n### Yield Calculation\n\nNormal CDF via the error function (Abramowitz & Stegun formula 7.1.26):\n\n```\nerf(x) ≈ 1 - (a₁t + a₂t² + a₃t³ + a₄t⁴ + a₅t⁵) × exp(-x²)\n where t = 1/(1 + 0.3275911 × |x|)\n\nΦ(z) = 0.5 × (1 + erf(z / √2))\n```\n\nConstants: a₁ = 0.254829592, a₂ = −0.284496736, a₃ = 1.421413741, a₄ = −1.453152027, a₅ = 1.061405429.\n\nYield is computed as the probability of falling within specification limits:\n\n```\nyield = Φ((USL - mean) / σ) - Φ((LSL - mean) / σ) (both limits)\nyield = Φ((USL - mean) / σ) (USL only)\nyield = 1 - Φ((LSL - mean) / σ) (LSL only)\n```\n\nClamped to [0, 100]. PPM = `round((100 - yield%) × 10000)`.\n\n**Edge case**: σ = 0 → yield is 100% if mean is within specs, 0% otherwise.\n\n### Category Exclusion\n\n`calculateProjectedStats(data, factor, outcome, excludedCategories, specs?)`:\n\nFilters out rows matching excluded categories, recomputes mean and **population** std dev on remaining data. Computes improvement percentages (stdDev reduction, mean centering improvement, Cpk improvement) when baseline stats are provided.\n\n### Model-Driven Simulation (Deferred)\n\nThe `simulateFromModel()` function and `getFactorBaselines()` exist in the codebase but are not used in Phase 1. They support regression-based what-if analysis (categorical coefficient swaps, continuous factor shifts, interaction terms). Deferred to Phase 2 per ADR-014.\n\n---\n\n## Part 14 — Investigation Mindmap\n\n> Sources: `packages/charts/src/mindmap/`, `packages/hooks/src/useMindmapState.ts`\n> User docs: [Investigation to Action](../03-features/workflows/investigation-to-action.md)\n\n### Architecture\n\nThe Investigation Mindmap is a Visx SVG radial chart with two modes:\n\n| Mode | Layout | Purpose |\n| ------------- | ---------------------- | ------------------------------ |\n| `'drilldown'` | Radial (hub and spoke) | Interactive factor exploration |\n| `'narrative'` | Horizontal timeline | Story of investigation steps |\n\n### Node Data Model\n\n```typescript\ninterface MindmapNode {\n factor: string;\n displayName?: string;\n etaSquared: number; // 0–1; 0 for drilled nodes\n state: 'active' | 'available' | 'exhausted';\n filteredValue?: string; // displayed below label when active\n isSuggested: boolean; // green pulse animation\n categoryData?: CategoryData[];\n}\n```\n\n**State transitions**:\n\n- `'available'` → `'active'`: user drills into the factor (selects a category)\n- `'available'` → `'exhausted'`: insufficient data (\u003C 3 rows in filtered scope) or η² \u003C 0.01\n- `'active'` → stays active (drilled factors persist)\n\n**Suggestion logic** (in `useMindmapState`): the non-drilled factor with the highest η² above 0.05 is marked as `isSuggested`. Only one factor is suggested at a time.\n\n### Node Sizing — Area-Proportional Encoding\n\n> Source: `packages/charts/src/mindmap/helpers.ts` — `getNodeRadius()`\n\nNode **area** (not radius) scales linearly with η². This follows Stevens' Power Law for perceptually accurate magnitude encoding:\n\n```\nclamped = clamp(etaSquared, 0, 1)\nminArea = π × 20² // MIN_NODE_RADIUS = 20px\nmaxArea = π × 40² // MAX_NODE_RADIUS = 40px\narea = minArea + clamped × (maxArea - minArea)\nradius = √(area / π)\n```\n\n### Visual Encoding\n\n| Property | Active (drilled) | Available | Exhausted | Suggested |\n| --------- | ---------------------------- | ---------------- | ----------- | ---------------- |\n| Fill | Blue (#3b82f6) | Slate | Dim slate | — |\n| Stroke | Blue | Slate | Slate | Green (#22c55e) |\n| Animation | — | — | — | Green pulse |\n| Label | Factor name + filtered value | Factor name + η% | Factor name | Factor name + η% |\n\nColors adapt to light/dark theme via `getNodeFill(state, isDark)` and `getNodeStroke(node, isDark)`.\n\n### Radial Layout (Drilldown Mode)\n\n> Source: `packages/charts/src/mindmap/layout.ts` — `computeLayout()`\n\nCenter hub (\"Start\") at the origin. Factor nodes arranged in concentric rings:\n\n| Node count | Rings | Radius |\n| ---------- | ----------- | -------------------------------------------------- |\n| ≤ 7 | Single ring | 65% of available radius |\n| 8+ | Two rings | Outer: 70% (first 6 nodes), Inner: 38% (remaining) |\n\nAngle formula: `angle = -π/2 + (2π × i) / count` — starting at 12 o'clock, evenly spaced.\n\n### Timeline Layout (Narrative Mode)\n\n> Source: `packages/charts/src/mindmap/layout.ts` — `computeTimelineLayout()`\n\nHorizontal left-to-right arrangement:\n\n- Single step: centered at t = 0.5\n- Multiple steps: `t = i / (count - 1)`, linearly interpolated\n- Padding: `min(60, usableWidth / (count + 2))`\n\n### Drill Trail\n\nBlue line segments connecting center → drilled nodes in the order they were drilled. Rendered from the `drillTrail` array (ordered factor names from drill path).\n\n### Category Popover\n\n> Source: `packages/charts/src/mindmap/CategoryPopover.tsx`\n\nClick on an available node → popover showing categories sorted by Total SS contribution %. Full keyboard navigation (ArrowDown/Up, Enter to select, Escape to close). Accessible with `role=\"listbox\"` and `aria-selected`.\n\nPositioning: prefers right side of node, flips left if insufficient space. Prefers top-aligned, flips upward near bottom edge.\n\n### Progress Bar\n\n> Source: `packages/charts/src/mindmap/ProgressFooter.tsx`\n\nHorizontal bar at the bottom of the SVG showing cumulative variation scope:\n\n```\nfill width = (cumulativeVariationPct / 100) × barWidth\ncolor = green (#22c55e) if pct ≥ targetPct, else blue (#3b82f6)\n```\n\nDefault target: 70%. Dashed vertical marker at the target position.\n\n### Conclusion Panel\n\n> Source: `packages/charts/src/mindmap/ConclusionPanel.tsx`\n\nRendered at the end of the narrative timeline. Shows whether the investigation target was reached. If `onNavigateToWhatIf` is provided, renders a \"Model improvements →\" button — the bridge from Investigation Phase to What-If Phase (the 2-phase workflow described in ADR-014).\n\n### State Hook (useMindmapState)\n\n> Source: `packages/hooks/src/useMindmapState.ts`\n\nResponsibilities:\n\n1. Calls `useDrillPath()` for drill statistics\n2. Converts filterStack to flat filters, computes filtered data\n3. Computes `MindmapNode[]` from factors: η² per factor, state classification, suggestion\n4. Manages mode state (`'drilldown'` | `'narrative'`)\n5. Manages annotations (step index → text, session-only)\n6. Maps DrillSteps to NarrativeSteps with merged annotations\n\n---\n\n## Part 15 — Deferred Methods (Phase 2)\n\nPer ADR-014, the following modules exist in `@variscout/core` but are not exported or used in the current product:\n\n| Module | Function | Purpose |\n| -------------------------- | ------------------------------- | ------------------------------------------- |\n| `stats/regression.ts` | `calculateRegression()` | Simple linear regression |\n| `stats/multiRegression.ts` | `calculateMultipleRegression()` | Multiple regression with categorical coding |\n| `stats/interaction.ts` | `getInteractionStrength()` | Factor interaction analysis |\n| `stats/modelReduction.ts` | `suggestTermRemoval()` | Backward elimination |\n| `variation/simulation.ts` | `simulateFromModel()` | Regression-based what-if |\n\nThese will enable model-driven simulation in a future release: regression coefficients → what-if adjustments → projected outcomes.\n\n---\n\n## References & Standards\n\n| Topic | Standard / Source |\n| ------------------------------------ | --------------------------------------------------------------------------- |\n| I-MR chart, σ_within | Wheeler, _Understanding Variation_ (2000); d2 constant from AIAG SPC Manual |\n| Cp, Cpk | AIAG Statistical Process Control Reference Manual, 2nd ed. |\n| d2 = 1.128 | Hartley unbiasing constant for moving range span 2 |\n| ANOVA effect size (η²) | Cohen, _Statistical Power Analysis for the Behavioral Sciences_ (1988) |\n| Boxplot, IQR fences | Tukey, _Exploratory Data Analysis_ (1977) |\n| KDE bandwidth | Silverman, _Density Estimation for Statistics and Data Analysis_ (1986) |\n| Benard median rank | Benard & Bos-Levenbach (1953); Minitab default |\n| Normal quantile | Acklam's rational approximation (~1e-9 accuracy) |\n| Error function | Abramowitz & Stegun, _Handbook of Mathematical Functions_, formula 7.1.26 |\n| Incomplete beta / continued fraction | Lentz's algorithm (max 200 iterations, ε = 1e-10) |\n| Node area encoding | Stevens' Power Law — area ∝ magnitude for perceptual accuracy |\n| Nelson Rule 2 | Nelson, _Journal of Quality Technology_ (1984) — 9-point runs |", + "src/content/docs/05-technical/statistics-reference.md", + "19d2fa1918c86b29", + { "html": 1621, "metadata": 1622 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"statistics--mindmap-technical-reference\">Statistics & Mindmap Technical Reference\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#statistics--mindmap-technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Statistics & Mindmap Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Exact formulas, algorithm choices, and implementation notes for the VariScout statistical engine and the Investigation Mindmap.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"audience--conventions\">Audience & Conventions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#audience--conventions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Audience & Conventions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>For\u003C/strong>: developers extending the codebase, statisticians validating methods, auditors checking conformance.\u003C/p>\n\u003Cp>\u003Cstrong>Source references\u003C/strong>: each section cites the implementation file as \u003Ccode dir=\"auto\">package/path/file.ts\u003C/code>. Function signatures use TypeScript notation.\u003C/p>\n\u003Cp>\u003Cstrong>Formula notation\u003C/strong>: LaTeX-style inline (\u003Ccode dir=\"auto\">σ\u003C/code>, \u003Ccode dir=\"auto\">Σ\u003C/code>, \u003Ccode dir=\"auto\">η²\u003C/code>). Greek letters are spelled out in code (\u003Ccode dir=\"auto\">sigmaWithin\u003C/code>, \u003Ccode dir=\"auto\">etaSquared\u003C/code>).\u003C/p>\n\u003Cp>\u003Cstrong>Not covered here\u003C/strong>: user-facing chart interactions, UI component APIs, design system colors. See \u003Ccode dir=\"auto\">docs/03-features/analysis/\u003C/code> for user documentation and \u003Ccode dir=\"auto\">docs/06-design-system/charts/\u003C/code> for chart component rules.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-model\">Data Model\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Model”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout operates on \u003Cstrong>individual measurements\u003C/strong> (subgroup size n = 1). Every row is a single observation with:\u003C/p>\n\u003Cul>\n\u003Cli>One \u003Cstrong>outcome\u003C/strong> column (numeric measurement)\u003C/li>\n\u003Cli>Zero or more \u003Cstrong>factor\u003C/strong> columns (categorical grouping variables)\u003C/li>\n\u003Cli>Optionally a \u003Cstrong>stage\u003C/strong> column (time period or batch identifier)\u003C/li>\n\u003C/ul>\n\u003Cp>Data must be in \u003Cstrong>time/production order\u003C/strong> for moving-range calculations to be meaningful. Shuffled data inflates MR-bar and overestimates σ_within.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-1--core-statistics\">Part 1 — Core Statistics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-1--core-statistics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 1 — Core Statistics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/basic.ts\u003C/code>\nUser docs: \u003Ca href=\"../03-features/analysis/i-chart.md\">I-Chart\u003C/a>, \u003Ca href=\"../03-features/analysis/capability.md\">Capability\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"central-tendency\">Central Tendency\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#central-tendency\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Central Tendency”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Statistic\u003C/th>\u003Cth>Formula\u003C/th>\u003Cth>Implementation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Mean\u003C/td>\u003Ctd>x̄ = (1/n) Σ xᵢ\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">d3.mean(data)\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Median\u003C/td>\u003Ctd>Middle value of sorted data\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">d3.median(data)\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Both are computed from the full (unfiltered within current scope) dataset.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"dispersion--two-sigmas\">Dispersion — Two Sigmas\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#dispersion--two-sigmas\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dispersion — Two Sigmas”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout maintains \u003Cstrong>two\u003C/strong> standard deviation estimates. The choice of which to use depends on the purpose:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Sigma\u003C/th>\u003Cth>Symbol\u003C/th>\u003Cth>Formula\u003C/th>\u003Cth>Used for\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>σ_overall\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">stdDev\u003C/code>\u003C/td>\u003Ctd>Sample std dev (n−1 denominator)\u003C/td>\u003Ctd>ANOVA SS decomposition, general descriptive statistics\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>σ_within\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">sigmaWithin\u003C/code>\u003C/td>\u003Ctd>MR-bar / d2\u003C/td>\u003Ctd>Control limits, Cp, Cpk\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>σ_overall\u003C/strong> — computed via \u003Ccode dir=\"auto\">d3.deviation(data)\u003C/code>, the unbiased sample standard deviation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">σ_overall = sqrt( Σ(xᵢ - x̄)² / (n - 1) )\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"σ_overall = sqrt( Σ(xᵢ - x̄)² / (n - 1) )\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>σ_within\u003C/strong> — estimated from the mean moving range (I-MR / Individuals chart method):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">MR_i = |x_i - x_{i-1}| for i = 2, ..., n\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">MR-bar = (1/(n-1)) Σ MR_i\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">σ_within = MR-bar / d2 where d2 = 1.128\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"MR_i = |x_i - x_{i-1}| for i = 2, ..., nMR-bar = (1/(n-1)) Σ MR_iσ_within = MR-bar / d2 where d2 = 1.128\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The constant \u003Cstrong>d2 = 1.128\u003C/strong> is the Hartley unbiasing constant for a moving range with span 2. Since VariScout always uses individual measurements (n = 1), the span is always 2 and d2 is fixed.\u003C/p>\n\u003Cp>\u003Cstrong>Why two sigmas?\u003C/strong> σ_within captures short-term, inherent process variation — the variation between consecutive measurements. It excludes between-subgroup shifts. This makes it the correct denominator for Shewhart control limits and capability indices (Wheeler, \u003Cem>Understanding Variation\u003C/em>). σ_overall includes all sources of variation and is used for ANOVA, where both within-group and between-group variation matter.\u003C/p>\n\u003Cp>\u003Cstrong>Edge case\u003C/strong>: when \u003Ccode dir=\"auto\">data.length < 2\u003C/code>, the moving range cannot be computed. The implementation falls back to \u003Ccode dir=\"auto\">d3.deviation(data)\u003C/code> for σ_within and returns \u003Ccode dir=\"auto\">mrBar = 0\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"control-limits-i-chart\">Control Limits (I-Chart)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#control-limits-i-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Control Limits (I-Chart)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">UCL = x̄ + 3 × σ_within\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LCL = x̄ - 3 × σ_within\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"UCL = x̄ + 3 × σ_withinLCL = x̄ - 3 × σ_within\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>These are the natural process limits (Shewhart 3-sigma limits). Points outside these limits signal special-cause variation. The limits use σ_within (not σ_overall) because they measure the expected range of short-term variation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"process-capability\">Process Capability\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#process-capability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Process Capability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/basic.ts\u003C/code> — \u003Ccode dir=\"auto\">calculateStats()\u003C/code>\nUser docs: \u003Ca href=\"../03-features/analysis/capability.md\">Capability\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cp>Capability indices require user-supplied specification limits (USL, LSL, or both).\u003C/p>\n\u003Cp>\u003Cstrong>Cp\u003C/strong> — process potential (spread vs tolerance width):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cp = (USL - LSL) / (6 × σ_within)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Cp = (USL - LSL) / (6 × σ_within)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Requires both USL and LSL. Undefined when σ_within = 0 (all values identical).\u003C/p>\n\u003Cp>\u003Cstrong>Cpk\u003C/strong> — process capability (centering + spread):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cpu = (USL - x̄) / (3 × σ_within)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cpl = (x̄ - LSL) / (3 × σ_within)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cpk = min(Cpu, Cpl)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Cpu = (USL - x̄) / (3 × σ_within)Cpl = (x̄ - LSL) / (3 × σ_within)Cpk = min(Cpu, Cpl)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Can be computed with only one limit (one-sided). Undefined when σ_within = 0.\u003C/p>\n\u003Cp>\u003Cstrong>Interpretation\u003C/strong>: Cpk ≥ 1.33 is generally considered capable (AIAG standard). A process with Cpk = 1.0 has its mean exactly 3σ from the nearest limit.\u003C/p>\n\u003Cp>\u003Cstrong>Edge cases\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>σ_within = 0 → Cp and Cpk are \u003Ccode dir=\"auto\">undefined\u003C/code> (not Infinity)\u003C/li>\n\u003Cli>Single limit → Cp is \u003Ccode dir=\"auto\">undefined\u003C/code>, Cpk is one-sided\u003C/li>\n\u003Cli>Empty data → zero-filled StatsResult with no capability indices\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"conformance\">Conformance\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#conformance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Conformance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/conformance.ts\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateConformance\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(values: number[], usl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> number, lsl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> number): ConformanceResult\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"calculateConformance(values: number[], usl?: number, lsl?: number): ConformanceResult\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Counts pass/fail against specification limits. USL failure takes priority — a value above USL is counted as \u003Ccode dir=\"auto\">failUsl\u003C/code> even if LSL also exists. Pass rate is \u003Ccode dir=\"auto\">(pass / total) × 100\u003C/code>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-2--one-way-anova\">Part 2 — One-Way ANOVA\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-2--one-way-anova\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 2 — One-Way ANOVA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/anova.ts\u003C/code>\nUser docs: \u003Ca href=\"../03-features/analysis/variation-decomposition.md\">Variation Decomposition\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"full-ss-decomposition\">Full SS Decomposition\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#full-ss-decomposition\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Full SS Decomposition”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For a factor with \u003Cem>k\u003C/em> groups, each of size \u003Cem>nᵢ\u003C/em>, total sample size \u003Cem>N = Σ nᵢ\u003C/em>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SS_total = Σ (x_ij - x̄)² where x̄ is the grand mean\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SS_between = Σ nᵢ × (x̄ᵢ - x̄)² between-group sum of squares\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SS_within = Σ (nᵢ - 1) × s²ᵢ within-group sum of squares\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"SS_total = Σ (x_ij - x̄)² where x̄ is the grand meanSS_between = Σ nᵢ × (x̄ᵢ - x̄)² between-group sum of squaresSS_within = Σ (nᵢ - 1) × s²ᵢ within-group sum of squares\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Note: SS_within is computed from per-group sample variances, not as SS_total − SS_between. This avoids floating-point accumulation errors.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"degrees-of-freedom\">Degrees of Freedom\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#degrees-of-freedom\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Degrees of Freedom”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">df_between = k - 1\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">df_within = N - k\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"df_between = k - 1df_within = N - k\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"f-statistic-and-p-value\">F-Statistic and p-Value\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#f-statistic-and-p-value\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “F-Statistic and p-Value”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">MS_between = SS_between / df_between\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">MS_within = SS_within / df_within\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">F = MS_between / MS_within\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">p = P(F > f | df_between, df_within) via fDistributionPValue()\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"MS_between = SS_between / df_betweenMS_within = SS_within / df_withinF = MS_between / MS_withinp = P(F > f | df_between, df_within) via fDistributionPValue()\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"eta-squared-effect-size\">Eta-Squared (Effect Size)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#eta-squared-effect-size\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Eta-Squared (Effect Size)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">η² = SS_between / (SS_between + SS_within)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"η² = SS_between / (SS_between + SS_within)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Interpretation ranges (Cohen’s conventions):\u003C/p>\n\u003Cul>\n\u003Cli>0.01–0.06: small effect\u003C/li>\n\u003Cli>0.06–0.14: medium effect\u003C/li>\n\u003Cli>> 0.14: large effect\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"significance\">Significance\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#significance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Significance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Alpha = 0.05 (hard-coded). \u003Ccode dir=\"auto\">isSignificant = pValue < 0.05\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"insight-generation\">Insight Generation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#insight-generation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Insight Generation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">generateAnovaInsight()\u003C/code> function produces a plain-English summary:\u003C/p>\n\u003Cul>\n\u003Cli>Not significant → “No significant difference between groups”\u003C/li>\n\u003Cli>Significant + lower-is-better keywords (time, defect, error, reject, delay, cost, waste) → names the lowest-mean group as “best”\u003C/li>\n\u003Cli>Significant + higher-is-better → names the highest-mean group as “best”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"guard-clauses\">Guard Clauses\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#guard-clauses\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Guard Clauses”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Returns \u003Ccode dir=\"auto\">null\u003C/code> when:\u003C/p>\n\u003Cul>\n\u003Cli>Fewer than 2 groups\u003C/li>\n\u003Cli>Total N < 3\u003C/li>\n\u003Cli>df_within = 0 (every group has exactly 1 observation)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-3--distribution-functions\">Part 3 — Distribution Functions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-3--distribution-functions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 3 — Distribution Functions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/distributions.ts\u003C/code> (internal, not re-exported from package)\u003C/p>\n\u003C/blockquote>\n\u003Cp>These are used by ANOVA and probability calculations. They are not exported from \u003Ccode dir=\"auto\">@variscout/core\u003C/code> — they are internal to the stats module.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"normal-pdf\">Normal PDF\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#normal-pdf\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Normal PDF”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">φ(x) = exp(-0.5 × x²) / √(2π)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"φ(x) = exp(-0.5 × x²) / √(2π)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Standard normal density. Used in probability plot SE calculations.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"log-gamma-lanczos-approximation\">Log-Gamma (Lanczos Approximation)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#log-gamma-lanczos-approximation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Log-Gamma (Lanczos Approximation)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">ln Γ(x) using g = 7, 9-term Lanczos series\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ln Γ(x) using g = 7, 9-term Lanczos series\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>For x < 0.5, uses the reflection formula: \u003Ccode dir=\"auto\">ln(π / sin(πx)) − ln Γ(1 − x)\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"regularized-incomplete-beta\">Regularized Incomplete Beta\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#regularized-incomplete-beta\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Regularized Incomplete Beta”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">I_x(a, b) = B(x; a, b) / B(a, b)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"I_x(a, b) = B(x; a, b) / B(a, b)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Computed via Lentz’s continued fraction algorithm (max 200 iterations, ε = 1e-10). Near-zero values floored at 1e-30 to prevent division by zero.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"f-distribution-p-value\">F-Distribution p-Value\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#f-distribution-p-value\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “F-Distribution p-Value”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">P(F > f | df1, df2) = I_x(df2/2, df1/2) where x = df2 / (df2 + df1 × f)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"P(F > f | df1, df2) = I_x(df2/2, df1/2) where x = df2 / (df2 + df1 × f)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Returns 1 for f ≤ 0, returns 0 for non-finite f.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"t-distribution-p-value\">t-Distribution p-Value\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#t-distribution-p-value\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “t-Distribution p-Value”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Two-tailed: delegates to \u003Ccode dir=\"auto\">fDistributionPValue(t², 1, df)\u003C/code> using the F-t equivalence.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-4--normal-quantile-inverse-cdf\">Part 4 — Normal Quantile (Inverse CDF)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-4--normal-quantile-inverse-cdf\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 4 — Normal Quantile (Inverse CDF)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/probability.ts\u003C/code> — \u003Ccode dir=\"auto\">normalQuantile()\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cp>Acklam’s rational approximation — a three-region piecewise function:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Region\u003C/th>\u003Cth>Range\u003C/th>\u003Cth>Method\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Lower tail\u003C/td>\u003Ctd>p < 0.02425\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">q = √(-2 ln p)\u003C/code>, rational 6/4 polynomial in q\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Central\u003C/td>\u003Ctd>0.02425 ≤ p ≤ 0.97575\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">r = p - 0.5\u003C/code>, rational 6/5 polynomial in r\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Upper tail\u003C/td>\u003Ctd>p > 0.97575\u003C/td>\u003Ctd>Symmetric to lower tail via 1−p\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Accuracy: ~1e-9 (sufficient for all SPC applications). Returns −∞ for p ≤ 0, +∞ for p ≥ 1, 0 for p = 0.5.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-5--probability-plot\">Part 5 — Probability Plot\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-5--probability-plot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 5 — Probability Plot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/probability.ts\u003C/code> — \u003Ccode dir=\"auto\">calculateProbabilityPlotData()\u003C/code>\nUser docs: \u003Ca href=\"../03-features/analysis/probability-plot.md\">Probability Plot\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"median-rank-benards-approximation\">Median Rank (Benard’s Approximation)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#median-rank-benards-approximation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Median Rank (Benard’s Approximation)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For sorted data points i = 1, …, n:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">p_i = (i - 0.3) / (n + 0.4)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"p_i = (i - 0.3) / (n + 0.4)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This is the Benard median-rank formula, the default in Minitab. It provides an unbiased estimate of the cumulative probability for each order statistic.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"z-score\">Z-Score\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#z-score\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Z-Score”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">z_i = Φ⁻¹(p_i) via normalQuantile()\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"z_i = Φ⁻¹(p_i) via normalQuantile()\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-error-of-percentile\">Standard Error of Percentile\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-error-of-percentile\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Error of Percentile”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SE_i = (σ × √(p_i × (1 - p_i) / n)) / φ(z_i)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"SE_i = (σ × √(p_i × (1 - p_i) / n)) / φ(z_i)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Where φ is the standard normal PDF. Capped at \u003Ccode dir=\"auto\">σ × 10\u003C/code> to prevent explosion at extreme percentiles where φ(z) approaches zero.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"95-confidence-interval\">95% Confidence Interval\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#95-confidence-interval\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “95% Confidence Interval”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">lower_i = x_i - 1.96 × SE_i\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">upper_i = x_i + 1.96 × SE_i\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"lower_i = x_i - 1.96 × SE_iupper_i = x_i + 1.96 × SE_i\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"preprocessing\">Preprocessing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#preprocessing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Preprocessing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Non-numeric, NaN, and Infinity values are filtered before computation. Data is sorted ascending.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-6--nelson-rule-2\">Part 6 — Nelson Rule 2\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-6--nelson-rule-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 6 — Nelson Rule 2”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/nelson.ts\u003C/code>\nUser docs: \u003Ca href=\"../03-features/analysis/nelson-rules.md\">Nelson Rules\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"definition\">Definition\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#definition\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Definition”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>9 or more consecutive points on the same side of the center line\u003C/strong> — a signal of systematic process shift.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"algorithm\">Algorithm\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#algorithm\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Algorithm”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Single-pass scan with run tracking:\u003C/p>\n\u003Col>\n\u003Cli>Initialize \u003Ccode dir=\"auto\">runStart = 0\u003C/code>, \u003Ccode dir=\"auto\">runSide = null\u003C/code>\u003C/li>\n\u003Cli>For each point, determine its side: \u003Ccode dir=\"auto\">'above'\u003C/code> if value > mean, \u003Ccode dir=\"auto\">'below'\u003C/code> if value < mean, \u003Ccode dir=\"auto\">null\u003C/code> if exactly equal\u003C/li>\n\u003Cli>If side differs from \u003Ccode dir=\"auto\">runSide\u003C/code> or side is \u003Ccode dir=\"auto\">null\u003C/code>: check completed run (if ≥ 9 points, record), reset run\u003C/li>\n\u003Cli>After loop, check the final run\u003C/li>\n\u003Cli>Points exactly equal to the mean break the current run (conservative interpretation)\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"exports\">Exports\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#exports\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Two functions provide different output formats:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Function\u003C/th>\u003Cth>Returns\u003C/th>\u003Cth>Use case\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">getNelsonRule2ViolationPoints()\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Set<number>\u003C/code> of indices\u003C/td>\u003Ctd>Point-level violation coloring\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">getNelsonRule2Sequences()\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Array<{ startIndex, endIndex, side }>\u003C/code>\u003C/td>\u003Ctd>Segment highlight rendering\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Returns empty results for arrays with fewer than 9 values.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-7--boxplot-statistics\">Part 7 — Boxplot Statistics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-7--boxplot-statistics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 7 — Boxplot Statistics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/boxplot.ts\u003C/code>\nUser docs: \u003Ca href=\"../03-features/analysis/boxplot.md\">Boxplot\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"five-number-summary\">Five-Number Summary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#five-number-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Five-Number Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Input values are sorted ascending. Then:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Statistic\u003C/th>\u003Cth>Formula\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Median\u003C/td>\u003Ctd>Exact midpoint (even n) or middle value (odd n)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Q1\u003C/td>\u003Ctd>Linear interpolation at index \u003Ccode dir=\"auto\">(n−1) × 0.25\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Q3\u003C/td>\u003Ctd>Linear interpolation at index \u003Ccode dir=\"auto\">(n−1) × 0.75\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>IQR\u003C/td>\u003Ctd>Q3 − Q1\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"outlier-detection-tukey\">Outlier Detection (Tukey)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#outlier-detection-tukey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Outlier Detection (Tukey)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Lower fence = Q1 - 1.5 × IQR\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Upper fence = Q3 + 1.5 × IQR\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Lower fence = Q1 - 1.5 × IQRUpper fence = Q3 + 1.5 × IQR\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Values strictly outside the fences are classified as outliers. Whiskers extend to the fence values (not to the most extreme non-outlier).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"sorting\">Sorting\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#sorting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sorting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">sortBoxplotData()\u003C/code> sorts an array of boxplot groups without mutation:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>\u003Ccode dir=\"auto\">sortBy\u003C/code>\u003C/th>\u003Cth>Sort key\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'name'\u003C/code> (default)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">localeCompare()\u003C/code> — alphabetical\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'mean'\u003C/code>\u003C/td>\u003Ctd>Numeric mean comparison\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'spread'\u003C/code>\u003C/td>\u003Ctd>IQR comparison\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Direction: \u003Ccode dir=\"auto\">'asc'\u003C/code> (default) or \u003Ccode dir=\"auto\">'desc'\u003C/code>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-8--kernel-density-estimation\">Part 8 — Kernel Density Estimation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-8--kernel-density-estimation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 8 — Kernel Density Estimation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/kde.ts\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"bandwidth-selection-silvermans-rule\">Bandwidth Selection (Silverman’s Rule)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#bandwidth-selection-silvermans-rule\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Bandwidth Selection (Silverman’s Rule)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">h = 0.9 × min(σ, IQR/1.34) × n^(-1/5)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"h = 0.9 × min(σ, IQR/1.34) × n^(-1/5)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">min(σ, IQR/1.34)\u003C/code> term is a robust spread estimator resistant to outliers. If only one spread measure is available, the other is used alone. Returns empty result if h ≤ 0 or n < 2.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"gaussian-kernel\">Gaussian Kernel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#gaussian-kernel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Gaussian Kernel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">K(u) = exp(-0.5 × u²)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"K(u) = exp(-0.5 × u²)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Unnormalized in the loop; the sum is divided by \u003Ccode dir=\"auto\">n × h × √(2π)\u003C/code> for proper normalization.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"evaluation-grid\">Evaluation Grid\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#evaluation-grid\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Evaluation Grid”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Default: 100 points\u003C/li>\n\u003Cli>Range: \u003Ccode dir=\"auto\">[min - 3h, max + 3h]\u003C/code> — extends 3 bandwidths beyond data range (matches the R/ggplot2 \u003Ccode dir=\"auto\">cut=3\u003C/code> default)\u003C/li>\n\u003Cli>Output format: \u003Ccode dir=\"auto\">{ value: x, count: density }\u003C/code> — compatible with \u003Ccode dir=\"auto\">@visx/stats\u003C/code> ViolinPlot\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-9--staged-analysis\">Part 9 — Staged Analysis\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-9--staged-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 9 — Staged Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/stats/staged.ts\u003C/code>\nUser docs: \u003Ca href=\"../03-features/analysis/staged-analysis.md\">Staged Analysis\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"stage-order-detection\">Stage Order Detection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#stage-order-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Stage Order Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">determineStageOrder(stageValues, mode?)\u003C/code>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Mode\u003C/th>\u003Cth>Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'data-order'\u003C/code>\u003C/td>\u003Ctd>First-occurrence order (no sorting)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'auto'\u003C/code> (default)\u003C/td>\u003Ctd>If all values match numeric patterns (\u003Ccode dir=\"auto\">/^\\d+(\\.\\d+)?$/\u003C/code> or \u003Ccode dir=\"auto\">/^(stage|phase|batch|period|run)?\\s*\\d+$/i\u003C/code>), sorts numerically by embedded number. Otherwise, first-occurrence order.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"per-stage-statistics\">Per-Stage Statistics\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#per-stage-statistics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Per-Stage Statistics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">calculateStatsByStage()\u003C/code> calls \u003Ccode dir=\"auto\">calculateStats()\u003C/code> independently for each stage, producing separate UCL, LCL, Cp, Cpk per stage. Also computes \u003Ccode dir=\"auto\">overallStats\u003C/code> across all values combined.\u003C/p>\n\u003Cp>Returns \u003Ccode dir=\"auto\">null\u003C/code> for empty data, empty stage order, or if no stage contains any data.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"stage-boundaries\">Stage Boundaries\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#stage-boundaries\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Stage Boundaries”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">getStageBoundaries()\u003C/code> maps sorted chart data points to stage x-axis extents for rendering. Returns \u003Ccode dir=\"auto\">{ name, startX, endX, stats }\u003C/code> per non-empty stage, using \u003Ccode dir=\"auto\">safeMin\u003C/code>/\u003Ccode dir=\"auto\">safeMax\u003C/code> iterative min/max (avoids \u003Ccode dir=\"auto\">Math.min(...spread)\u003C/code> stack overflow on large arrays).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-10--variation-decomposition\">Part 10 — Variation Decomposition\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-10--variation-decomposition\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 10 — Variation Decomposition”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/variation/contributions.ts\u003C/code>\nUser docs: \u003Ca href=\"../03-features/analysis/variation-decomposition.md\">Variation Decomposition\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"category-total-ss\">Category Total SS\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#category-total-ss\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Category Total SS”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For a factor with categories c₁, c₂, …, cₖ:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Total SS = Σ (x_ij - x̄)² over all observations\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Category SS_c = Σ (x_ij - x̄)² over observations in category c\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Category % = (Category SS_c / Total SS) × 100\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Total SS = Σ (x_ij - x̄)² over all observationsCategory SS_c = Σ (x_ij - x̄)² over observations in category cCategory % = (Category SS_c / Total SS) × 100\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Design decision\u003C/strong>: Total SS partitioning (not between-group SS) captures \u003Cstrong>both\u003C/strong> mean shift and within-group spread. A category with high internal variation but mean near the grand mean will still show non-zero impact. This better answers “Which categories should I focus on?” from an improvement perspective.\u003C/p>\n\u003Cp>All category percentages sum to 100% — variation is fully partitioned.\u003C/p>\n\u003Cp>Returns \u003Ccode dir=\"auto\">null\u003C/code> if fewer than 2 rows or zero total variance.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"category-stats\">Category Stats\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#category-stats\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Category Stats”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">getCategoryStats()\u003C/code> returns per-category detail: count, mean, stdDev (population), contributionPct. Sorted by contribution descending (worst performers first). Used by the What-If Simulator.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-11--drill-down--cumulative-scope\">Part 11 — Drill-Down & Cumulative Scope\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-11--drill-down--cumulative-scope\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 11 — Drill-Down & Cumulative Scope”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/variation/drill.ts\u003C/code>, \u003Ccode dir=\"auto\">packages/hooks/src/useDrillPath.ts\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cumulative-scope-calculation\">Cumulative Scope Calculation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cumulative-scope-calculation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cumulative Scope Calculation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The drill scope is \u003Cstrong>multiplicative\u003C/strong>, not additive. Each drill level reduces the “window” to a fraction of the previous level:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">cumulativeScope = Π (localScope_i) for i = 1, ..., depth\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"cumulativeScope = Π (localScope_i) for i = 1, ..., depth\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Example: three levels with 80%, 70%, 60% local scope → cumulative = 0.8 × 0.7 × 0.6 = 33.6%.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"algorithm-calculatedrillvariation\">Algorithm (calculateDrillVariation)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#algorithm-calculatedrillvariation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Algorithm (calculateDrillVariation)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Start with root entry: \u003Ccode dir=\"auto\">localVariation = 100%, cumulative = 100%\u003C/code>\u003C/li>\n\u003Cli>For each filter in order:\n\u003Cul>\n\u003Cli>Compute \u003Ccode dir=\"auto\">calculateCategoryTotalSS()\u003C/code> on \u003Cstrong>current filtered data\u003C/strong> (not raw data)\u003C/li>\n\u003Cli>Sum contributions of selected category values → \u003Ccode dir=\"auto\">selectedPct\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">cumulativePct = (cumulativePct × selectedPct) / 100\u003C/code>\u003C/li>\n\u003Cli>Filter data down to selected values for next iteration\u003C/li>\n\u003Cli>Break if fewer than 2 rows remain\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"drill-path-statistics-usedrillpath-hook\">Drill Path Statistics (useDrillPath hook)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#drill-path-statistics-usedrillpath-hook\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill Path Statistics (useDrillPath hook)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">useDrillPath\u003C/code> hook retrospectively computes drill path statistics by iterating the filter stack:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> DrillStep {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">scopeFraction\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// selected categories' Total SS fraction (0–1)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cumulativeScope\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// running product of all scopeFractions (0–1)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">meanBefore\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// mean before this filter applied\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">meanAfter\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// mean after this filter applied\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cpkBefore\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cpkAfter\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">countBefore\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">countAfter\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface DrillStep { factor: string; values: (string | number)[]; scopeFraction: number; // selected categories' Total SS fraction (0–1) cumulativeScope: number; // running product of all scopeFractions (0–1) meanBefore: number; // mean before this filter applied meanAfter: number; // mean after this filter applied cpkBefore: number | undefined; cpkAfter: number | undefined; countBefore: number; countAfter: number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>For each filter action, the hook calls \u003Ccode dir=\"auto\">calculateCategoryTotalSS()\u003C/code> on the progressively filtered data and \u003Ccode dir=\"auto\">calculateStats()\u003C/code> on the outcome values before and after the filter. This provides the before/after delta visible in the narrative timeline.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"total-ss-vs-eta-squared\">Total SS vs Eta-Squared\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#total-ss-vs-eta-squared\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Total SS vs Eta-Squared”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The codebase uses two different metrics for variation attribution:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Formula\u003C/th>\u003Cth>Where used\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Category Total SS %\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">SS_category / SS_total × 100\u003C/code>\u003C/td>\u003Ctd>Drill scope tracking, breadcrumbs, progress bar, category popover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>η² (eta-squared)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">SS_between / SS_total\u003C/code>\u003C/td>\u003Ctd>Mindmap node sizing, node percentage label\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Total SS partitioning captures within-group spread. Eta-squared captures only between-group mean differences. The distinction is intentional: scope tracking uses Total SS (comprehensive), while node visual prominence uses η² (highlighting factors where category means differ most).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-12--drill-suggestions\">Part 12 — Drill Suggestions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-12--drill-suggestions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 12 — Drill Suggestions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/variation/suggestions.ts\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"constants\">Constants\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#constants\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Constants”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DRILL_SWITCH_THRESHOLD = 5 // Minimum % variation for drill suggestions\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DRILL_SWITCH_THRESHOLD = 5 // Minimum % variation for drill suggestions\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"max-category-contribution\">Max Category Contribution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#max-category-contribution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Max Category Contribution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">getMaxCategoryContribution(data, factor, outcome)\u003C/code>: returns the highest single-category Total SS contribution for a factor, as a fraction (0–1). This metric matches the numbers visible in the category popover, making the suggestion logic transparent.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"next-drill-factor\">Next Drill Factor\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#next-drill-factor\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Next Drill Factor”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">getNextDrillFactor(factorVariations, currentFactor, minThreshold?)\u003C/code>: after drilling into a factor, finds the remaining factor with highest variation above \u003Ccode dir=\"auto\">minThreshold\u003C/code> (default 5%). Returns factor name or \u003Ccode dir=\"auto\">null\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"optimal-factor-selection-greedy\">Optimal Factor Selection (Greedy)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#optimal-factor-selection-greedy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Optimal Factor Selection (Greedy)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">findOptimalFactors(data, factors, outcome, targetPct?, maxFactors?)\u003C/code>:\u003C/p>\n\u003Col>\n\u003Cli>Compute η² for each factor via \u003Ccode dir=\"auto\">getEtaSquared()\u003C/code>\u003C/li>\n\u003Cli>Sort factors by η² descending\u003C/li>\n\u003Cli>Greedy selection: accumulate as \u003Ccode dir=\"auto\">remaining = remaining × (1 - η²_i)\u003C/code>, cumulative = \u003Ccode dir=\"auto\">100 - remaining × 100\u003C/code>\u003C/li>\n\u003Cli>Stop when cumulative ≥ \u003Ccode dir=\"auto\">targetPct\u003C/code> (default 70%) or \u003Ccode dir=\"auto\">maxFactors\u003C/code> (default 3) reached\u003C/li>\n\u003C/ol>\n\u003Cp>Returns \u003Ccode dir=\"auto\">OptimalFactorResult[]\u003C/code> with factor, variationPct (η² × 100), bestValue (category with highest weighted mean deviation), and cumulativePct.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-13--what-if-simulation\">Part 13 — What-If Simulation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-13--what-if-simulation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 13 — What-If Simulation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/core/src/variation/simulation.ts\u003C/code>\nUser docs: \u003Ca href=\"../03-features/workflows/investigation-to-action.md\">Investigation to Action\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"direct-adjustment\">Direct Adjustment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#direct-adjustment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Direct Adjustment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">simulateDirectAdjustment(currentStats, params, specs?)\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">projectedMean = currentStats.mean + meanShift\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">projectedStdDev = currentStats.stdDev × (1 - variationReduction)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"projectedMean = currentStats.mean + meanShiftprojectedStdDev = currentStats.stdDev × (1 - variationReduction)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Where \u003Ccode dir=\"auto\">variationReduction\u003C/code> is a fraction 0–1 (e.g., 0.2 = 20% reduction).\u003C/p>\n\u003Cp>Projected capability:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">projectedCp = (USL - LSL) / (6 × projectedStdDev)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">projectedCpk = min((USL - projectedMean) / (3 × projectedStdDev),\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">(projectedMean - LSL) / (3 × projectedStdDev))\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"projectedCp = (USL - LSL) / (6 × projectedStdDev)projectedCpk = min((USL - projectedMean) / (3 × projectedStdDev), (projectedMean - LSL) / (3 × projectedStdDev))\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"yield-calculation\">Yield Calculation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#yield-calculation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Yield Calculation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Normal CDF via the error function (Abramowitz & Stegun formula 7.1.26):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">erf(x) ≈ 1 - (a₁t + a₂t² + a₃t³ + a₄t⁴ + a₅t⁵) × exp(-x²)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">where t = 1/(1 + 0.3275911 × |x|)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Φ(z) = 0.5 × (1 + erf(z / √2))\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"erf(x) ≈ 1 - (a₁t + a₂t² + a₃t³ + a₄t⁴ + a₅t⁵) × exp(-x²) where t = 1/(1 + 0.3275911 × |x|)Φ(z) = 0.5 × (1 + erf(z / √2))\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Constants: a₁ = 0.254829592, a₂ = −0.284496736, a₃ = 1.421413741, a₄ = −1.453152027, a₅ = 1.061405429.\u003C/p>\n\u003Cp>Yield is computed as the probability of falling within specification limits:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">yield = Φ((USL - mean) / σ) - Φ((LSL - mean) / σ) (both limits)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">yield = Φ((USL - mean) / σ) (USL only)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">yield = 1 - Φ((LSL - mean) / σ) (LSL only)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"yield = Φ((USL - mean) / σ) - Φ((LSL - mean) / σ) (both limits)yield = Φ((USL - mean) / σ) (USL only)yield = 1 - Φ((LSL - mean) / σ) (LSL only)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Clamped to [0, 100]. PPM = \u003Ccode dir=\"auto\">round((100 - yield%) × 10000)\u003C/code>.\u003C/p>\n\u003Cp>\u003Cstrong>Edge case\u003C/strong>: σ = 0 → yield is 100% if mean is within specs, 0% otherwise.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"category-exclusion\">Category Exclusion\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#category-exclusion\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Category Exclusion”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">calculateProjectedStats(data, factor, outcome, excludedCategories, specs?)\u003C/code>:\u003C/p>\n\u003Cp>Filters out rows matching excluded categories, recomputes mean and \u003Cstrong>population\u003C/strong> std dev on remaining data. Computes improvement percentages (stdDev reduction, mean centering improvement, Cpk improvement) when baseline stats are provided.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"model-driven-simulation-deferred\">Model-Driven Simulation (Deferred)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#model-driven-simulation-deferred\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Model-Driven Simulation (Deferred)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">simulateFromModel()\u003C/code> function and \u003Ccode dir=\"auto\">getFactorBaselines()\u003C/code> exist in the codebase but are not used in Phase 1. They support regression-based what-if analysis (categorical coefficient swaps, continuous factor shifts, interaction terms). Deferred to Phase 2 per ADR-014.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-14--investigation-mindmap\">Part 14 — Investigation Mindmap\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-14--investigation-mindmap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 14 — Investigation Mindmap”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Sources: \u003Ccode dir=\"auto\">packages/charts/src/mindmap/\u003C/code>, \u003Ccode dir=\"auto\">packages/hooks/src/useMindmapState.ts\u003C/code>\nUser docs: \u003Ca href=\"../03-features/workflows/investigation-to-action.md\">Investigation to Action\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"architecture\">Architecture\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Investigation Mindmap is a Visx SVG radial chart with two modes:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Mode\u003C/th>\u003Cth>Layout\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'drilldown'\u003C/code>\u003C/td>\u003Ctd>Radial (hub and spoke)\u003C/td>\u003Ctd>Interactive factor exploration\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'narrative'\u003C/code>\u003C/td>\u003Ctd>Horizontal timeline\u003C/td>\u003Ctd>Story of investigation steps\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"node-data-model\">Node Data Model\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#node-data-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Node Data Model”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> MindmapNode {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">displayName\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">etaSquared\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 0–1; 0 for drilled nodes\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">active\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">available\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">exhausted\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredValue\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// displayed below label when active\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isSuggested\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// green pulse animation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">categoryData\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">CategoryData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface MindmapNode { factor: string; displayName?: string; etaSquared: number; // 0–1; 0 for drilled nodes state: 'active' | 'available' | 'exhausted'; filteredValue?: string; // displayed below label when active isSuggested: boolean; // green pulse animation categoryData?: CategoryData[];}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>State transitions\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">'available'\u003C/code> → \u003Ccode dir=\"auto\">'active'\u003C/code>: user drills into the factor (selects a category)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">'available'\u003C/code> → \u003Ccode dir=\"auto\">'exhausted'\u003C/code>: insufficient data (< 3 rows in filtered scope) or η² < 0.01\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">'active'\u003C/code> → stays active (drilled factors persist)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Suggestion logic\u003C/strong> (in \u003Ccode dir=\"auto\">useMindmapState\u003C/code>): the non-drilled factor with the highest η² above 0.05 is marked as \u003Ccode dir=\"auto\">isSuggested\u003C/code>. Only one factor is suggested at a time.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"node-sizing--area-proportional-encoding\">Node Sizing — Area-Proportional Encoding\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#node-sizing--area-proportional-encoding\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Node Sizing — Area-Proportional Encoding”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/charts/src/mindmap/helpers.ts\u003C/code> — \u003Ccode dir=\"auto\">getNodeRadius()\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cp>Node \u003Cstrong>area\u003C/strong> (not radius) scales linearly with η². This follows Stevens’ Power Law for perceptually accurate magnitude encoding:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">clamped = clamp(etaSquared, 0, 1)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">minArea = π × 20² // MIN_NODE_RADIUS = 20px\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">maxArea = π × 40² // MAX_NODE_RADIUS = 40px\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">area = minArea + clamped × (maxArea - minArea)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">radius = √(area / π)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"clamped = clamp(etaSquared, 0, 1)minArea = π × 20² // MIN_NODE_RADIUS = 20pxmaxArea = π × 40² // MAX_NODE_RADIUS = 40pxarea = minArea + clamped × (maxArea - minArea)radius = √(area / π)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"visual-encoding\">Visual Encoding\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#visual-encoding\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Encoding”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Active (drilled)\u003C/th>\u003Cth>Available\u003C/th>\u003Cth>Exhausted\u003C/th>\u003Cth>Suggested\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Fill\u003C/td>\u003Ctd>Blue (#3b82f6)\u003C/td>\u003Ctd>Slate\u003C/td>\u003Ctd>Dim slate\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Stroke\u003C/td>\u003Ctd>Blue\u003C/td>\u003Ctd>Slate\u003C/td>\u003Ctd>Slate\u003C/td>\u003Ctd>Green (#22c55e)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Animation\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Green pulse\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Label\u003C/td>\u003Ctd>Factor name + filtered value\u003C/td>\u003Ctd>Factor name + η%\u003C/td>\u003Ctd>Factor name\u003C/td>\u003Ctd>Factor name + η%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Colors adapt to light/dark theme via \u003Ccode dir=\"auto\">getNodeFill(state, isDark)\u003C/code> and \u003Ccode dir=\"auto\">getNodeStroke(node, isDark)\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"radial-layout-drilldown-mode\">Radial Layout (Drilldown Mode)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#radial-layout-drilldown-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Radial Layout (Drilldown Mode)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/charts/src/mindmap/layout.ts\u003C/code> — \u003Ccode dir=\"auto\">computeLayout()\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cp>Center hub (“Start”) at the origin. Factor nodes arranged in concentric rings:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Node count\u003C/th>\u003Cth>Rings\u003C/th>\u003Cth>Radius\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>≤ 7\u003C/td>\u003Ctd>Single ring\u003C/td>\u003Ctd>65% of available radius\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8+\u003C/td>\u003Ctd>Two rings\u003C/td>\u003Ctd>Outer: 70% (first 6 nodes), Inner: 38% (remaining)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Angle formula: \u003Ccode dir=\"auto\">angle = -π/2 + (2π × i) / count\u003C/code> — starting at 12 o’clock, evenly spaced.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"timeline-layout-narrative-mode\">Timeline Layout (Narrative Mode)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#timeline-layout-narrative-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Timeline Layout (Narrative Mode)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/charts/src/mindmap/layout.ts\u003C/code> — \u003Ccode dir=\"auto\">computeTimelineLayout()\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cp>Horizontal left-to-right arrangement:\u003C/p>\n\u003Cul>\n\u003Cli>Single step: centered at t = 0.5\u003C/li>\n\u003Cli>Multiple steps: \u003Ccode dir=\"auto\">t = i / (count - 1)\u003C/code>, linearly interpolated\u003C/li>\n\u003Cli>Padding: \u003Ccode dir=\"auto\">min(60, usableWidth / (count + 2))\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"drill-trail\">Drill Trail\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#drill-trail\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill Trail”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Blue line segments connecting center → drilled nodes in the order they were drilled. Rendered from the \u003Ccode dir=\"auto\">drillTrail\u003C/code> array (ordered factor names from drill path).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"category-popover\">Category Popover\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#category-popover\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Category Popover”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/charts/src/mindmap/CategoryPopover.tsx\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cp>Click on an available node → popover showing categories sorted by Total SS contribution %. Full keyboard navigation (ArrowDown/Up, Enter to select, Escape to close). Accessible with \u003Ccode dir=\"auto\">role=\"listbox\"\u003C/code> and \u003Ccode dir=\"auto\">aria-selected\u003C/code>.\u003C/p>\n\u003Cp>Positioning: prefers right side of node, flips left if insufficient space. Prefers top-aligned, flips upward near bottom edge.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"progress-bar\">Progress Bar\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#progress-bar\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Progress Bar”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/charts/src/mindmap/ProgressFooter.tsx\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cp>Horizontal bar at the bottom of the SVG showing cumulative variation scope:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">fill width = (cumulativeVariationPct / 100) × barWidth\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">color = green (#22c55e) if pct ≥ targetPct, else blue (#3b82f6)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"fill width = (cumulativeVariationPct / 100) × barWidthcolor = green (#22c55e) if pct ≥ targetPct, else blue (#3b82f6)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Default target: 70%. Dashed vertical marker at the target position.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"conclusion-panel\">Conclusion Panel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#conclusion-panel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Conclusion Panel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/charts/src/mindmap/ConclusionPanel.tsx\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cp>Rendered at the end of the narrative timeline. Shows whether the investigation target was reached. If \u003Ccode dir=\"auto\">onNavigateToWhatIf\u003C/code> is provided, renders a “Model improvements →” button — the bridge from Investigation Phase to What-If Phase (the 2-phase workflow described in ADR-014).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"state-hook-usemindmapstate\">State Hook (useMindmapState)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#state-hook-usemindmapstate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “State Hook (useMindmapState)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Source: \u003Ccode dir=\"auto\">packages/hooks/src/useMindmapState.ts\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cp>Responsibilities:\u003C/p>\n\u003Col>\n\u003Cli>Calls \u003Ccode dir=\"auto\">useDrillPath()\u003C/code> for drill statistics\u003C/li>\n\u003Cli>Converts filterStack to flat filters, computes filtered data\u003C/li>\n\u003Cli>Computes \u003Ccode dir=\"auto\">MindmapNode[]\u003C/code> from factors: η² per factor, state classification, suggestion\u003C/li>\n\u003Cli>Manages mode state (\u003Ccode dir=\"auto\">'drilldown'\u003C/code> | \u003Ccode dir=\"auto\">'narrative'\u003C/code>)\u003C/li>\n\u003Cli>Manages annotations (step index → text, session-only)\u003C/li>\n\u003Cli>Maps DrillSteps to NarrativeSteps with merged annotations\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"part-15--deferred-methods-phase-2\">Part 15 — Deferred Methods (Phase 2)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#part-15--deferred-methods-phase-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 15 — Deferred Methods (Phase 2)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Per ADR-014, the following modules exist in \u003Ccode dir=\"auto\">@variscout/core\u003C/code> but are not exported or used in the current product:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Module\u003C/th>\u003Cth>Function\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stats/regression.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">calculateRegression()\u003C/code>\u003C/td>\u003Ctd>Simple linear regression\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stats/multiRegression.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">calculateMultipleRegression()\u003C/code>\u003C/td>\u003Ctd>Multiple regression with categorical coding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stats/interaction.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getInteractionStrength()\u003C/code>\u003C/td>\u003Ctd>Factor interaction analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stats/modelReduction.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">suggestTermRemoval()\u003C/code>\u003C/td>\u003Ctd>Backward elimination\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">variation/simulation.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">simulateFromModel()\u003C/code>\u003C/td>\u003Ctd>Regression-based what-if\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>These will enable model-driven simulation in a future release: regression coefficients → what-if adjustments → projected outcomes.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"references--standards\">References & Standards\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#references--standards\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “References & Standards”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Topic\u003C/th>\u003Cth>Standard / Source\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>I-MR chart, σ_within\u003C/td>\u003Ctd>Wheeler, \u003Cem>Understanding Variation\u003C/em> (2000); d2 constant from AIAG SPC Manual\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cp, Cpk\u003C/td>\u003Ctd>AIAG Statistical Process Control Reference Manual, 2nd ed.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>d2 = 1.128\u003C/td>\u003Ctd>Hartley unbiasing constant for moving range span 2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ANOVA effect size (η²)\u003C/td>\u003Ctd>Cohen, \u003Cem>Statistical Power Analysis for the Behavioral Sciences\u003C/em> (1988)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot, IQR fences\u003C/td>\u003Ctd>Tukey, \u003Cem>Exploratory Data Analysis\u003C/em> (1977)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>KDE bandwidth\u003C/td>\u003Ctd>Silverman, \u003Cem>Density Estimation for Statistics and Data Analysis\u003C/em> (1986)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Benard median rank\u003C/td>\u003Ctd>Benard & Bos-Levenbach (1953); Minitab default\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Normal quantile\u003C/td>\u003Ctd>Acklam’s rational approximation (~1e-9 accuracy)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Error function\u003C/td>\u003Ctd>Abramowitz & Stegun, \u003Cem>Handbook of Mathematical Functions\u003C/em>, formula 7.1.26\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Incomplete beta / continued fraction\u003C/td>\u003Ctd>Lentz’s algorithm (max 200 iterations, ε = 1e-10)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Node area encoding\u003C/td>\u003Ctd>Stevens’ Power Law — area ∝ magnitude for perceptual accuracy\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Nelson Rule 2\u003C/td>\u003Ctd>Nelson, \u003Cem>Journal of Quality Technology\u003C/em> (1984) — 9-point runs\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 1623, + "localImagePaths": 1857, + "remoteImagePaths": 1858, + "frontmatter": 1859, + "imagePaths": 1860 + }, + [ + 1624, 1626, 1629, 1632, 1635, 1638, 1641, 1644, 1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, + 1671, 1674, 1677, 1680, 1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, 1713, 1716, + 1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, 1749, 1752, 1755, 1758, 1761, 1764, + 1767, 1770, 1773, 1776, 1779, 1782, 1785, 1788, 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, + 1815, 1818, 1821, 1824, 1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854 + ], + { "depth": 30, "slug": 1625, "text": 1613 }, + "statistics--mindmap-technical-reference", + { "depth": 33, "slug": 1627, "text": 1628 }, + "audience--conventions", + "Audience & Conventions", + { "depth": 33, "slug": 1630, "text": 1631 }, + "data-model", + "Data Model", + { "depth": 33, "slug": 1633, "text": 1634 }, + "part-1--core-statistics", + "Part 1 — Core Statistics", + { "depth": 79, "slug": 1636, "text": 1637 }, + "central-tendency", + "Central Tendency", + { "depth": 79, "slug": 1639, "text": 1640 }, + "dispersion--two-sigmas", + "Dispersion — Two Sigmas", + { "depth": 79, "slug": 1642, "text": 1643 }, + "control-limits-i-chart", + "Control Limits (I-Chart)", + { "depth": 79, "slug": 1645, "text": 1646 }, + "process-capability", + "Process Capability", + { "depth": 79, "slug": 1648, "text": 1649 }, + "conformance", + "Conformance", + { "depth": 33, "slug": 1651, "text": 1652 }, + "part-2--one-way-anova", + "Part 2 — One-Way ANOVA", + { "depth": 79, "slug": 1654, "text": 1655 }, + "full-ss-decomposition", + "Full SS Decomposition", + { "depth": 79, "slug": 1657, "text": 1658 }, + "degrees-of-freedom", + "Degrees of Freedom", + { "depth": 79, "slug": 1660, "text": 1661 }, + "f-statistic-and-p-value", + "F-Statistic and p-Value", + { "depth": 79, "slug": 1663, "text": 1664 }, + "eta-squared-effect-size", + "Eta-Squared (Effect Size)", + { "depth": 79, "slug": 1666, "text": 1667 }, + "significance", + "Significance", + { "depth": 79, "slug": 1669, "text": 1670 }, + "insight-generation", + "Insight Generation", + { "depth": 79, "slug": 1672, "text": 1673 }, + "guard-clauses", + "Guard Clauses", + { "depth": 33, "slug": 1675, "text": 1676 }, + "part-3--distribution-functions", + "Part 3 — Distribution Functions", + { "depth": 79, "slug": 1678, "text": 1679 }, + "normal-pdf", + "Normal PDF", + { "depth": 79, "slug": 1681, "text": 1682 }, + "log-gamma-lanczos-approximation", + "Log-Gamma (Lanczos Approximation)", + { "depth": 79, "slug": 1684, "text": 1685 }, + "regularized-incomplete-beta", + "Regularized Incomplete Beta", + { "depth": 79, "slug": 1687, "text": 1688 }, + "f-distribution-p-value", + "F-Distribution p-Value", + { "depth": 79, "slug": 1690, "text": 1691 }, + "t-distribution-p-value", + "t-Distribution p-Value", + { "depth": 33, "slug": 1693, "text": 1694 }, + "part-4--normal-quantile-inverse-cdf", + "Part 4 — Normal Quantile (Inverse CDF)", + { "depth": 33, "slug": 1696, "text": 1697 }, + "part-5--probability-plot", + "Part 5 — Probability Plot", + { "depth": 79, "slug": 1699, "text": 1700 }, + "median-rank-benards-approximation", + "Median Rank (Benard’s Approximation)", + { "depth": 79, "slug": 1702, "text": 1703 }, + "z-score", + "Z-Score", + { "depth": 79, "slug": 1705, "text": 1706 }, + "standard-error-of-percentile", + "Standard Error of Percentile", + { "depth": 79, "slug": 1708, "text": 1709 }, + "95-confidence-interval", + "95% Confidence Interval", + { "depth": 79, "slug": 1711, "text": 1712 }, + "preprocessing", + "Preprocessing", + { "depth": 33, "slug": 1714, "text": 1715 }, + "part-6--nelson-rule-2", + "Part 6 — Nelson Rule 2", + { "depth": 79, "slug": 1717, "text": 1718 }, + "definition", + "Definition", + { "depth": 79, "slug": 1720, "text": 1721 }, + "algorithm", + "Algorithm", + { "depth": 79, "slug": 1723, "text": 1724 }, + "exports", + "Exports", + { "depth": 33, "slug": 1726, "text": 1727 }, + "part-7--boxplot-statistics", + "Part 7 — Boxplot Statistics", + { "depth": 79, "slug": 1729, "text": 1730 }, + "five-number-summary", + "Five-Number Summary", + { "depth": 79, "slug": 1732, "text": 1733 }, + "outlier-detection-tukey", + "Outlier Detection (Tukey)", + { "depth": 79, "slug": 1735, "text": 1736 }, + "sorting", + "Sorting", + { "depth": 33, "slug": 1738, "text": 1739 }, + "part-8--kernel-density-estimation", + "Part 8 — Kernel Density Estimation", + { "depth": 79, "slug": 1741, "text": 1742 }, + "bandwidth-selection-silvermans-rule", + "Bandwidth Selection (Silverman’s Rule)", + { "depth": 79, "slug": 1744, "text": 1745 }, + "gaussian-kernel", + "Gaussian Kernel", + { "depth": 79, "slug": 1747, "text": 1748 }, + "evaluation-grid", + "Evaluation Grid", + { "depth": 33, "slug": 1750, "text": 1751 }, + "part-9--staged-analysis", + "Part 9 — Staged Analysis", + { "depth": 79, "slug": 1753, "text": 1754 }, + "stage-order-detection", + "Stage Order Detection", + { "depth": 79, "slug": 1756, "text": 1757 }, + "per-stage-statistics", + "Per-Stage Statistics", + { "depth": 79, "slug": 1759, "text": 1760 }, + "stage-boundaries", + "Stage Boundaries", + { "depth": 33, "slug": 1762, "text": 1763 }, + "part-10--variation-decomposition", + "Part 10 — Variation Decomposition", + { "depth": 79, "slug": 1765, "text": 1766 }, + "category-total-ss", + "Category Total SS", + { "depth": 79, "slug": 1768, "text": 1769 }, + "category-stats", + "Category Stats", + { "depth": 33, "slug": 1771, "text": 1772 }, + "part-11--drill-down--cumulative-scope", + "Part 11 — Drill-Down & Cumulative Scope", + { "depth": 79, "slug": 1774, "text": 1775 }, + "cumulative-scope-calculation", + "Cumulative Scope Calculation", + { "depth": 79, "slug": 1777, "text": 1778 }, + "algorithm-calculatedrillvariation", + "Algorithm (calculateDrillVariation)", + { "depth": 79, "slug": 1780, "text": 1781 }, + "drill-path-statistics-usedrillpath-hook", + "Drill Path Statistics (useDrillPath hook)", + { "depth": 79, "slug": 1783, "text": 1784 }, + "total-ss-vs-eta-squared", + "Total SS vs Eta-Squared", + { "depth": 33, "slug": 1786, "text": 1787 }, + "part-12--drill-suggestions", + "Part 12 — Drill Suggestions", + { "depth": 79, "slug": 1789, "text": 1790 }, + "constants", + "Constants", + { "depth": 79, "slug": 1792, "text": 1793 }, + "max-category-contribution", + "Max Category Contribution", + { "depth": 79, "slug": 1795, "text": 1796 }, + "next-drill-factor", + "Next Drill Factor", + { "depth": 79, "slug": 1798, "text": 1799 }, + "optimal-factor-selection-greedy", + "Optimal Factor Selection (Greedy)", + { "depth": 33, "slug": 1801, "text": 1802 }, + "part-13--what-if-simulation", + "Part 13 — What-If Simulation", + { "depth": 79, "slug": 1804, "text": 1805 }, + "direct-adjustment", + "Direct Adjustment", + { "depth": 79, "slug": 1807, "text": 1808 }, + "yield-calculation", + "Yield Calculation", + { "depth": 79, "slug": 1810, "text": 1811 }, + "category-exclusion", + "Category Exclusion", + { "depth": 79, "slug": 1813, "text": 1814 }, + "model-driven-simulation-deferred", + "Model-Driven Simulation (Deferred)", + { "depth": 33, "slug": 1816, "text": 1817 }, + "part-14--investigation-mindmap", + "Part 14 — Investigation Mindmap", + { "depth": 79, "slug": 1819, "text": 1820 }, + "architecture", + "Architecture", + { "depth": 79, "slug": 1822, "text": 1823 }, + "node-data-model", + "Node Data Model", + { "depth": 79, "slug": 1825, "text": 1826 }, + "node-sizing--area-proportional-encoding", + "Node Sizing — Area-Proportional Encoding", + { "depth": 79, "slug": 1828, "text": 1829 }, + "visual-encoding", + "Visual Encoding", + { "depth": 79, "slug": 1831, "text": 1832 }, + "radial-layout-drilldown-mode", + "Radial Layout (Drilldown Mode)", + { "depth": 79, "slug": 1834, "text": 1835 }, + "timeline-layout-narrative-mode", + "Timeline Layout (Narrative Mode)", + { "depth": 79, "slug": 1837, "text": 1838 }, + "drill-trail", + "Drill Trail", + { "depth": 79, "slug": 1840, "text": 1841 }, + "category-popover", + "Category Popover", + { "depth": 79, "slug": 1843, "text": 1844 }, + "progress-bar", + "Progress Bar", + { "depth": 79, "slug": 1846, "text": 1847 }, + "conclusion-panel", + "Conclusion Panel", + { "depth": 79, "slug": 1849, "text": 1850 }, + "state-hook-usemindmapstate", + "State Hook (useMindmapState)", + { "depth": 33, "slug": 1852, "text": 1853 }, + "part-15--deferred-methods-phase-2", + "Part 15 — Deferred Methods (Phase 2)", + { "depth": 33, "slug": 1855, "text": 1856 }, + "references--standards", + "References & Standards", + [], + [], + { "title": 1613 }, + [], + "05-technical", + { "id": 1861, "data": 1863, "body": 1868, "filePath": 1869, "digest": 1870, "rendered": 1871 }, + { + "title": 1864, + "editUrl": 16, + "head": 1865, + "template": 18, + "sidebar": 1866, + "pagefind": 16, + "draft": 20 + }, + "Technical Documentation", + [], + { "hidden": 20, "attrs": 1867 }, + {}, + "# Technical Documentation\n\nTechnical specifications for VariScout implementation. These documents are designed to be used by developers (human or AI) building the product.\n\n---\n\n## Architecture Overview\n\n```\nVARISCOUT ARCHITECTURE (Browser-Only)\n─────────────────────────────────────────────────────────────────\n\n┌─────────────────────────────────────────────────────────────────┐\n│ USER'S BROWSER │\n├─────────────────────────────────────────────────────────────────┤\n│ │\n│ ┌───────────────────────────────────────────────────────────┐ │\n│ │ REACT APPLICATION │ │\n│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │\n│ │ │ I-Chart │ │ Boxplot │ │ Pareto │ │Capability│ │ │\n│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │\n│ │ │ │ │\n│ │ ↓ │ │\n│ │ ┌───────────────┐ │ │\n│ │ │ Analysis Core │ (statistics, calculations) │ │\n│ │ └───────────────┘ │ │\n│ └───────────────────────────────────────────────────────────┘ │\n│ │ │\n│ ↓ │\n│ ┌───────────────────────────────────────────────────────────┐ │\n│ │ IndexedDB │ │\n│ │ ┌──────────┐ ┌──────────┐ │ │\n│ │ │ Projects │ │ Settings │ │ │\n│ │ └──────────┘ └──────────┘ │ │\n│ └───────────────────────────────────────────────────────────┘ │\n│ │\n│ ┌───────────────────────────────────────────────────────────┐ │\n│ │ Service Worker │ │\n│ │ (offline caching, PWA) │ │\n│ └───────────────────────────────────────────────────────────┘ │\n│ │\n└─────────────────────────────────────────────────────────────────┘\n\n No external payment or license services.\n Tier detection: Azure Marketplace (ARM template params / Graph API).\n See ADR-007 for distribution strategy.\n```\n\n---\n\n## Sections\n\n### Architecture\n\nHigh-level architecture overview and detailed design documents:\n\n| Document | Description |\n| -------------------------------------------------------- | -------------------------------------------- |\n| [Architecture Overview](architecture.md) | High-level system architecture |\n| [Monorepo Structure](architecture/monorepo.md) | pnpm workspaces, package boundaries |\n| [Offline-First](architecture/offline-first.md) | PWA, service worker, IndexedDB |\n| [Shared Packages](architecture/shared-packages.md) | Package extraction and reuse strategy |\n| [Data Flow](architecture/data-flow.md) | Data pipeline from input to visualization |\n| [Component Patterns](architecture/component-patterns.md) | Hook integration, colorScheme, base patterns |\n| [Component Map](architecture/component-map.md) | L3 component views per package (internal modules) |\n| [LikeC4 Model](../architecture/likec4/) | C4 architecture model (L1-L3) in LikeC4 |\n| [Documentation Methodology](documentation-methodology.md) | Diataxis, C4, Docs-as-Code, journey spine |\n\n### Implementation\n\nBuild, deploy, test, and operate:\n\n| Document | Description |\n| -------------------------------------------------------- | ------------------------------------------ |\n| [Deployment](implementation/deployment.md) | Build and deployment pipeline |\n| [Testing](implementation/testing.md) | Vitest, Playwright, verification protocols |\n| [Data Input](implementation/data-input.md) | Parser, paste flow, column detection |\n| [System Limits](implementation/system-limits.md) | Row limits, factor limits, performance |\n| [Security Scanning](implementation/security-scanning.md) | OWASP scanning, CVE checks |\n| [AI Tooling (ruflo)](implementation/ruflo.md) | AI development workflow tooling |\n| [Statistics Reference](statistics-reference.md) | Exact formulas, algorithms, implementation |\n\n### Integrations\n\nCross-product and embedding:\n\n| Document | Description |\n| -------------------------------------------------- | ----------------------------- |\n| [Embed Messaging](integrations/embed-messaging.md) | postMessage API for embedding |\n| [Shared UI](integrations/shared-ui.md) | Shared UI component strategy |\n\n---\n\n## Key Technical Decisions\n\n| Decision | Choice | Rationale |\n| ------------------------ | ----------------- | ----------------------------------------------- |\n| No backend for user data | Client-only | GDPR simplicity, no hosting costs |\n| IndexedDB for storage | Dexie.js | Large data support, async, persistent |\n| Tier detection | Azure Marketplace | ARM template parameters, Graph API tenant check |\n| Distribution | Azure Marketplace | Per-seat SaaS subscriptions, Microsoft billing |\n| Hosting | Azure App Service | WEBSITE_RUN_FROM_PACKAGE, EasyAuth |\n\nSee [Architecture Decision Records](../07-decisions/index.md) for detailed rationale.\n\n---\n\n## Development Setup\n\n```bash\n# Clone repo\ngit clone https://github.com/your-org/variscout-lite.git\ncd variscout-lite\n\n# Install dependencies\npnpm install\n\n# Development server\npnpm dev\n\n# Build for production\npnpm build\n\n# Preview production build\npnpm preview\n```\n\n---\n\n## Quick Reference\n\n```bash\npnpm dev # PWA dev server (localhost:5173)\npnpm --filter @variscout/azure-app dev # Azure app dev server\n\npnpm build # Build all packages and apps\npnpm test # Run Vitest tests (all packages)\n\n# AI development tooling\nnpx ruflo@latest daemon status # Check worker state\nnpx ruflo@latest memory search --query \"...\" # Semantic search\nnpx ruflo@latest security scan --depth full # OWASP scan\n```", + "src/content/docs/05-technical/index.md", + "07aad1bec0633890", + { "html": 1872, "metadata": 1873 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"technical-documentation\">Technical Documentation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#technical-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Technical specifications for VariScout implementation. These documents are designed to be used by developers (human or AI) building the product.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"architecture-overview\">Architecture Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#architecture-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">VARISCOUT ARCHITECTURE (Browser-Only)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">─────────────────────────────────────────────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ USER'S BROWSER │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌───────────────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ REACT APPLICATION │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ I-Chart │ │ Boxplot │ │ Pareto │ │Capability│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ↓ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ┌───────────────┐ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ Analysis Core │ (statistics, calculations) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └───────────────┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────────────────────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ↓ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌───────────────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ IndexedDB │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ┌──────────┐ ┌──────────┐ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ Projects │ │ Settings │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └──────────┘ └──────────┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────────────────────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌───────────────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Service Worker │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ (offline caching, PWA) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────────────────────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">No external payment or license services.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Tier detection: Azure Marketplace (ARM template params / Graph API).\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">See ADR-007 for distribution strategy.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"VARISCOUT ARCHITECTURE (Browser-Only)─────────────────────────────────────────────────────────────────┌─────────────────────────────────────────────────────────────────┐│ USER'S BROWSER │├─────────────────────────────────────────────────────────────────┤│ ││ ┌───────────────────────────────────────────────────────────┐ ││ │ REACT APPLICATION │ ││ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ ││ │ │ I-Chart │ │ Boxplot │ │ Pareto │ │Capability│ │ ││ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ ││ │ │ │ ││ │ ↓ │ ││ │ ┌───────────────┐ │ ││ │ │ Analysis Core │ (statistics, calculations) │ ││ │ └───────────────┘ │ ││ └───────────────────────────────────────────────────────────┘ ││ │ ││ ↓ ││ ┌───────────────────────────────────────────────────────────┐ ││ │ IndexedDB │ ││ │ ┌──────────┐ ┌──────────┐ │ ││ │ │ Projects │ │ Settings │ │ ││ │ └──────────┘ └──────────┘ │ ││ └───────────────────────────────────────────────────────────┘ ││ ││ ┌───────────────────────────────────────────────────────────┐ ││ │ Service Worker │ ││ │ (offline caching, PWA) │ ││ └───────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘ No external payment or license services. Tier detection: Azure Marketplace (ARM template params / Graph API). See ADR-007 for distribution strategy.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sections\">Sections\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sections\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sections”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"architecture\">Architecture\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>High-level architecture overview and detailed design documents:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Document\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"architecture.md\">Architecture Overview\u003C/a>\u003C/td>\u003Ctd>High-level system architecture\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"architecture/monorepo.md\">Monorepo Structure\u003C/a>\u003C/td>\u003Ctd>pnpm workspaces, package boundaries\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"architecture/offline-first.md\">Offline-First\u003C/a>\u003C/td>\u003Ctd>PWA, service worker, IndexedDB\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"architecture/shared-packages.md\">Shared Packages\u003C/a>\u003C/td>\u003Ctd>Package extraction and reuse strategy\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"architecture/data-flow.md\">Data Flow\u003C/a>\u003C/td>\u003Ctd>Data pipeline from input to visualization\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"architecture/component-patterns.md\">Component Patterns\u003C/a>\u003C/td>\u003Ctd>Hook integration, colorScheme, base patterns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"architecture/component-map.md\">Component Map\u003C/a>\u003C/td>\u003Ctd>L3 component views per package (internal modules)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"../architecture/likec4/\">LikeC4 Model\u003C/a>\u003C/td>\u003Ctd>C4 architecture model (L1-L3) in LikeC4\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"documentation-methodology.md\">Documentation Methodology\u003C/a>\u003C/td>\u003Ctd>Diataxis, C4, Docs-as-Code, journey spine\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"implementation\">Implementation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Build, deploy, test, and operate:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Document\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"implementation/deployment.md\">Deployment\u003C/a>\u003C/td>\u003Ctd>Build and deployment pipeline\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"implementation/testing.md\">Testing\u003C/a>\u003C/td>\u003Ctd>Vitest, Playwright, verification protocols\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"implementation/data-input.md\">Data Input\u003C/a>\u003C/td>\u003Ctd>Parser, paste flow, column detection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"implementation/system-limits.md\">System Limits\u003C/a>\u003C/td>\u003Ctd>Row limits, factor limits, performance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"implementation/security-scanning.md\">Security Scanning\u003C/a>\u003C/td>\u003Ctd>OWASP scanning, CVE checks\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"implementation/ruflo.md\">AI Tooling (ruflo)\u003C/a>\u003C/td>\u003Ctd>AI development workflow tooling\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"statistics-reference.md\">Statistics Reference\u003C/a>\u003C/td>\u003Ctd>Exact formulas, algorithms, implementation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"integrations\">Integrations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#integrations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integrations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Cross-product and embedding:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Document\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"integrations/embed-messaging.md\">Embed Messaging\u003C/a>\u003C/td>\u003Ctd>postMessage API for embedding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"integrations/shared-ui.md\">Shared UI\u003C/a>\u003C/td>\u003Ctd>Shared UI component strategy\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-technical-decisions\">Key Technical Decisions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-technical-decisions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Technical Decisions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Decision\u003C/th>\u003Cth>Choice\u003C/th>\u003Cth>Rationale\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No backend for user data\u003C/td>\u003Ctd>Client-only\u003C/td>\u003Ctd>GDPR simplicity, no hosting costs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>IndexedDB for storage\u003C/td>\u003Ctd>Dexie.js\u003C/td>\u003Ctd>Large data support, async, persistent\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tier detection\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>ARM template parameters, Graph API tenant check\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Distribution\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>Per-seat SaaS subscriptions, Microsoft billing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hosting\u003C/td>\u003Ctd>Azure App Service\u003C/td>\u003Ctd>WEBSITE_RUN_FROM_PACKAGE, EasyAuth\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"../07-decisions/index.md\">Architecture Decision Records\u003C/a> for detailed rationale.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"development-setup\">Development Setup\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#development-setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Development Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Clone repo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">clone\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">https://github.com/your-org/variscout-lite.git\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">cd\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-lite\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Install dependencies\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">install\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Development server\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build for production\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Preview production build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">preview\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"git clone https://github.com/your-org/variscout-lite.gitcd variscout-litepnpm installpnpm devpnpm buildpnpm preview\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"quick-reference\">Quick Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#quick-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># PWA dev server (localhost:5173)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Azure app dev server\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build all packages and apps\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run Vitest tests (all packages)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># AI development tooling\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">daemon\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">status\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Check worker state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">memory\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">search\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Semantic search\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">security\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">scan\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--depth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">full\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># OWASP scan\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm dev # PWA dev server (localhost:5173)pnpm --filter @variscout/azure-app dev # Azure app dev serverpnpm build # Build all packages and appspnpm test # Run Vitest tests (all packages)npx ruflo@latest daemon status # Check worker statenpx ruflo@latest memory search --query "..." # Semantic searchnpx ruflo@latest security scan --depth full # OWASP scan\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>", + { + "headings": 1874, + "localImagePaths": 1899, + "remoteImagePaths": 1900, + "frontmatter": 1901, + "imagePaths": 1902 + }, + [1875, 1877, 1880, 1883, 1884, 1887, 1890, 1893, 1896], + { "depth": 30, "slug": 1876, "text": 1864 }, + "technical-documentation", + { "depth": 33, "slug": 1878, "text": 1879 }, + "architecture-overview", + "Architecture Overview", + { "depth": 33, "slug": 1881, "text": 1882 }, + "sections", + "Sections", + { "depth": 79, "slug": 1819, "text": 1820 }, + { "depth": 79, "slug": 1885, "text": 1886 }, + "implementation", + "Implementation", + { "depth": 79, "slug": 1888, "text": 1889 }, + "integrations", + "Integrations", + { "depth": 33, "slug": 1891, "text": 1892 }, + "key-technical-decisions", + "Key Technical Decisions", + { "depth": 33, "slug": 1894, "text": 1895 }, + "development-setup", + "Development Setup", + { "depth": 33, "slug": 1897, "text": 1898 }, + "quick-reference", + "Quick Reference", + [], + [], + { "title": 1864 }, + [], + "04-cases", + { "id": 1903, "data": 1905, "body": 1910, "filePath": 1911, "digest": 1912, "rendered": 1913 }, + { + "title": 1906, + "editUrl": 16, + "head": 1907, + "template": 18, + "sidebar": 1908, + "pagefind": 16, + "draft": 20 + }, + "VaRiScout Lite Case Studies", + [], + { "hidden": 20, "attrs": 1909 }, + {}, + "# VaRiScout Lite Case Studies\n\n## 12-Week Content Calendar\n\nCase studies mapped to the marketing content calendar. Each case provides data, teaching materials, and video content for its scheduled week.\n\n---\n\n## Case Portfolio\n\n| Week | Case | Location | Primary Analysis | Campaign Phase |\n| ---- | ----------------- | -------------------- | ------------------------------------- | --------------- |\n| 1-4 | **Bottleneck** | ESTIEM training | Process flow, I-Chart, Boxplot | Phase 1: Launch |\n| 5-8 | **Hospital Ward** | Healthcare | Aggregation trap, time patterns | Phase 2: Deepen |\n| 9-12 | **Coffee** | East Africa | Factor comparison | Phase 3: Apply |\n| 9-12 | **Packaging** | Africa manufacturing | Pareto, capability, process diagnosis | Phase 3: Apply |\n| 12 | **Avocado** | Post-harvest | Regression | Phase 3: Apply |\n\n---\n\n## Phase 1: Launch (Weeks 1-4)\n\n### Bottleneck Case (`bottleneck/`)\n\n**Week 1 Featured Case - Conversion Video**\n\nA process with 5 steps. Step 3 was blamed for delays. The manager wanted to invest in Step 3 equipment. But when we actually see the data... Step 2 had 3x the variation.\n\n| File | Description |\n| ----------- | ------------------------------------ |\n| `README.md` | Case overview and teaching points |\n| `data.csv` | 150 observations (5 steps × 30 each) |\n\n**Key insight:** \"What's hiding in YOUR process?\"\n\n**Website:** `/cases/bottleneck`\n\n---\n\n## Phase 2: Deepen (Weeks 5-8)\n\n### Hospital Ward Case (`hospital-ward/`)\n\n**Week 5 Featured Case - Aggregation Trap**\n\nThe dashboard showed 75% average occupancy. Everything looked fine. But hidden in the hourly data: 95% crisis at night, 50% waste in the afternoon.\n\n| File | Description |\n| ----------- | ------------------------------------- |\n| `README.md` | Case overview and teaching points |\n| `data.csv` | 672 observations (28 days × 24 hours) |\n\n**Key insight:** \"What your daily average hides\"\n\n**Website:** `/cases/hospital-ward`\n\n---\n\n## Phase 3: Apply (Weeks 9-12)\n\n### Coffee Case (`coffee/`)\n\n**Week 9-11 Featured Case - Africa Context**\n\nDrying Bed C consistently fails export spec. Is it the bed, the operator, or the measurement? VaRiScout reveals the pattern in 30 seconds.\n\n| File | Description |\n| --------------------- | -------------------------------------------- |\n| `README.md` | Case overview and teaching points |\n| `washing-station.csv` | 30 batches with moisture % and defect counts |\n\n**Teaching points:**\n\n- Factor comparison (Boxplot by drying bed)\n- Spec limits in context (I-Chart)\n\n**Website:** `/cases/coffee`\n\n### Packaging Case (`packaging/`)\n\n**Week 9-11 Featured Case - Africa Context**\n\nNight shift is systematically underfilling. Is it the operators, the equipment, or the measurement? Two datasets tell the complete story.\n\n| File | Description |\n| ----------------- | --------------------------------------------------- |\n| `README.md` | Case overview covering defects and process analysis |\n| `defects.csv` | Daily defect tracking by product and type |\n| `fillweights.csv` | 120 fill weight measurements by shift |\n\n**Teaching points:**\n\n- Pareto prioritization (defect types)\n- Process diagnosis (connecting defects to measurements)\n\n**Website:** `/cases/packaging`\n\n### Avocado Case (`avocado/`)\n\n**Week 12 Featured Case - AI Comparison**\n\nRegression shows coating amount predicts shelf life (R² ~ 0.72). What factors explain the remaining variation?\n\n| File | Description |\n| ------------------------ | -------------------------------------------------- |\n| `README.md` | Case overview covering regression analysis |\n| `coating-regression.csv` | 120 observations with coating, process, shelf life |\n\n**Teaching points:**\n\n- Regression interpretation (slope, R², prediction)\n- Categorical factors (Spray vs. Dip, Carnauba vs. Polyethylene)\n\n**Website:** `/cases/avocado`\n\n---\n\n## Additional Cases (Future Use)\n\n### Oven Zones (`oven-zones/`)\n\n_Not currently in 12-week calendar. Kept for future content._\n\nMulti-zone oven temperature analysis for Performance Mode demonstrations.\n\n| File | Description |\n| ----------- | ------------- |\n| `README.md` | Case overview |\n\n### Machine Utilization (`machine-utilization/`)\n\n_Not currently in 12-week calendar. Kept for future content._\n\nPackaging machine stoppage analysis. Production manager requests €180,000 for second machine. Data reveals it's not capacity—it's workflow.\n\n| File | Description |\n| ------------------------- | ---------------------- |\n| `README.md` | Case overview |\n| `week2_enhanced.csv` | Enhanced stoppage data |\n| `week2_pareto_counts.csv` | Pareto count data |\n\n---\n\n## Folder Structure\n\n```\ndocs/cases/\n├── README.md # This file\n├── bottleneck/ # Week 1 - ESTIEM/Conversion\n│ ├── README.md\n│ └── data.csv\n├── hospital-ward/ # Week 5 - Aggregation\n│ ├── README.md\n│ └── data.csv\n├── coffee/ # Week 9 - Africa\n│ ├── README.md\n│ └── washing-station.csv\n├── packaging/ # Week 9 - Africa\n│ ├── README.md\n│ ├── defects.csv\n│ └── fillweights.csv\n├── avocado/ # Week 12 - Regression\n│ ├── README.md\n│ └── coating-regression.csv\n├── oven-zones/ # Future use\n│ └── README.md\n└── machine-utilization/ # Future use\n ├── README.md\n └── *.csv\n```\n\n---\n\n## Website URL Mapping\n\n| Case | Website URL | Source |\n| ------------- | ---------------------- | --------------------------- |\n| Bottleneck | `/cases/bottleneck` | `docs/cases/bottleneck/` |\n| Hospital Ward | `/cases/hospital-ward` | `docs/cases/hospital-ward/` |\n| Coffee | `/cases/coffee` | `docs/cases/coffee/` |\n| Packaging | `/cases/packaging` | `docs/cases/packaging/` |\n| Avocado | `/cases/avocado` | `docs/cases/avocado/` |\n\n---\n\n## AI Comparison Videos (Week 4, 8, 12)\n\nEvery 4th week features a 3-way comparison:\n\n| Week | Case | Video Title |\n| ---- | ------------- | ------------------------------------------------------ |\n| 4 | Bottleneck | \"VaRiScout vs Copilot Analyst: Finding the Bottleneck\" |\n| 8 | Hospital Ward | \"Can AI Find Hidden Patterns?\" |\n| 12 | Avocado | \"Can AI Find the Relationship?\" |\n\n---\n\n_Case studies developed for VaRiScout Lite demonstration_\n_Target audience: Lean Six Sigma Green Belt trainees_", + "src/content/docs/04-cases/index.md", + "f8a6c256913de2ae", + { "html": 1914, "metadata": 1915 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"variscout-lite-case-studies\">VaRiScout Lite Case Studies\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-lite-case-studies\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VaRiScout Lite Case Studies”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"12-week-content-calendar\">12-Week Content Calendar\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#12-week-content-calendar\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “12-Week Content Calendar”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Case studies mapped to the marketing content calendar. Each case provides data, teaching materials, and video content for its scheduled week.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"case-portfolio\">Case Portfolio\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#case-portfolio\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Case Portfolio”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Week\u003C/th>\u003Cth>Case\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>Primary Analysis\u003C/th>\u003Cth>Campaign Phase\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1-4\u003C/td>\u003Ctd>\u003Cstrong>Bottleneck\u003C/strong>\u003C/td>\u003Ctd>ESTIEM training\u003C/td>\u003Ctd>Process flow, I-Chart, Boxplot\u003C/td>\u003Ctd>Phase 1: Launch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5-8\u003C/td>\u003Ctd>\u003Cstrong>Hospital Ward\u003C/strong>\u003C/td>\u003Ctd>Healthcare\u003C/td>\u003Ctd>Aggregation trap, time patterns\u003C/td>\u003Ctd>Phase 2: Deepen\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9-12\u003C/td>\u003Ctd>\u003Cstrong>Coffee\u003C/strong>\u003C/td>\u003Ctd>East Africa\u003C/td>\u003Ctd>Factor comparison\u003C/td>\u003Ctd>Phase 3: Apply\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9-12\u003C/td>\u003Ctd>\u003Cstrong>Packaging\u003C/strong>\u003C/td>\u003Ctd>Africa manufacturing\u003C/td>\u003Ctd>Pareto, capability, process diagnosis\u003C/td>\u003Ctd>Phase 3: Apply\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>\u003Cstrong>Avocado\u003C/strong>\u003C/td>\u003Ctd>Post-harvest\u003C/td>\u003Ctd>Regression\u003C/td>\u003Ctd>Phase 3: Apply\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-1-launch-weeks-1-4\">Phase 1: Launch (Weeks 1-4)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-1-launch-weeks-1-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 1: Launch (Weeks 1-4)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"bottleneck-case-bottleneck\">Bottleneck Case (\u003Ccode dir=\"auto\">bottleneck/\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#bottleneck-case-bottleneck\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Bottleneck Case (bottleneck/)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Week 1 Featured Case - Conversion Video\u003C/strong>\u003C/p>\n\u003Cp>A process with 5 steps. Step 3 was blamed for delays. The manager wanted to invest in Step 3 equipment. But when we actually see the data… Step 2 had 3x the variation.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">README.md\u003C/code>\u003C/td>\u003Ctd>Case overview and teaching points\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">data.csv\u003C/code>\u003C/td>\u003Ctd>150 observations (5 steps × 30 each)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key insight:\u003C/strong> “What’s hiding in YOUR process?”\u003C/p>\n\u003Cp>\u003Cstrong>Website:\u003C/strong> \u003Ccode dir=\"auto\">/cases/bottleneck\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-2-deepen-weeks-5-8\">Phase 2: Deepen (Weeks 5-8)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-deepen-weeks-5-8\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2: Deepen (Weeks 5-8)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"hospital-ward-case-hospital-ward\">Hospital Ward Case (\u003Ccode dir=\"auto\">hospital-ward/\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#hospital-ward-case-hospital-ward\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hospital Ward Case (hospital-ward/)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Week 5 Featured Case - Aggregation Trap\u003C/strong>\u003C/p>\n\u003Cp>The dashboard showed 75% average occupancy. Everything looked fine. But hidden in the hourly data: 95% crisis at night, 50% waste in the afternoon.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">README.md\u003C/code>\u003C/td>\u003Ctd>Case overview and teaching points\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">data.csv\u003C/code>\u003C/td>\u003Ctd>672 observations (28 days × 24 hours)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key insight:\u003C/strong> “What your daily average hides”\u003C/p>\n\u003Cp>\u003Cstrong>Website:\u003C/strong> \u003Ccode dir=\"auto\">/cases/hospital-ward\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-3-apply-weeks-9-12\">Phase 3: Apply (Weeks 9-12)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3-apply-weeks-9-12\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3: Apply (Weeks 9-12)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"coffee-case-coffee\">Coffee Case (\u003Ccode dir=\"auto\">coffee/\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#coffee-case-coffee\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Coffee Case (coffee/)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Week 9-11 Featured Case - Africa Context\u003C/strong>\u003C/p>\n\u003Cp>Drying Bed C consistently fails export spec. Is it the bed, the operator, or the measurement? VaRiScout reveals the pattern in 30 seconds.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">README.md\u003C/code>\u003C/td>\u003Ctd>Case overview and teaching points\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">washing-station.csv\u003C/code>\u003C/td>\u003Ctd>30 batches with moisture % and defect counts\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Teaching points:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Factor comparison (Boxplot by drying bed)\u003C/li>\n\u003Cli>Spec limits in context (I-Chart)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Website:\u003C/strong> \u003Ccode dir=\"auto\">/cases/coffee\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"packaging-case-packaging\">Packaging Case (\u003Ccode dir=\"auto\">packaging/\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#packaging-case-packaging\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Packaging Case (packaging/)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Week 9-11 Featured Case - Africa Context\u003C/strong>\u003C/p>\n\u003Cp>Night shift is systematically underfilling. Is it the operators, the equipment, or the measurement? Two datasets tell the complete story.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">README.md\u003C/code>\u003C/td>\u003Ctd>Case overview covering defects and process analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">defects.csv\u003C/code>\u003C/td>\u003Ctd>Daily defect tracking by product and type\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">fillweights.csv\u003C/code>\u003C/td>\u003Ctd>120 fill weight measurements by shift\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Teaching points:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Pareto prioritization (defect types)\u003C/li>\n\u003Cli>Process diagnosis (connecting defects to measurements)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Website:\u003C/strong> \u003Ccode dir=\"auto\">/cases/packaging\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"avocado-case-avocado\">Avocado Case (\u003Ccode dir=\"auto\">avocado/\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#avocado-case-avocado\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Avocado Case (avocado/)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Week 12 Featured Case - AI Comparison\u003C/strong>\u003C/p>\n\u003Cp>Regression shows coating amount predicts shelf life (R² ~ 0.72). What factors explain the remaining variation?\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">README.md\u003C/code>\u003C/td>\u003Ctd>Case overview covering regression analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">coating-regression.csv\u003C/code>\u003C/td>\u003Ctd>120 observations with coating, process, shelf life\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Teaching points:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Regression interpretation (slope, R², prediction)\u003C/li>\n\u003Cli>Categorical factors (Spray vs. Dip, Carnauba vs. Polyethylene)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Website:\u003C/strong> \u003Ccode dir=\"auto\">/cases/avocado\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"additional-cases-future-use\">Additional Cases (Future Use)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#additional-cases-future-use\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Additional Cases (Future Use)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"oven-zones-oven-zones\">Oven Zones (\u003Ccode dir=\"auto\">oven-zones/\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#oven-zones-oven-zones\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Oven Zones (oven-zones/)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>Not currently in 12-week calendar. Kept for future content.\u003C/em>\u003C/p>\n\u003Cp>Multi-zone oven temperature analysis for Performance Mode demonstrations.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">README.md\u003C/code>\u003C/td>\u003Ctd>Case overview\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"machine-utilization-machine-utilization\">Machine Utilization (\u003Ccode dir=\"auto\">machine-utilization/\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#machine-utilization-machine-utilization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Machine Utilization (machine-utilization/)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>Not currently in 12-week calendar. Kept for future content.\u003C/em>\u003C/p>\n\u003Cp>Packaging machine stoppage analysis. Production manager requests €180,000 for second machine. Data reveals it’s not capacity—it’s workflow.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">README.md\u003C/code>\u003C/td>\u003Ctd>Case overview\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">week2_enhanced.csv\u003C/code>\u003C/td>\u003Ctd>Enhanced stoppage data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">week2_pareto_counts.csv\u003C/code>\u003C/td>\u003Ctd>Pareto count data\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"folder-structure\">Folder Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#folder-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Folder Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">docs/cases/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── README.md # This file\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── bottleneck/ # Week 1 - ESTIEM/Conversion\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── README.md\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── data.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── hospital-ward/ # Week 5 - Aggregation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── README.md\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── data.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── coffee/ # Week 9 - Africa\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── README.md\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── washing-station.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── packaging/ # Week 9 - Africa\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── README.md\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── defects.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── fillweights.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── avocado/ # Week 12 - Regression\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── README.md\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── coating-regression.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── oven-zones/ # Future use\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── README.md\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── machine-utilization/ # Future use\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── README.md\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── *.csv\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"docs/cases/├── README.md # This file├── bottleneck/ # Week 1 - ESTIEM/Conversion│ ├── README.md│ └── data.csv├── hospital-ward/ # Week 5 - Aggregation│ ├── README.md│ └── data.csv├── coffee/ # Week 9 - Africa│ ├── README.md│ └── washing-station.csv├── packaging/ # Week 9 - Africa│ ├── README.md│ ├── defects.csv│ └── fillweights.csv├── avocado/ # Week 12 - Regression│ ├── README.md│ └── coating-regression.csv├── oven-zones/ # Future use│ └── README.md└── machine-utilization/ # Future use ├── README.md └── *.csv\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-url-mapping\">Website URL Mapping\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-url-mapping\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website URL Mapping”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Case\u003C/th>\u003Cth>Website URL\u003C/th>\u003Cth>Source\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/cases/bottleneck\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">docs/cases/bottleneck/\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hospital Ward\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/cases/hospital-ward\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">docs/cases/hospital-ward/\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Coffee\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/cases/coffee\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">docs/cases/coffee/\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Packaging\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/cases/packaging\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">docs/cases/packaging/\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Avocado\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/cases/avocado\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">docs/cases/avocado/\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ai-comparison-videos-week-4-8-12\">AI Comparison Videos (Week 4, 8, 12)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ai-comparison-videos-week-4-8-12\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “AI Comparison Videos (Week 4, 8, 12)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every 4th week features a 3-way comparison:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Week\u003C/th>\u003Cth>Case\u003C/th>\u003Cth>Video Title\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>”VaRiScout vs Copilot Analyst: Finding the Bottleneck”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>Hospital Ward\u003C/td>\u003Ctd>”Can AI Find Hidden Patterns?“\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>Avocado\u003C/td>\u003Ctd>”Can AI Find the Relationship?”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cp>\u003Cem>Case studies developed for VaRiScout Lite demonstration\u003C/em>\n\u003Cem>Target audience: Lean Six Sigma Green Belt trainees\u003C/em>\u003C/p>", + { + "headings": 1916, + "localImagePaths": 1967, + "remoteImagePaths": 1968, + "frontmatter": 1969, + "imagePaths": 1970 + }, + [ + 1917, 1919, 1922, 1925, 1928, 1931, 1934, 1937, 1940, 1943, 1946, 1949, 1952, 1955, 1958, 1961, + 1964 + ], + { "depth": 30, "slug": 1918, "text": 1906 }, + "variscout-lite-case-studies", + { "depth": 33, "slug": 1920, "text": 1921 }, + "12-week-content-calendar", + "12-Week Content Calendar", + { "depth": 33, "slug": 1923, "text": 1924 }, + "case-portfolio", + "Case Portfolio", + { "depth": 33, "slug": 1926, "text": 1927 }, + "phase-1-launch-weeks-1-4", + "Phase 1: Launch (Weeks 1-4)", + { "depth": 79, "slug": 1929, "text": 1930 }, + "bottleneck-case-bottleneck", + "Bottleneck Case (bottleneck/)", + { "depth": 33, "slug": 1932, "text": 1933 }, + "phase-2-deepen-weeks-5-8", + "Phase 2: Deepen (Weeks 5-8)", + { "depth": 79, "slug": 1935, "text": 1936 }, + "hospital-ward-case-hospital-ward", + "Hospital Ward Case (hospital-ward/)", + { "depth": 33, "slug": 1938, "text": 1939 }, + "phase-3-apply-weeks-9-12", + "Phase 3: Apply (Weeks 9-12)", + { "depth": 79, "slug": 1941, "text": 1942 }, + "coffee-case-coffee", + "Coffee Case (coffee/)", + { "depth": 79, "slug": 1944, "text": 1945 }, + "packaging-case-packaging", + "Packaging Case (packaging/)", + { "depth": 79, "slug": 1947, "text": 1948 }, + "avocado-case-avocado", + "Avocado Case (avocado/)", + { "depth": 33, "slug": 1950, "text": 1951 }, + "additional-cases-future-use", + "Additional Cases (Future Use)", + { "depth": 79, "slug": 1953, "text": 1954 }, + "oven-zones-oven-zones", + "Oven Zones (oven-zones/)", + { "depth": 79, "slug": 1956, "text": 1957 }, + "machine-utilization-machine-utilization", + "Machine Utilization (machine-utilization/)", + { "depth": 33, "slug": 1959, "text": 1960 }, + "folder-structure", + "Folder Structure", + { "depth": 33, "slug": 1962, "text": 1963 }, + "website-url-mapping", + "Website URL Mapping", + { "depth": 33, "slug": 1965, "text": 1966 }, + "ai-comparison-videos-week-4-8-12", + "AI Comparison Videos (Week 4, 8, 12)", + [], + [], + { "title": 1906 }, + [], + "06-design-system", + { "id": 1971, "data": 1973, "body": 1978, "filePath": 1979, "digest": 1980, "rendered": 1981 }, + { + "title": 1974, + "editUrl": 16, + "head": 1975, + "template": 18, + "sidebar": 1976, + "pagefind": 16, + "draft": 20 + }, + "VariScout Design System", + [], + { "hidden": 20, "attrs": 1977 }, + {}, + "# VariScout Design System\n\nA unified design system for VariScout covering PWA and Azure App platforms.\n\n## Principles\n\n1. **Theme-aware** - Supports dark/light modes (light mode for paid tiers)\n2. **Data-focused** - Colors prioritize data visibility and status communication\n3. **Consistent semantics** - Same meaning for colors across platforms\n4. **Responsive** - Adapts to screen size without losing functionality\n5. **Accessible** - WCAG AA compliant contrast ratios\n\n## Theming (PWA)\n\nThe PWA uses CSS variables for theming, enabling runtime theme switching:\n\n| Feature | Free tier | Paid tiers (Individual/Team/Enterprise) |\n| ----------------- | ----------- | --------------------------------------- |\n| Dark mode | ✓ (default) | ✓ |\n| Light mode | - | ✓ |\n| System preference | - | ✓ |\n| Company accent | - | ✓ |\n\n### Semantic Color Classes\n\nComponents use semantic Tailwind classes that adapt to the active theme:\n\n| Semantic Class | Dark Mode | Light Mode |\n| ------------------------ | --------- | ---------- |\n| `bg-surface` | slate-900 | slate-50 |\n| `bg-surface-secondary` | slate-800 | slate-100 |\n| `text-content` | slate-200 | slate-900 |\n| `text-content-secondary` | slate-400 | slate-600 |\n| `border-edge` | slate-700 | slate-200 |\n\nSee [Colors](./foundations/colors.md) for the complete mapping.\n\n## Quick Reference\n\n### Foundations\n\n- [Colors](./foundations/colors.md) - Color palette and semantic usage\n- [Typography](./foundations/typography.md) - Fonts, sizes, weights\n- [Spacing](./foundations/spacing.md) - Spacing scale and units\n- [Accessibility](./foundations/accessibility.md) - WCAG AA guidelines, keyboard navigation, screen readers\n\n### Charts\n\n- [Overview](./charts/overview.md) - Chart styling principles\n- [Colors](./charts/colors.md) - Data visualization palette\n- [Responsive](./charts/responsive.md) - Breakpoints and scaling\n- [Hooks](./charts/hooks.md) - Chart hooks (useChartTheme, useChartScale)\n- [I-Chart](./charts/ichart.md) - Individuals control chart design\n- [Boxplot](./charts/boxplot.md) - Boxplot and violin mode design\n- [Pareto](./charts/pareto.md) - Pareto chart design\n- [Capability](./charts/capability.md) - Capability histogram design\n- [Probability Plot](./charts/probability-plot.md) - Probability plot design\n- [Performance Mode](./charts/performance-mode.md) - Multi-channel chart design\n- [Shared Components](./charts/shared-components.md) - ChartSourceBar, EditableChartTitle, etc.\n\n### Components\n\n- [Buttons](./components/buttons.md) - Button variants\n- [Cards](./components/cards.md) - Cards and panels\n- [Modals](./components/modals.md) - Modal patterns\n- [Forms](./components/forms.md) - Form elements\n- [VariationBar](./components/variation-funnel.md) - Variation scope progress bar\n- [What-If Simulator](./components/what-if-simulator.md) - Process improvement exploration\n\n### Patterns\n\n- [Layout](./patterns/layout.md) - Page layouts\n- [Feedback](./patterns/feedback.md) - Status and loading states\n- [Navigation](./patterns/navigation.md) - Navigation patterns and breadcrumbs\n- [Interactions](./patterns/interactions.md) - Interaction patterns (inline edit, grids, selection cards)\n- [Panels and Drawers](./patterns/panels-and-drawers.md) - Panel decision framework, drawer types, z-index scale\n\n## Usage\n\n### PWA (Tailwind with Semantic Classes)\n\n```jsx\n// Use semantic classes for theme-aware styling\n\u003Cdiv className=\"bg-surface border border-edge rounded-lg p-4\">\n \u003Ch2 className=\"text-content font-semibold\">Title\u003C/h2>\n \u003Cp className=\"text-content-secondary\">Description\u003C/p>\n\u003C/div>\n\n// Primary button (brand colors don't change with theme)\n\u003Cbutton className=\"bg-blue-600 hover:bg-blue-700 text-white rounded-lg px-4 py-2\">\n Primary Button\n\u003C/button>\n```\n\n### Charts (Visx)\n\n```tsx\nimport { useChartTheme } from '@variscout/charts';\n\n// Chrome colors adapt to theme\nconst { chrome } = useChartTheme();\n\u003Ctext fill={chrome.labelPrimary}>Axis Label\u003C/text>\n\n// Data colors remain universal (pass/fail/warning)\n\u003CCircle fill=\"#22c55e\" /> // In-spec point\n\u003CCircle fill=\"#ef4444\" /> // Out of spec (high)\n```", + "src/content/docs/06-design-system/index.md", + "410fb5bf4f8ef312", + { "html": 1982, "metadata": 1983 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"variscout-design-system\">VariScout Design System\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-design-system\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout Design System”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A unified design system for VariScout covering PWA and Azure App platforms.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"principles\">Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Theme-aware\u003C/strong> - Supports dark/light modes (light mode for paid tiers)\u003C/li>\n\u003Cli>\u003Cstrong>Data-focused\u003C/strong> - Colors prioritize data visibility and status communication\u003C/li>\n\u003Cli>\u003Cstrong>Consistent semantics\u003C/strong> - Same meaning for colors across platforms\u003C/li>\n\u003Cli>\u003Cstrong>Responsive\u003C/strong> - Adapts to screen size without losing functionality\u003C/li>\n\u003Cli>\u003Cstrong>Accessible\u003C/strong> - WCAG AA compliant contrast ratios\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"theming-pwa\">Theming (PWA)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#theming-pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theming (PWA)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA uses CSS variables for theming, enabling runtime theme switching:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Free tier\u003C/th>\u003Cth>Paid tiers (Individual/Team/Enterprise)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Dark mode\u003C/td>\u003Ctd>✓ (default)\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Light mode\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>System preference\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Company accent\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"semantic-color-classes\">Semantic Color Classes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#semantic-color-classes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Semantic Color Classes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Components use semantic Tailwind classes that adapt to the active theme:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Semantic Class\u003C/th>\u003Cth>Dark Mode\u003C/th>\u003Cth>Light Mode\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface\u003C/code>\u003C/td>\u003Ctd>slate-900\u003C/td>\u003Ctd>slate-50\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface-secondary\u003C/code>\u003C/td>\u003Ctd>slate-800\u003C/td>\u003Ctd>slate-100\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">text-content\u003C/code>\u003C/td>\u003Ctd>slate-200\u003C/td>\u003Ctd>slate-900\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">text-content-secondary\u003C/code>\u003C/td>\u003Ctd>slate-400\u003C/td>\u003Ctd>slate-600\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">border-edge\u003C/code>\u003C/td>\u003Ctd>slate-700\u003C/td>\u003Ctd>slate-200\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"./foundations/colors.md\">Colors\u003C/a> for the complete mapping.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"quick-reference\">Quick Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#quick-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"foundations\">Foundations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#foundations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Foundations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./foundations/colors.md\">Colors\u003C/a> - Color palette and semantic usage\u003C/li>\n\u003Cli>\u003Ca href=\"./foundations/typography.md\">Typography\u003C/a> - Fonts, sizes, weights\u003C/li>\n\u003Cli>\u003Ca href=\"./foundations/spacing.md\">Spacing\u003C/a> - Spacing scale and units\u003C/li>\n\u003Cli>\u003Ca href=\"./foundations/accessibility.md\">Accessibility\u003C/a> - WCAG AA guidelines, keyboard navigation, screen readers\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"charts\">Charts\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./charts/overview.md\">Overview\u003C/a> - Chart styling principles\u003C/li>\n\u003Cli>\u003Ca href=\"./charts/colors.md\">Colors\u003C/a> - Data visualization palette\u003C/li>\n\u003Cli>\u003Ca href=\"./charts/responsive.md\">Responsive\u003C/a> - Breakpoints and scaling\u003C/li>\n\u003Cli>\u003Ca href=\"./charts/hooks.md\">Hooks\u003C/a> - Chart hooks (useChartTheme, useChartScale)\u003C/li>\n\u003Cli>\u003Ca href=\"./charts/ichart.md\">I-Chart\u003C/a> - Individuals control chart design\u003C/li>\n\u003Cli>\u003Ca href=\"./charts/boxplot.md\">Boxplot\u003C/a> - Boxplot and violin mode design\u003C/li>\n\u003Cli>\u003Ca href=\"./charts/pareto.md\">Pareto\u003C/a> - Pareto chart design\u003C/li>\n\u003Cli>\u003Ca href=\"./charts/capability.md\">Capability\u003C/a> - Capability histogram design\u003C/li>\n\u003Cli>\u003Ca href=\"./charts/probability-plot.md\">Probability Plot\u003C/a> - Probability plot design\u003C/li>\n\u003Cli>\u003Ca href=\"./charts/performance-mode.md\">Performance Mode\u003C/a> - Multi-channel chart design\u003C/li>\n\u003Cli>\u003Ca href=\"./charts/shared-components.md\">Shared Components\u003C/a> - ChartSourceBar, EditableChartTitle, etc.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"components\">Components\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Components”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./components/buttons.md\">Buttons\u003C/a> - Button variants\u003C/li>\n\u003Cli>\u003Ca href=\"./components/cards.md\">Cards\u003C/a> - Cards and panels\u003C/li>\n\u003Cli>\u003Ca href=\"./components/modals.md\">Modals\u003C/a> - Modal patterns\u003C/li>\n\u003Cli>\u003Ca href=\"./components/forms.md\">Forms\u003C/a> - Form elements\u003C/li>\n\u003Cli>\u003Ca href=\"./components/variation-funnel.md\">VariationBar\u003C/a> - Variation scope progress bar\u003C/li>\n\u003Cli>\u003Ca href=\"./components/what-if-simulator.md\">What-If Simulator\u003C/a> - Process improvement exploration\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"patterns\">Patterns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./patterns/layout.md\">Layout\u003C/a> - Page layouts\u003C/li>\n\u003Cli>\u003Ca href=\"./patterns/feedback.md\">Feedback\u003C/a> - Status and loading states\u003C/li>\n\u003Cli>\u003Ca href=\"./patterns/navigation.md\">Navigation\u003C/a> - Navigation patterns and breadcrumbs\u003C/li>\n\u003Cli>\u003Ca href=\"./patterns/interactions.md\">Interactions\u003C/a> - Interaction patterns (inline edit, grids, selection cards)\u003C/li>\n\u003Cli>\u003Ca href=\"./patterns/panels-and-drawers.md\">Panels and Drawers\u003C/a> - Panel decision framework, drawer types, z-index scale\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usage\">Usage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-tailwind-with-semantic-classes\">PWA (Tailwind with Semantic Classes)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-tailwind-with-semantic-classes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA (Tailwind with Semantic Classes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Use semantic classes for theme-aware styling\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-surface border border-edge rounded-lg p-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content font-semibold\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Title\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Description\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Primary button (brand colors don't change with theme)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-blue-600 hover:bg-blue-700 text-white rounded-lg px-4 py-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Primary Button\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Use semantic classes for theme-aware styling\u003Cdiv className="bg-surface border border-edge rounded-lg p-4"> \u003Ch2 className="text-content font-semibold">Title\u003C/h2> \u003Cp className="text-content-secondary">Description\u003C/p>\u003C/div>// Primary button (brand colors don't change with theme)\u003Cbutton className="bg-blue-600 hover:bg-blue-700 text-white rounded-lg px-4 py-2"> Primary Button\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"charts-visx\">Charts (Visx)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#charts-visx\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Charts (Visx)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useChartTheme } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chrome colors adapt to theme\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">labelPrimary\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Axis Label\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Data colors remain universal (pass/fail/warning)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Circle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#22c55e\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// In-spec point\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Circle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ef4444\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Out of spec (high)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useChartTheme } from '@variscout/charts';// Chrome colors adapt to themeconst { chrome } = useChartTheme();\u003Ctext fill={chrome.labelPrimary}>Axis Label\u003C/text>// Data colors remain universal (pass/fail/warning)\u003CCircle fill="#22c55e" /> // In-spec point\u003CCircle fill="#ef4444" /> // Out of spec (high)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>", + { + "headings": 1984, + "localImagePaths": 2016, + "remoteImagePaths": 2017, + "frontmatter": 2018, + "imagePaths": 2019 + }, + [1985, 1987, 1990, 1993, 1996, 1997, 2000, 2001, 2004, 2007, 2010, 2013], + { "depth": 30, "slug": 1986, "text": 1974 }, + "variscout-design-system", + { "depth": 33, "slug": 1988, "text": 1989 }, + "principles", + "Principles", + { "depth": 33, "slug": 1991, "text": 1992 }, + "theming-pwa", + "Theming (PWA)", + { "depth": 79, "slug": 1994, "text": 1995 }, + "semantic-color-classes", + "Semantic Color Classes", + { "depth": 33, "slug": 1897, "text": 1898 }, + { "depth": 79, "slug": 1998, "text": 1999 }, + "foundations", + "Foundations", + { "depth": 79, "slug": 1272, "text": 1273 }, + { "depth": 79, "slug": 2002, "text": 2003 }, + "components", + "Components", + { "depth": 79, "slug": 2005, "text": 2006 }, + "patterns", + "Patterns", + { "depth": 33, "slug": 2008, "text": 2009 }, + "usage", + "Usage", + { "depth": 79, "slug": 2011, "text": 2012 }, + "pwa-tailwind-with-semantic-classes", + "PWA (Tailwind with Semantic Classes)", + { "depth": 79, "slug": 2014, "text": 2015 }, + "charts-visx", + "Charts (Visx)", + [], + [], + { "title": 1974 }, + [], + "08-products/feature-parity", + { "id": 2020, "data": 2022, "body": 2027, "filePath": 2028, "digest": 2029, "rendered": 2030 }, + { + "title": 2023, + "editUrl": 16, + "head": 2024, + "template": 18, + "sidebar": 2025, + "pagefind": 16, + "draft": 20 + }, + "Feature Parity Matrix", + [], + { "hidden": 20, "attrs": 2026 }, + {}, + "# Feature Parity Matrix\n\nComplete feature availability across VariScout platforms.\n\n---\n\n## Platform Overview\n\n| Platform | Primary Use | Status | Distribution | Price |\n| ------------------ | --------------------------------- | ----------- | ----------------- | ---------- |\n| **Azure Standard** | Full analysis, local file storage | **PRIMARY** | Azure Marketplace | €99/month |\n| **Azure Team** | + Teams, cloud storage, mobile | **PRIMARY** | Azure Marketplace | €299/month |\n| **PWA** | Training & education | Production | Direct URL | FREE |\n\n> Per [ADR-007](../07-decisions/adr-007-azure-marketplace-distribution.md), Azure App is the only paid product with a two-plan model: Standard (€99/month) and Team (€299/month). Both are Azure Marketplace Managed Applications. PWA is free forever. See [ADR-016](../07-decisions/adr-016-teams-integration.md) for Teams integration design.\n\n---\n\n## Core Analysis Features\n\n| Feature | Azure Standard | Azure Team | PWA (Free) |\n| ---------------------------- | :------------: | :--------: | :--------: |\n| **I-Chart** | ✓ | ✓ | ✓ |\n| **Boxplot** | ✓ | ✓ | ✓ |\n| **Pareto** | ✓ | ✓ | ✓ |\n| **Capability Histogram** | ✓ | ✓ | ✓ |\n| **Probability Plot** | ✓ | ✓ | ✓ |\n| **Violin Mode** | ✓ | ✓ | ✓ |\n| **Boxplot category sorting** | ✓ | ✓ | ✓ |\n| **Performance Mode** | ✓ | ✓ | - |\n\n> PWA includes core analysis charts plus Green Belt tools for training. Performance Mode requires the Azure App (either plan).\n\n---\n\n## Statistical Calculations\n\nAll platforms share `@variscout/core` and produce **identical results** for the features they support.\n\n| Calculation | Azure Standard | Azure Team | PWA | Formula Reference |\n| --------------------- | :------------: | :--------: | :-: | ------------------- |\n| Mean, Median, Std Dev | ✓ | ✓ | ✓ | Standard |\n| UCL/LCL (3σ) | ✓ | ✓ | ✓ | x̄ ± 3σ |\n| Cp, Cpk | ✓ | ✓ | ✓ | (USL-LSL)/6σ |\n| η² (Eta-squared) | ✓ | ✓ | ✓ | SS_between/SS_total |\n| F-statistic, p-value | ✓ | ✓ | ✓ | ANOVA |\n| Nelson Rule 2 | ✓ | ✓ | ✓ | 9-point run |\n\n---\n\n## Navigation & Interaction\n\n| Feature | Azure Standard | Azure Team | PWA (Free) | Notes |\n| --------------------------------- | :------------: | :--------: | :--------: | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| **Drill-down** | ✓ | ✓ | ✓ | |\n| **Linked filtering** | ✓ | ✓ | ✓ | |\n| **Breadcrumb navigation** | ✓ | ✓ | ✓ | |\n| **Multi-select filters** | ✓ | ✓ | ✓ | |\n| **Observations & Findings** | ✓ | ✓ | ✓ | Pin filter states + chart observations as findings; status tracking, comments, board view; Azure adds: persistence, popout window |\n| **What-If Simulator** | ✓ | ✓ | ✓ | |\n| **Keyboard navigation** | ✓ | ✓ | ✓ | |\n| **Copy chart to clipboard** | ✓ | ✓ | ✓ | Includes filter context bar when active |\n| **Filter context on charts** | ✓ | ✓ | ✓ | Shows active filters inside chart cards; toggle in Settings |\n| **Editable chart titles** | ✓ | ✓ | ✓ | |\n| **Selection panel** | ✓ | ✓ | ✓ | Minitab-style point brushing |\n| **Create Factor** | ✓ | ✓ | ✓ | From point selection |\n| **Focus mode (fullscreen chart)** | ✓ | ✓ | ✓ | |\n| **Presentation Mode** | ✓ | ✓ | - | Full-screen grid overview + focused chart view |\n| **Median in Stats Panel** | ✓ | ✓ | ✓ | Always shown alongside Mean |\n| **Spec editing (Stats)** | ✓ | ✓ | ✓ | `onEditSpecs` callback; pencil link opens SpecEditor popover |\n| **Chart color highlights** | ✓ | ✓ | ✓ | Desktop: right-click context menu. Mobile: tap → action sheet. Red/amber/green category markers (Boxplot, Pareto). I-Chart: desktop only. |\n\n---\n\n## Data Handling\n\n| Feature | Azure Standard | Azure Team | PWA (Free) | Notes |\n| --------------------------------- | :------------: | :--------: | :--------: | ------------------------------------------------------------- |\n| **CSV upload** | ✓ | ✓ | - | Azure App only |\n| **Excel upload** | ✓ | ✓ | - | Azure App only |\n| **Paste data** | ✓ | ✓ | ✓ | |\n| **Sample datasets** | ✓ | ✓ | ✓ | PWA pre-loaded with cases |\n| **Column mapping** | ✓ | ✓ | ✓ | Data-rich cards with type badges, sample values, data preview |\n| **Spec entry at column mapping** | ✓ | ✓ | ✓ | Collapsible SpecsSection in ColumnMapping |\n| **Column data preview** | ✓ | ✓ | ✓ | Collapsible mini-table showing first 5 rows |\n| **Column renaming at setup** | ✓ | ✓ | ✓ | Pencil icon on column cards → `columnAliases` |\n| **Time factor extraction** | ✓ | ✓ | ✓ | Extract year/month/weekday/hour from date columns |\n| **Inline data editing** | ✓ | ✓ | ✓ | Edit cells, add/delete rows, batch apply |\n| **Add data during analysis** | ✓ | ✓ | - | Paste/upload/manual append with auto-detection |\n| **Manual entry** | ✓ | ✓ | ✓ | |\n| **Data validation** | ✓ | ✓ | ✓ | |\n| **Row limit** | 100,000 | 100,000 | 50,000 | Configurable via `DataIngestionConfig` |\n| **Max factors** | 6 | 6 | 3 | Configurable via `maxFactors` prop |\n| **Factor management in analysis** | ✓ | ✓ | ✓ | Both: ColumnMapping re-edit via \"Factors\" button in nav bar |\n\n---\n\n## Persistence & Storage\n\n| Feature | Azure Standard | Azure Team | PWA (Free) | Notes |\n| ---------------------- | :----------------------------------: | :---------------------------------: | :--------: | -------------------------------------------- |\n| **Local storage** | IndexedDB | IndexedDB | - | PWA is session-only |\n| **File storage** | Local files (File System Access API) | Local files + OneDrive + SharePoint | - | Team adds cloud sync |\n| **Channel storage** | - | SharePoint (per channel) | - | Team plan only |\n| **Offline support** | Cached | Cached | ✓ | Azure caches for offline |\n| **Analysis save/load** | ✓ | ✓ | - | PWA is session-only |\n| **Export CSV** | ✓ | ✓ | ✓ | |\n| **Export JSON** | ✓ | ✓ | - | Azure App only |\n| **Screenshot export** | ✓ | ✓ | ✓ | |\n| **Sync notifications** | - | ✓ | - | Toast feedback for sync status, errors, auth |\n\n---\n\n## Teams Integration\n\n| Feature | Azure Standard | Azure Team | PWA (Free) | Notes |\n| ------------------------------------- | :------------: | :--------: | :--------: | ----------------------------------------------------------------- |\n| **Teams channel tab** | - | ✓ | - | Shared analysis in team channels |\n| **Teams personal tab** | - | ✓ | - | Personal analysis within Teams |\n| **Teams SSO** | - | ✓ | - | On-Behalf-Of token exchange |\n| **Channel file storage (SharePoint)** | - | ✓ | - | .vrs files in channel document library |\n| **Photo evidence in findings** | - | ✓ | - | Teams SDK `media.selectMedia()` + HTML5 fallback; channel storage |\n| **Deep links to charts** | - | ✓ | - | Share chart URLs via Teams chat |\n| **Adaptive Cards sharing** | - | Planned | - | Share findings/charts as interactive cards |\n| **Teams mobile access** | - | ✓ | - | Full analysis via Teams mobile app |\n| **Phone-responsive carousel** | - | ✓ | - | Responsive mobile layout within Editor |\n\n> See [ADR-016](../07-decisions/adr-016-teams-integration.md) for full Teams integration technical design.\n\n---\n\n## Authentication & Security\n\n| Feature | Azure Standard | Azure Team | PWA (Free) | Notes |\n| --------------------------- | :------------: | :------------------------------------------: | :--------: | ---------------------------------------------- |\n| **Microsoft SSO** | ✓ | ✓ | - | EasyAuth redirect (Standard), Teams SSO (Team) |\n| **Azure AD / Entra ID** | ✓ | ✓ | - | |\n| **Data in customer tenant** | ✓ | ✓ | N/A | PWA is local only |\n| **No data transmission** | ✓ | ✓ | ✓ | All client-side |\n| **Permissions scope** | User.Read | + Files.ReadWrite.All, Channel.ReadBasic.All | - | Team requires admin consent |\n| **Admin consent required** | - | ✓ | - | One-time tenant admin approval |\n\n---\n\n## Theming & Customization\n\n| Feature | Azure Standard | Azure Team | PWA (Free) | Notes |\n| ------------------------ | :------------: | :--------: | :--------: | -------------------------------------------------------------------------------- |\n| **Dark/Light theme** | ✓ | ✓ | - | PWA: dark only; Azure: full dark/light switching |\n| **System theme follow** | ✓ | ✓ | - | PWA: dark only; Azure: follows system preference |\n| **Company accent color** | ✓ | ✓ | - | Azure App only |\n| **Chart font scale** | ✓ | ✓ | ✓ | Compact / Normal / Large presets in both apps |\n| **Settings panel** | ✓ | ✓ | ✓ | PWA: display toggles + chart text size; Azure: full (theme, accent, all toggles) |\n| **Branding removal** | ✓ | ✓ | - | Azure App only |\n\n---\n\n## Learning & Help\n\n| Feature | Azure Standard | Azure Team | PWA (Free) | Notes |\n| ------------------------ | :------------: | :--------: | :--------: | --------------- |\n| **Help tooltips** | ✓ | ✓ | ✓ | |\n| **Glossary integration** | ✓ | ✓ | ✓ | |\n| **\"Learn more\" links** | ✓ | ✓ | ✓ | Link to website |\n| **Sample case studies** | ✓ | ✓ | ✓ | PWA pre-loaded |\n\n---\n\n## Licensing & Pricing\n\n| Aspect | Azure Standard | Azure Team | PWA (Free) |\n| ----------------- | ------------------------------------ | --------------------------------------------- | --------------------------------------------------------- |\n| **Distribution** | Azure Marketplace | Azure Marketplace | Direct URL |\n| **Pricing** | €99/month | €299/month | FREE (forever) |\n| **Billing** | Monthly (Managed Application) | Monthly (Managed Application) | N/A |\n| **Users** | Unlimited (per-deployment) | Unlimited (per-deployment) | N/A |\n| **Features** | All analysis features | All analysis + Teams + cloud storage + mobile | Core analysis + Green Belt (no Performance Mode, no save) |\n| **Auth** | EasyAuth / Entra (User.Read) | EasyAuth + Teams SSO (+ Files, Channels) | None |\n| **Storage** | Local files (File System Access API) | + OneDrive + SharePoint channels | Session-only |\n| **Admin consent** | None | Required (one-time) | N/A |\n\n---\n\n## Platform-Specific Features\n\n### Azure Standard Only (vs PWA)\n\n- Performance Mode (multi-channel Cpk analysis)\n- File upload (CSV/Excel)\n- Save/persistence (local files via File System Access API, IndexedDB fallback)\n- EasyAuth authentication flow\n- Company accent color / branding removal\n- ARM template deployment (Managed Application)\n- Add data during analysis (paste/upload append with row/column auto-detection)\n- Presentation mode (full-screen chart overview with focused navigation)\n\n### Azure Team Only (vs Standard)\n\n- OneDrive personal file sync\n- SharePoint channel file storage\n- Teams channel tab and personal tab\n- Teams SSO (On-Behalf-Of token exchange)\n- Phone-responsive carousel for gemba investigations (responsive layout within Editor)\n- Photo evidence capture in findings (camera + channel storage)\n- Adaptive Cards sharing (Planned)\n- Teams mobile access\n- Sync notifications (toast feedback for cloud operations)\n\n### PWA Only\n\n- Free forever (training & education)\n- Pre-loaded case study datasets\n- Service Worker offline caching\n\n---\n\n## Planned Features (Roadmap)\n\n| Feature | Target Platform | Status |\n| -------------- | --------------- | ------- |\n| Adaptive Cards | Azure Team | Planned |\n\n---\n\n## See Also\n\n- [Products Overview](index.md)\n- [Azure App](azure/index.md)\n- [PWA (Free Training Tool)](pwa/index.md)\n- [ADR-007: Distribution Strategy](../07-decisions/adr-007-azure-marketplace-distribution.md)\n- [ADR-016: Teams Integration](../07-decisions/adr-016-teams-integration.md)", + "src/content/docs/08-products/feature-parity.md", + "3d77ad603894d7d1", + { "html": 2031, "metadata": 2032 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"feature-parity-matrix\">Feature Parity Matrix\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#feature-parity-matrix\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Parity Matrix”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Complete feature availability across VariScout platforms.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-overview\">Platform Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Overview”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Primary Use\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Distribution\u003C/th>\u003Cth>Price\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Azure Standard\u003C/strong>\u003C/td>\u003Ctd>Full analysis, local file storage\u003C/td>\u003Ctd>\u003Cstrong>PRIMARY\u003C/strong>\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>€99/month\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Azure Team\u003C/strong>\u003C/td>\u003Ctd>+ Teams, cloud storage, mobile\u003C/td>\u003Ctd>\u003Cstrong>PRIMARY\u003C/strong>\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>€299/month\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>PWA\u003C/strong>\u003C/td>\u003Ctd>Training & education\u003C/td>\u003Ctd>Production\u003C/td>\u003Ctd>Direct URL\u003C/td>\u003Ctd>FREE\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>Per \u003Ca href=\"../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a>, Azure App is the only paid product with a two-plan model: Standard (€99/month) and Team (€299/month). Both are Azure Marketplace Managed Applications. PWA is free forever. See \u003Ca href=\"../07-decisions/adr-016-teams-integration.md\">ADR-016\u003C/a> for Teams integration design.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-analysis-features\">Core Analysis Features\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-analysis-features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Analysis Features”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth align=\"center\">Azure Standard\u003C/th>\u003Cth align=\"center\">Azure Team\u003C/th>\u003Cth align=\"center\">PWA (Free)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>I-Chart\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Boxplot\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pareto\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Capability Histogram\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Probability Plot\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Violin Mode\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Boxplot category sorting\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Performance Mode\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>PWA includes core analysis charts plus Green Belt tools for training. Performance Mode requires the Azure App (either plan).\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"statistical-calculations\">Statistical Calculations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#statistical-calculations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Statistical Calculations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All platforms share \u003Ccode dir=\"auto\">@variscout/core\u003C/code> and produce \u003Cstrong>identical results\u003C/strong> for the features they support.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Calculation\u003C/th>\u003Cth align=\"center\">Azure Standard\u003C/th>\u003Cth align=\"center\">Azure Team\u003C/th>\u003Cth align=\"center\">PWA\u003C/th>\u003Cth>Formula Reference\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Mean, Median, Std Dev\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Standard\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UCL/LCL (3σ)\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>x̄ ± 3σ\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cp, Cpk\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>(USL-LSL)/6σ\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>η² (Eta-squared)\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>SS_between/SS_total\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>F-statistic, p-value\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>ANOVA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Nelson Rule 2\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>9-point run\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"navigation--interaction\">Navigation & Interaction\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#navigation--interaction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Navigation & Interaction”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth align=\"center\">Azure Standard\u003C/th>\u003Cth align=\"center\">Azure Team\u003C/th>\u003Cth align=\"center\">PWA (Free)\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Drill-down\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Linked filtering\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Breadcrumb navigation\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Multi-select filters\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Observations & Findings\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Pin filter states + chart observations as findings; status tracking, comments, board view; Azure adds: persistence, popout window\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>What-If Simulator\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Keyboard navigation\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Copy chart to clipboard\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Includes filter context bar when active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Filter context on charts\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Shows active filters inside chart cards; toggle in Settings\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Editable chart titles\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Selection panel\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Minitab-style point brushing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Create Factor\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>From point selection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Focus mode (fullscreen chart)\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Presentation Mode\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Full-screen grid overview + focused chart view\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Median in Stats Panel\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Always shown alongside Mean\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Spec editing (Stats)\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">onEditSpecs\u003C/code> callback; pencil link opens SpecEditor popover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Chart color highlights\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Desktop: right-click context menu. Mobile: tap → action sheet. Red/amber/green category markers (Boxplot, Pareto). I-Chart: desktop only.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-handling\">Data Handling\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Handling”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth align=\"center\">Azure Standard\u003C/th>\u003Cth align=\"center\">Azure Team\u003C/th>\u003Cth align=\"center\">PWA (Free)\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>CSV upload\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Azure App only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Excel upload\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Azure App only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Paste data\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Sample datasets\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>PWA pre-loaded with cases\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Column mapping\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Data-rich cards with type badges, sample values, data preview\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Spec entry at column mapping\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Collapsible SpecsSection in ColumnMapping\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Column data preview\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Collapsible mini-table showing first 5 rows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Column renaming at setup\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Pencil icon on column cards → \u003Ccode dir=\"auto\">columnAliases\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Time factor extraction\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Extract year/month/weekday/hour from date columns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Inline data editing\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Edit cells, add/delete rows, batch apply\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Add data during analysis\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Paste/upload/manual append with auto-detection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Manual entry\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Data validation\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Row limit\u003C/strong>\u003C/td>\u003Ctd align=\"center\">100,000\u003C/td>\u003Ctd align=\"center\">100,000\u003C/td>\u003Ctd align=\"center\">50,000\u003C/td>\u003Ctd>Configurable via \u003Ccode dir=\"auto\">DataIngestionConfig\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Max factors\u003C/strong>\u003C/td>\u003Ctd align=\"center\">6\u003C/td>\u003Ctd align=\"center\">6\u003C/td>\u003Ctd align=\"center\">3\u003C/td>\u003Ctd>Configurable via \u003Ccode dir=\"auto\">maxFactors\u003C/code> prop\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Factor management in analysis\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Both: ColumnMapping re-edit via “Factors” button in nav bar\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persistence--storage\">Persistence & Storage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persistence--storage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persistence & Storage”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth align=\"center\">Azure Standard\u003C/th>\u003Cth align=\"center\">Azure Team\u003C/th>\u003Cth align=\"center\">PWA (Free)\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Local storage\u003C/strong>\u003C/td>\u003Ctd align=\"center\">IndexedDB\u003C/td>\u003Ctd align=\"center\">IndexedDB\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>PWA is session-only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>File storage\u003C/strong>\u003C/td>\u003Ctd align=\"center\">Local files (File System Access API)\u003C/td>\u003Ctd align=\"center\">Local files + OneDrive + SharePoint\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Team adds cloud sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Channel storage\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">SharePoint (per channel)\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Team plan only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Offline support\u003C/strong>\u003C/td>\u003Ctd align=\"center\">Cached\u003C/td>\u003Ctd align=\"center\">Cached\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Azure caches for offline\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Analysis save/load\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>PWA is session-only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Export CSV\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Export JSON\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Azure App only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Screenshot export\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Sync notifications\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Toast feedback for sync status, errors, auth\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teams-integration\">Teams Integration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teams-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teams Integration”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth align=\"center\">Azure Standard\u003C/th>\u003Cth align=\"center\">Azure Team\u003C/th>\u003Cth align=\"center\">PWA (Free)\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Teams channel tab\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Shared analysis in team channels\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Teams personal tab\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Personal analysis within Teams\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Teams SSO\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>On-Behalf-Of token exchange\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Channel file storage (SharePoint)\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>.vrs files in channel document library\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Photo evidence in findings\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Teams SDK \u003Ccode dir=\"auto\">media.selectMedia()\u003C/code> + HTML5 fallback; channel storage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Deep links to charts\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Share chart URLs via Teams chat\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Adaptive Cards sharing\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">Planned\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Share findings/charts as interactive cards\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Teams mobile access\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Full analysis via Teams mobile app\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Phone-responsive carousel\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Responsive mobile layout within Editor\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>See \u003Ca href=\"../07-decisions/adr-016-teams-integration.md\">ADR-016\u003C/a> for full Teams integration technical design.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"authentication--security\">Authentication & Security\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#authentication--security\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Authentication & Security”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth align=\"center\">Azure Standard\u003C/th>\u003Cth align=\"center\">Azure Team\u003C/th>\u003Cth align=\"center\">PWA (Free)\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Microsoft SSO\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>EasyAuth redirect (Standard), Teams SSO (Team)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Azure AD / Entra ID\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Data in customer tenant\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">N/A\u003C/td>\u003Ctd>PWA is local only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>No data transmission\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>All client-side\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Permissions scope\u003C/strong>\u003C/td>\u003Ctd align=\"center\">User.Read\u003C/td>\u003Ctd align=\"center\">+ Files.ReadWrite.All, Channel.ReadBasic.All\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Team requires admin consent\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Admin consent required\u003C/strong>\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>One-time tenant admin approval\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"theming--customization\">Theming & Customization\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#theming--customization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theming & Customization”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth align=\"center\">Azure Standard\u003C/th>\u003Cth align=\"center\">Azure Team\u003C/th>\u003Cth align=\"center\">PWA (Free)\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Dark/Light theme\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>PWA: dark only; Azure: full dark/light switching\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>System theme follow\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>PWA: dark only; Azure: follows system preference\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Company accent color\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Azure App only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Chart font scale\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Compact / Normal / Large presets in both apps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Settings panel\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>PWA: display toggles + chart text size; Azure: full (theme, accent, all toggles)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Branding removal\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd>Azure App only\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"learning--help\">Learning & Help\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#learning--help\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Learning & Help”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth align=\"center\">Azure Standard\u003C/th>\u003Cth align=\"center\">Azure Team\u003C/th>\u003Cth align=\"center\">PWA (Free)\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Help tooltips\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Glossary integration\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>“Learn more” links\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Link to website\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Sample case studies\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>PWA pre-loaded\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"licensing--pricing\">Licensing & Pricing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#licensing--pricing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Licensing & Pricing”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Azure Standard\u003C/th>\u003Cth>Azure Team\u003C/th>\u003Cth>PWA (Free)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Distribution\u003C/strong>\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>Direct URL\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pricing\u003C/strong>\u003C/td>\u003Ctd>€99/month\u003C/td>\u003Ctd>€299/month\u003C/td>\u003Ctd>FREE (forever)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Billing\u003C/strong>\u003C/td>\u003Ctd>Monthly (Managed Application)\u003C/td>\u003Ctd>Monthly (Managed Application)\u003C/td>\u003Ctd>N/A\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Users\u003C/strong>\u003C/td>\u003Ctd>Unlimited (per-deployment)\u003C/td>\u003Ctd>Unlimited (per-deployment)\u003C/td>\u003Ctd>N/A\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Features\u003C/strong>\u003C/td>\u003Ctd>All analysis features\u003C/td>\u003Ctd>All analysis + Teams + cloud storage + mobile\u003C/td>\u003Ctd>Core analysis + Green Belt (no Performance Mode, no save)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Auth\u003C/strong>\u003C/td>\u003Ctd>EasyAuth / Entra (User.Read)\u003C/td>\u003Ctd>EasyAuth + Teams SSO (+ Files, Channels)\u003C/td>\u003Ctd>None\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Storage\u003C/strong>\u003C/td>\u003Ctd>Local files (File System Access API)\u003C/td>\u003Ctd>+ OneDrive + SharePoint channels\u003C/td>\u003Ctd>Session-only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Admin consent\u003C/strong>\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>Required (one-time)\u003C/td>\u003Ctd>N/A\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-specific-features\">Platform-Specific Features\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-specific-features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform-Specific Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-standard-only-vs-pwa\">Azure Standard Only (vs PWA)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-standard-only-vs-pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Standard Only (vs PWA)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Performance Mode (multi-channel Cpk analysis)\u003C/li>\n\u003Cli>File upload (CSV/Excel)\u003C/li>\n\u003Cli>Save/persistence (local files via File System Access API, IndexedDB fallback)\u003C/li>\n\u003Cli>EasyAuth authentication flow\u003C/li>\n\u003Cli>Company accent color / branding removal\u003C/li>\n\u003Cli>ARM template deployment (Managed Application)\u003C/li>\n\u003Cli>Add data during analysis (paste/upload append with row/column auto-detection)\u003C/li>\n\u003Cli>Presentation mode (full-screen chart overview with focused navigation)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-team-only-vs-standard\">Azure Team Only (vs Standard)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-team-only-vs-standard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Team Only (vs Standard)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>OneDrive personal file sync\u003C/li>\n\u003Cli>SharePoint channel file storage\u003C/li>\n\u003Cli>Teams channel tab and personal tab\u003C/li>\n\u003Cli>Teams SSO (On-Behalf-Of token exchange)\u003C/li>\n\u003Cli>Phone-responsive carousel for gemba investigations (responsive layout within Editor)\u003C/li>\n\u003Cli>Photo evidence capture in findings (camera + channel storage)\u003C/li>\n\u003Cli>Adaptive Cards sharing (Planned)\u003C/li>\n\u003Cli>Teams mobile access\u003C/li>\n\u003Cli>Sync notifications (toast feedback for cloud operations)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-only\">PWA Only\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA Only”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Free forever (training & education)\u003C/li>\n\u003Cli>Pre-loaded case study datasets\u003C/li>\n\u003Cli>Service Worker offline caching\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"planned-features-roadmap\">Planned Features (Roadmap)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#planned-features-roadmap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Planned Features (Roadmap)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Target Platform\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Adaptive Cards\u003C/td>\u003Ctd>Azure Team\u003C/td>\u003Ctd>Planned\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Products Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"azure/index.md\">Azure App\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"pwa/index.md\">PWA (Free Training Tool)\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007: Distribution Strategy\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../07-decisions/adr-016-teams-integration.md\">ADR-016: Teams Integration\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2033, + "localImagePaths": 2085, + "remoteImagePaths": 2086, + "frontmatter": 2087, + "imagePaths": 2088 + }, + [ + 2034, 2036, 2039, 2042, 2045, 2048, 2051, 2054, 2057, 2060, 2063, 2066, 2069, 2072, 2075, 2078, + 2081, 2084 + ], + { "depth": 30, "slug": 2035, "text": 2023 }, + "feature-parity-matrix", + { "depth": 33, "slug": 2037, "text": 2038 }, + "platform-overview", + "Platform Overview", + { "depth": 33, "slug": 2040, "text": 2041 }, + "core-analysis-features", + "Core Analysis Features", + { "depth": 33, "slug": 2043, "text": 2044 }, + "statistical-calculations", + "Statistical Calculations", + { "depth": 33, "slug": 2046, "text": 2047 }, + "navigation--interaction", + "Navigation & Interaction", + { "depth": 33, "slug": 2049, "text": 2050 }, + "data-handling", + "Data Handling", + { "depth": 33, "slug": 2052, "text": 2053 }, + "persistence--storage", + "Persistence & Storage", + { "depth": 33, "slug": 2055, "text": 2056 }, + "teams-integration", + "Teams Integration", + { "depth": 33, "slug": 2058, "text": 2059 }, + "authentication--security", + "Authentication & Security", + { "depth": 33, "slug": 2061, "text": 2062 }, + "theming--customization", + "Theming & Customization", + { "depth": 33, "slug": 2064, "text": 2065 }, + "learning--help", + "Learning & Help", + { "depth": 33, "slug": 2067, "text": 2068 }, + "licensing--pricing", + "Licensing & Pricing", + { "depth": 33, "slug": 2070, "text": 2071 }, + "platform-specific-features", + "Platform-Specific Features", + { "depth": 79, "slug": 2073, "text": 2074 }, + "azure-standard-only-vs-pwa", + "Azure Standard Only (vs PWA)", + { "depth": 79, "slug": 2076, "text": 2077 }, + "azure-team-only-vs-standard", + "Azure Team Only (vs Standard)", + { "depth": 79, "slug": 2079, "text": 2080 }, + "pwa-only", + "PWA Only", + { "depth": 33, "slug": 2082, "text": 2083 }, + "planned-features-roadmap", + "Planned Features (Roadmap)", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2023 }, + [], + "08-products", + { "id": 2089, "data": 2091, "body": 2096, "filePath": 2097, "digest": 2098, "rendered": 2099 }, + { + "title": 2092, + "editUrl": 16, + "head": 2093, + "template": 18, + "sidebar": 2094, + "pagefind": 16, + "draft": 20 + }, + "Products", + [], + { "hidden": 20, "attrs": 2095 }, + {}, + "# Products\n\nVariScout is a 2-product model: **free PWA** for learning and training, **paid Azure App** for teams.\n\n> **GTM:** \"Try it free at variscout.com. When you're ready for your team, get it on Azure Marketplace.\"\n\n---\n\n## Distribution Hierarchy\n\nPer [ADR-007](../07-decisions/adr-007-azure-marketplace-distribution.md):\n\n```mermaid\nflowchart LR\n subgraph Paid[\"Paid Product\"]\n A1[Azure Standard\u003Cbr/>€99/month]\n A2[Azure Team\u003Cbr/>€299/month]\n end\n\n subgraph Free[\"Free Product\"]\n C[PWA\u003Cbr/>Free Training Tool]\n end\n\n C -->|\"Need file upload, save, Performance Mode\"| A1\n A1 -->|\"Need Teams, OneDrive, SharePoint, mobile\"| A2\n```\n\n## Product Matrix\n\n| Product | Status | Distribution | Use Case | Pricing |\n| ------------------------------------ | ----------- | ----------------- | -------------------------- | -------------- |\n| **[Azure Standard](azure/index.md)** | **PRIMARY** | Azure Marketplace | Full analysis, local files | €99/month |\n| **[Azure Team](azure/index.md)** | **PRIMARY** | Azure Marketplace | + Teams, OneDrive, mobile | €299/month |\n| [PWA](pwa/index.md) | Production | Direct URL | Training & education | FREE (forever) |\n| [Power BI](powerbi/index.md) | Planned | AppSource | Dashboard integration | TBD |\n| [Website](website/index.md) | Production | Public | Marketing & docs | N/A |\n\n:::tip[Getting Started]\n**Free**: Start with the [PWA](pwa/index.md) — free training tool with copy-paste input and 16 sample datasets. Upgrade to the [Azure App](azure/index.md) for file upload, save/persistence, Performance Mode, and team features.\n:::\n\n---\n\n## Distribution Strategy\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ VariScout on Azure Marketplace (PRIMARY) │\n│ │\n│ Standard Plan €99/month Full analysis, local files │\n│ Team Plan €299/month + Teams, OneDrive, mobile │\n│ Unlimited users in tenant │\n│ │\n│ Offer type: Managed Application │\n│ Billing: Microsoft (3% fee, monthly) │\n│ Data: Stays in customer's Azure tenant │\n└─────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Feature Comparison\n\n| Feature | Azure App | PWA (Free) | Power BI |\n| ---------------- | --------- | ---------- | ---------------- |\n| I-Chart | ✓ | ✓ | Planned |\n| Boxplot | ✓ | ✓ | Planned |\n| Pareto | ✓ | ✓ | Planned |\n| Capability | ✓ | ✓ | Planned |\n| Performance Mode | ✓ | - | - |\n| File Upload | ✓ | - | - |\n| Save/Persistence | ✓ | - | Power BI Service |\n| Drill-Down | ✓ | ✓ | Native |\n| Linked Filtering | ✓ | ✓ | Native |\n| Offline | Cached | ✓ | - |\n| Cloud Sync | OneDrive | - | Power BI Service |\n| SSO | Microsoft | - | Microsoft |\n\n---\n\n## Pricing (Azure App)\n\n| Plan | Price | Net Revenue | Includes |\n| -------- | ---------- | ------------------- | ---------------------------------------------- |\n| Standard | €99/month | €96.03/month (−3%) | Full analysis, file upload, save, SSO, offline |\n| Team | €299/month | €290.03/month (−3%) | + Teams, OneDrive, SharePoint, mobile, photos |\n\n| Aspect | Value |\n| ------- | -------------------------------------------------- |\n| Billing | Monthly (Microsoft handles billing, 3% fee) |\n| Model | Per-deployment (one subscription per Azure tenant) |\n\n**Standard** — all chart types, Performance Mode, Microsoft SSO, offline support, data stays in customer's Azure tenant.\n\n**Team** — everything in Standard, plus Teams integration, OneDrive/SharePoint sync, mobile access, and photo evidence.\n\n---\n\n## Architecture\n\nBoth products share the same core packages:\n\n```\n@variscout/core → Statistics, parsing, types\n@variscout/charts → Visx chart components\n@variscout/hooks → Shared React hooks\n@variscout/ui → UI utilities\n```\n\nThis ensures:\n\n- Identical statistical calculations across platforms\n- Consistent chart appearance\n- Shared methodology (Four Lenses)\n\n---\n\n## Deployment Models\n\n| Product | Deployment | Data Location | License |\n| --------- | -------------------------------------- | --------------------------- | -------------------------------- |\n| Azure App | Managed Application to customer tenant | Customer's Azure + OneDrive | Deployment config (all features) |\n| PWA | Static hosting (public) | Browser (session only) | Free forever (training) |\n| Power BI | AppSource | Power BI Service | TBD |\n\n---\n\n## Support Model\n\n| Level | Included In | Support Channel |\n| --------- | ----------- | -------------------- |\n| Community | PWA | GitHub Issues |\n| Standard | Azure App | Email (24h response) |\n\n---\n\n## See Also\n\n- [ADR-007: Azure Marketplace Distribution](../07-decisions/adr-007-azure-marketplace-distribution.md)\n- [Azure Marketplace Guide](azure/marketplace.md)", + "src/content/docs/08-products/index.md", + "6e045ca6339ba6eb", + { "html": 2100, "metadata": 2101 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"products\">Products\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#products\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Products”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is a 2-product model: \u003Cstrong>free PWA\u003C/strong> for learning and training, \u003Cstrong>paid Azure App\u003C/strong> for teams.\u003C/p>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>GTM:\u003C/strong> “Try it free at variscout.com. When you’re ready for your team, get it on Azure Marketplace.”\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"distribution-hierarchy\">Distribution Hierarchy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#distribution-hierarchy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Distribution Hierarchy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Per \u003Ca href=\"../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a>:\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n subgraph Paid[\"Paid Product\"]\n A1[Azure Standard<br/>€99/month]\n A2[Azure Team<br/>€299/month]\n end\n\n subgraph Free[\"Free Product\"]\n C[PWA<br/>Free Training Tool]\n end\n\n C -->|\"Need file upload, save, Performance Mode\"| A1\n A1 -->|\"Need Teams, OneDrive, SharePoint, mobile\"| A2\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"product-matrix\">Product Matrix\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#product-matrix\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Matrix”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Distribution\u003C/th>\u003Cth>Use Case\u003C/th>\u003Cth>Pricing\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>\u003Ca href=\"azure/index.md\">Azure Standard\u003C/a>\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>PRIMARY\u003C/strong>\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>Full analysis, local files\u003C/td>\u003Ctd>€99/month\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>\u003Ca href=\"azure/index.md\">Azure Team\u003C/a>\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>PRIMARY\u003C/strong>\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>+ Teams, OneDrive, mobile\u003C/td>\u003Ctd>€299/month\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"pwa/index.md\">PWA\u003C/a>\u003C/td>\u003Ctd>Production\u003C/td>\u003Ctd>Direct URL\u003C/td>\u003Ctd>Training & education\u003C/td>\u003Ctd>FREE (forever)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"powerbi/index.md\">Power BI\u003C/a>\u003C/td>\u003Ctd>Planned\u003C/td>\u003Ctd>AppSource\u003C/td>\u003Ctd>Dashboard integration\u003C/td>\u003Ctd>TBD\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"website/index.md\">Website\u003C/a>\u003C/td>\u003Ctd>Production\u003C/td>\u003Ctd>Public\u003C/td>\u003Ctd>Marketing & docs\u003C/td>\u003Ctd>N/A\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Caside aria-label=\"Getting Started\" class=\"starlight-aside starlight-aside--tip\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.43909 8.85483L1.44039 8.85354L4.96668 5.33815C5.30653 4.99386 5.7685 4.79662 6.2524 4.78972L6.26553 4.78963L12.9014 4.78962L13.8479 3.84308C16.9187 0.772319 20.0546 0.770617 21.4678 0.975145C21.8617 1.02914 22.2271 1.21053 22.5083 1.4917C22.7894 1.77284 22.9708 2.13821 23.0248 2.53199C23.2294 3.94517 23.2278 7.08119 20.1569 10.1521L19.2107 11.0983V17.7338L19.2106 17.7469C19.2037 18.2308 19.0067 18.6933 18.6624 19.0331L15.1456 22.5608C14.9095 22.7966 14.6137 22.964 14.29 23.0449C13.9663 23.1259 13.6267 23.1174 13.3074 23.0204C12.9881 22.9235 12.7011 22.7417 12.4771 22.4944C12.2533 22.2473 12.1006 21.9441 12.0355 21.6171L11.1783 17.3417L6.65869 12.822L4.34847 12.3589L2.38351 11.965C2.05664 11.8998 1.75272 11.747 1.50564 11.5232C1.25835 11.2992 1.07653 11.0122 0.979561 10.6929C0.882595 10.3736 0.874125 10.034 0.955057 9.7103C1.03599 9.38659 1.20328 9.09092 1.43909 8.85483ZM6.8186 10.8724L2.94619 10.096L6.32006 6.73268H10.9583L6.8186 10.8724ZM15.2219 5.21703C17.681 2.75787 20.0783 2.75376 21.1124 2.8876C21.2462 3.92172 21.2421 6.31895 18.783 8.77812L12.0728 15.4883L8.51172 11.9272L15.2219 5.21703ZM13.9042 21.0538L13.1279 17.1811L17.2676 13.0414V17.68L13.9042 21.0538Z\">\u003C/path>\u003Cpath d=\"M9.31827 18.3446C9.45046 17.8529 9.17864 17.3369 8.68945 17.1724C8.56178 17.1294 8.43145 17.1145 8.30512 17.1243C8.10513 17.1398 7.91519 17.2172 7.76181 17.3434C7.62613 17.455 7.51905 17.6048 7.45893 17.7835C6.97634 19.2186 5.77062 19.9878 4.52406 20.4029C4.08525 20.549 3.6605 20.644 3.29471 20.7053C3.35607 20.3395 3.45098 19.9148 3.59711 19.476C4.01221 18.2294 4.78141 17.0237 6.21648 16.5411C6.39528 16.481 6.54504 16.3739 6.65665 16.2382C6.85126 16.0016 6.92988 15.678 6.84417 15.3647C6.83922 15.3466 6.83373 15.3286 6.82767 15.3106C6.74106 15.053 6.55701 14.8557 6.33037 14.7459C6.10949 14.6389 5.84816 14.615 5.59715 14.6994C5.47743 14.7397 5.36103 14.7831 5.24786 14.8294C3.22626 15.6569 2.2347 17.4173 1.75357 18.8621C1.49662 19.6337 1.36993 20.3554 1.30679 20.8818C1.27505 21.1464 1.25893 21.3654 1.25072 21.5213C1.24662 21.5993 1.24448 21.6618 1.24337 21.7066L1.243 21.7226L1.24235 21.7605L1.2422 21.7771L1.24217 21.7827L1.24217 21.7856C1.24217 22.3221 1.67703 22.7579 2.2137 22.7579L2.2155 22.7579L2.22337 22.7578L2.23956 22.7577C2.25293 22.7575 2.27096 22.7572 2.29338 22.7567C2.33821 22.7555 2.40073 22.7534 2.47876 22.7493C2.63466 22.7411 2.85361 22.725 3.11822 22.6932C3.64462 22.6301 4.36636 22.5034 5.13797 22.2464C6.58274 21.7653 8.3431 20.7738 9.17063 18.7522C9.21696 18.639 9.26037 18.5226 9.30064 18.4029C9.30716 18.3835 9.31304 18.364 9.31827 18.3446Z\">\u003C/path>\u003C/svg>Getting Started\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>\u003Cstrong>Free\u003C/strong>: Start with the \u003Ca href=\"pwa/index.md\">PWA\u003C/a> — free training tool with copy-paste input and 16 sample datasets. Upgrade to the \u003Ca href=\"azure/index.md\">Azure App\u003C/a> for file upload, save/persistence, Performance Mode, and team features.\u003C/p>\u003C/div>\u003C/aside>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"distribution-strategy\">Distribution Strategy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#distribution-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Distribution Strategy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ VariScout on Azure Marketplace (PRIMARY) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Standard Plan €99/month Full analysis, local files │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Team Plan €299/month + Teams, OneDrive, mobile │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Unlimited users in tenant │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Offer type: Managed Application │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Billing: Microsoft (3% fee, monthly) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Data: Stays in customer's Azure tenant │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────┐│ VariScout on Azure Marketplace (PRIMARY) ││ ││ Standard Plan €99/month Full analysis, local files ││ Team Plan €299/month + Teams, OneDrive, mobile ││ Unlimited users in tenant ││ ││ Offer type: Managed Application ││ Billing: Microsoft (3% fee, monthly) ││ Data: Stays in customer's Azure tenant │└─────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-comparison\">Feature Comparison\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Azure App\u003C/th>\u003Cth>PWA (Free)\u003C/th>\u003Cth>Power BI\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>I-Chart\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>Planned\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>Planned\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>Planned\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>Planned\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>-\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>File Upload\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>-\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Save/Persistence\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Power BI Service\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Drill-Down\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>Native\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Linked Filtering\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>Native\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Offline\u003C/td>\u003Ctd>Cached\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>-\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cloud Sync\u003C/td>\u003Ctd>OneDrive\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Power BI Service\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SSO\u003C/td>\u003Ctd>Microsoft\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Microsoft\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pricing-azure-app\">Pricing (Azure App)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pricing-azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pricing (Azure App)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Plan\u003C/th>\u003Cth>Price\u003C/th>\u003Cth>Net Revenue\u003C/th>\u003Cth>Includes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Standard\u003C/td>\u003Ctd>€99/month\u003C/td>\u003Ctd>€96.03/month (−3%)\u003C/td>\u003Ctd>Full analysis, file upload, save, SSO, offline\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Team\u003C/td>\u003Ctd>€299/month\u003C/td>\u003Ctd>€290.03/month (−3%)\u003C/td>\u003Ctd>+ Teams, OneDrive, SharePoint, mobile, photos\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Value\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Billing\u003C/td>\u003Ctd>Monthly (Microsoft handles billing, 3% fee)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Model\u003C/td>\u003Ctd>Per-deployment (one subscription per Azure tenant)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Standard\u003C/strong> — all chart types, Performance Mode, Microsoft SSO, offline support, data stays in customer’s Azure tenant.\u003C/p>\n\u003Cp>\u003Cstrong>Team\u003C/strong> — everything in Standard, plus Teams integration, OneDrive/SharePoint sync, mobile access, and photo evidence.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"architecture\">Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both products share the same core packages:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">@variscout/core → Statistics, parsing, types\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">@variscout/charts → Visx chart components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">@variscout/hooks → Shared React hooks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">@variscout/ui → UI utilities\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"@variscout/core → Statistics, parsing, types@variscout/charts → Visx chart components@variscout/hooks → Shared React hooks@variscout/ui → UI utilities\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This ensures:\u003C/p>\n\u003Cul>\n\u003Cli>Identical statistical calculations across platforms\u003C/li>\n\u003Cli>Consistent chart appearance\u003C/li>\n\u003Cli>Shared methodology (Four Lenses)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"deployment-models\">Deployment Models\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#deployment-models\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment Models”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth>Deployment\u003C/th>\u003Cth>Data Location\u003C/th>\u003Cth>License\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Azure App\u003C/td>\u003Ctd>Managed Application to customer tenant\u003C/td>\u003Ctd>Customer’s Azure + OneDrive\u003C/td>\u003Ctd>Deployment config (all features)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PWA\u003C/td>\u003Ctd>Static hosting (public)\u003C/td>\u003Ctd>Browser (session only)\u003C/td>\u003Ctd>Free forever (training)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Power BI\u003C/td>\u003Ctd>AppSource\u003C/td>\u003Ctd>Power BI Service\u003C/td>\u003Ctd>TBD\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"support-model\">Support Model\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#support-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Support Model”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Level\u003C/th>\u003Cth>Included In\u003C/th>\u003Cth>Support Channel\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Community\u003C/td>\u003Ctd>PWA\u003C/td>\u003Ctd>GitHub Issues\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Standard\u003C/td>\u003Ctd>Azure App\u003C/td>\u003Ctd>Email (24h response)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007: Azure Marketplace Distribution\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"azure/marketplace.md\">Azure Marketplace Guide\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2102, + "localImagePaths": 2128, + "remoteImagePaths": 2129, + "frontmatter": 2130, + "imagePaths": 2131 + }, + [2103, 2105, 2108, 2111, 2114, 2117, 2120, 2121, 2124, 2127], + { "depth": 30, "slug": 2104, "text": 2092 }, + "products", + { "depth": 33, "slug": 2106, "text": 2107 }, + "distribution-hierarchy", + "Distribution Hierarchy", + { "depth": 33, "slug": 2109, "text": 2110 }, + "product-matrix", + "Product Matrix", + { "depth": 33, "slug": 2112, "text": 2113 }, + "distribution-strategy", + "Distribution Strategy", + { "depth": 33, "slug": 2115, "text": 2116 }, + "feature-comparison", + "Feature Comparison", + { "depth": 33, "slug": 2118, "text": 2119 }, + "pricing-azure-app", + "Pricing (Azure App)", + { "depth": 33, "slug": 1819, "text": 1820 }, + { "depth": 33, "slug": 2122, "text": 2123 }, + "deployment-models", + "Deployment Models", + { "depth": 33, "slug": 2125, "text": 2126 }, + "support-model", + "Support Model", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2092 }, + [], + "07-decisions/adr-001-monorepo", + { "id": 2132, "data": 2134, "body": 2139, "filePath": 2140, "digest": 2141, "rendered": 2142 }, + { + "title": 2135, + "editUrl": 16, + "head": 2136, + "template": 18, + "sidebar": 2137, + "pagefind": 16, + "draft": 20 + }, + "ADR-001: Monorepo with pnpm Workspaces", + [], + { "hidden": 20, "attrs": 2138 }, + {}, + "# ADR-001: Monorepo with pnpm Workspaces\n\n**Status**: Accepted\n\n**Date**: 2024-01-15\n\n---\n\n## Context\n\nVariScout consists of multiple applications (PWA, Azure App, Marketing Website) that share significant code including statistical calculations, chart components, and UI utilities. We needed a code organization strategy that enables sharing while maintaining clear boundaries.\n\n---\n\n## Decision\n\nUse pnpm workspaces in a monorepo structure:\n\n```\npackages/\n├── core/ # Pure logic (stats, parser, types)\n├── charts/ # React + Visx chart components\n├── data/ # Sample datasets\n├── hooks/ # Shared React hooks\n└── ui/ # Shared UI components\n\napps/\n├── pwa/ # React + Vite PWA\n├── azure/ # Azure Team App\n└── website/ # Astro marketing site\n```\n\n---\n\n## Consequences\n\n### Benefits\n\n- Single source of truth for shared code\n- Atomic commits across packages and apps\n- Simplified dependency management with `workspace:*`\n- pnpm's efficient disk usage via hard links\n\n### Trade-offs\n\n- More complex build orchestration\n- Must be careful about package boundaries\n- Git history can be harder to navigate\n\n---\n\n## See Also\n\n- [Monorepo Architecture](../05-technical/architecture/monorepo.md)", + "src/content/docs/07-decisions/adr-001-monorepo.md", + "7e40e1761716976a", + { "html": 2143, "metadata": 2144 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-001-monorepo-with-pnpm-workspaces\">ADR-001: Monorepo with pnpm Workspaces\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-001-monorepo-with-pnpm-workspaces\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-001: Monorepo with pnpm Workspaces”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Accepted\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2024-01-15\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout consists of multiple applications (PWA, Azure App, Marketing Website) that share significant code including statistical calculations, chart components, and UI utilities. We needed a code organization strategy that enables sharing while maintaining clear boundaries.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use pnpm workspaces in a monorepo structure:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">packages/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── core/ # Pure logic (stats, parser, types)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── charts/ # React + Visx chart components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── data/ # Sample datasets\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── hooks/ # Shared React hooks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── ui/ # Shared UI components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">apps/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── pwa/ # React + Vite PWA\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── azure/ # Azure Team App\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── website/ # Astro marketing site\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"packages/├── core/ # Pure logic (stats, parser, types)├── charts/ # React + Visx chart components├── data/ # Sample datasets├── hooks/ # Shared React hooks└── ui/ # Shared UI componentsapps/├── pwa/ # React + Vite PWA├── azure/ # Azure Team App└── website/ # Astro marketing site\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"benefits\">Benefits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#benefits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Benefits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Single source of truth for shared code\u003C/li>\n\u003Cli>Atomic commits across packages and apps\u003C/li>\n\u003Cli>Simplified dependency management with \u003Ccode dir=\"auto\">workspace:*\u003C/code>\u003C/li>\n\u003Cli>pnpm’s efficient disk usage via hard links\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"trade-offs\">Trade-offs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#trade-offs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Trade-offs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>More complex build orchestration\u003C/li>\n\u003Cli>Must be careful about package boundaries\u003C/li>\n\u003Cli>Git history can be harder to navigate\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../05-technical/architecture/monorepo.md\">Monorepo Architecture\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2145, + "localImagePaths": 2162, + "remoteImagePaths": 2163, + "frontmatter": 2164, + "imagePaths": 2165 + }, + [2146, 2148, 2149, 2152, 2155, 2158, 2161], + { "depth": 30, "slug": 2147, "text": 2135 }, + "adr-001-monorepo-with-pnpm-workspaces", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + "decision", + "Decision", + { "depth": 33, "slug": 2153, "text": 2154 }, + "consequences", + "Consequences", + { "depth": 79, "slug": 2156, "text": 2157 }, + "benefits", + "Benefits", + { "depth": 79, "slug": 2159, "text": 2160 }, + "trade-offs", + "Trade-offs", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2135 }, + [], + "07-decisions/adr-002-visx-charts", + { "id": 2166, "data": 2168, "body": 2173, "filePath": 2174, "digest": 2175, "rendered": 2176 }, + { + "title": 2169, + "editUrl": 16, + "head": 2170, + "template": 18, + "sidebar": 2171, + "pagefind": 16, + "draft": 20 + }, + "ADR-002: Visx for Chart Components", + [], + { "hidden": 20, "attrs": 2172 }, + {}, + "# ADR-002: Visx for Chart Components\n\n**Status**: Accepted\n\n**Date**: 2024-01-20\n\n---\n\n## Context\n\nWe needed a charting solution for statistical process control charts (I-Charts, Boxplots, Capability histograms). Options considered:\n\n1. **Chart.js**: Popular, but canvas-based limits customization\n2. **Recharts**: React-friendly but high-level API hides SVG control\n3. **D3.js**: Maximum control but verbose and imperative\n4. **Visx**: D3-powered React primitives with full SVG access\n\n---\n\n## Decision\n\nUse Visx (@visx/\\*) for all chart components. Visx provides low-level SVG primitives that compose into React components, giving us:\n\n- Full control over SVG elements for custom annotations (spec limits, zones)\n- D3 scales and utilities without D3's DOM manipulation\n- React component model with hooks\n\n---\n\n## Consequences\n\n### Benefits\n\n- Precise control over chart rendering\n- Easy to add custom elements (spec lines, shading, annotations)\n- Server-side rendering possible\n- Small bundle size (tree-shakeable)\n\n### Trade-offs\n\n- More code to write vs high-level chart libraries\n- Team needs SVG/D3 knowledge\n- No built-in chart types (must build from primitives)\n\n---\n\n## See Also\n\n- [Charts Package](../06-design-system/charts/overview.md)", + "src/content/docs/07-decisions/adr-002-visx-charts.md", + "b118b2342ba079c5", + { "html": 2177, "metadata": 2178 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-002-visx-for-chart-components\">ADR-002: Visx for Chart Components\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-002-visx-for-chart-components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-002: Visx for Chart Components”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Accepted\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2024-01-20\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>We needed a charting solution for statistical process control charts (I-Charts, Boxplots, Capability histograms). Options considered:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Chart.js\u003C/strong>: Popular, but canvas-based limits customization\u003C/li>\n\u003Cli>\u003Cstrong>Recharts\u003C/strong>: React-friendly but high-level API hides SVG control\u003C/li>\n\u003Cli>\u003Cstrong>D3.js\u003C/strong>: Maximum control but verbose and imperative\u003C/li>\n\u003Cli>\u003Cstrong>Visx\u003C/strong>: D3-powered React primitives with full SVG access\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use Visx (@visx/*) for all chart components. Visx provides low-level SVG primitives that compose into React components, giving us:\u003C/p>\n\u003Cul>\n\u003Cli>Full control over SVG elements for custom annotations (spec limits, zones)\u003C/li>\n\u003Cli>D3 scales and utilities without D3’s DOM manipulation\u003C/li>\n\u003Cli>React component model with hooks\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"benefits\">Benefits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#benefits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Benefits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Precise control over chart rendering\u003C/li>\n\u003Cli>Easy to add custom elements (spec lines, shading, annotations)\u003C/li>\n\u003Cli>Server-side rendering possible\u003C/li>\n\u003Cli>Small bundle size (tree-shakeable)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"trade-offs\">Trade-offs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#trade-offs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Trade-offs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>More code to write vs high-level chart libraries\u003C/li>\n\u003Cli>Team needs SVG/D3 knowledge\u003C/li>\n\u003Cli>No built-in chart types (must build from primitives)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../06-design-system/charts/overview.md\">Charts Package\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2179, + "localImagePaths": 2188, + "remoteImagePaths": 2189, + "frontmatter": 2190, + "imagePaths": 2191 + }, + [2180, 2182, 2183, 2184, 2185, 2186, 2187], + { "depth": 30, "slug": 2181, "text": 2169 }, + "adr-002-visx-for-chart-components", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2156, "text": 2157 }, + { "depth": 79, "slug": 2159, "text": 2160 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2169 }, + [], + "07-decisions/adr-003-indexeddb", + { "id": 2192, "data": 2194, "body": 2199, "filePath": 2200, "digest": 2201, "rendered": 2202 }, + { + "title": 2195, + "editUrl": 16, + "head": 2196, + "template": 18, + "sidebar": 2197, + "pagefind": 16, + "draft": 20 + }, + "ADR-003: IndexedDB for PWA Storage", + [], + { "hidden": 20, "attrs": 2198 }, + {}, + "# ADR-003: IndexedDB for PWA Storage\n\n**Status**: Accepted\n\n**Date**: 2024-02-01\n\n---\n\n## Context\n\nPWA needs to store user data (uploaded files, analysis results, settings) persistently in the browser. Options:\n\n1. **localStorage**: Simple but 5MB limit, synchronous, string-only\n2. **IndexedDB**: Complex API but large storage, async, structured data\n3. **Cache API**: Designed for HTTP responses, not app data\n\n---\n\n## Decision\n\nUse IndexedDB with a wrapper utility for:\n\n- Uploaded datasets (can be multi-MB)\n- Computed statistics cache\n- User preferences and settings\n\nUse localStorage only for:\n\n- Small, simple values (theme preference, last-used settings)\n\n---\n\n## Consequences\n\n### Benefits\n\n- Virtually unlimited storage (browser-managed quotas)\n- Structured data with indexes for queries\n- Async API won't block UI thread\n- Survives browser restarts\n\n### Trade-offs\n\n- Complex API requiring wrapper abstraction\n- Debugging is harder than localStorage\n- Storage can be evicted under pressure\n\n---\n\n## See Also\n\n- [PWA Storage](../08-products/pwa/storage.md)", + "src/content/docs/07-decisions/adr-003-indexeddb.md", + "95e7d044a400a436", + { "html": 2203, "metadata": 2204 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-003-indexeddb-for-pwa-storage\">ADR-003: IndexedDB for PWA Storage\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-003-indexeddb-for-pwa-storage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-003: IndexedDB for PWA Storage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Accepted\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2024-02-01\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>PWA needs to store user data (uploaded files, analysis results, settings) persistently in the browser. Options:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>localStorage\u003C/strong>: Simple but 5MB limit, synchronous, string-only\u003C/li>\n\u003Cli>\u003Cstrong>IndexedDB\u003C/strong>: Complex API but large storage, async, structured data\u003C/li>\n\u003Cli>\u003Cstrong>Cache API\u003C/strong>: Designed for HTTP responses, not app data\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use IndexedDB with a wrapper utility for:\u003C/p>\n\u003Cul>\n\u003Cli>Uploaded datasets (can be multi-MB)\u003C/li>\n\u003Cli>Computed statistics cache\u003C/li>\n\u003Cli>User preferences and settings\u003C/li>\n\u003C/ul>\n\u003Cp>Use localStorage only for:\u003C/p>\n\u003Cul>\n\u003Cli>Small, simple values (theme preference, last-used settings)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"benefits\">Benefits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#benefits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Benefits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Virtually unlimited storage (browser-managed quotas)\u003C/li>\n\u003Cli>Structured data with indexes for queries\u003C/li>\n\u003Cli>Async API won’t block UI thread\u003C/li>\n\u003Cli>Survives browser restarts\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"trade-offs\">Trade-offs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#trade-offs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Trade-offs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Complex API requiring wrapper abstraction\u003C/li>\n\u003Cli>Debugging is harder than localStorage\u003C/li>\n\u003Cli>Storage can be evicted under pressure\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../08-products/pwa/storage.md\">PWA Storage\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2205, + "localImagePaths": 2214, + "remoteImagePaths": 2215, + "frontmatter": 2216, + "imagePaths": 2217 + }, + [2206, 2208, 2209, 2210, 2211, 2212, 2213], + { "depth": 30, "slug": 2207, "text": 2195 }, + "adr-003-indexeddb-for-pwa-storage", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2156, "text": 2157 }, + { "depth": 79, "slug": 2159, "text": 2160 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2195 }, + [], + "07-decisions/adr-004-offline-first", + { "id": 2218, "data": 2220, "body": 2225, "filePath": 2226, "digest": 2227, "rendered": 2228 }, + { + "title": 2221, + "editUrl": 16, + "head": 2222, + "template": 18, + "sidebar": 2223, + "pagefind": 16, + "draft": 20 + }, + "ADR-004: Offline-First Architecture", + [], + { "hidden": 20, "attrs": 2224 }, + {}, + "# ADR-004: Offline-First Architecture\n\n**Status**: Accepted\n\n**Date**: 2024-02-05\n\n---\n\n## Context\n\nQuality professionals often work in manufacturing environments with unreliable network connectivity. The tool must work without internet access after initial installation.\n\n---\n\n## Decision\n\nImplement offline-first architecture:\n\n1. **No backend required**: All statistical processing in browser\n2. **Service Worker**: Cache app shell and assets\n3. **Local-first data**: All data stays in IndexedDB\n4. **Optional sync**: Azure app can sync to OneDrive when online\n\n---\n\n## Consequences\n\n### Benefits\n\n- Works in low/no connectivity environments\n- No server costs or maintenance\n- Data privacy (stays on user's device)\n- Instant load after first visit\n\n### Trade-offs\n\n- Can't do cross-device sync without explicit cloud integration\n- Limited to browser's computational capabilities\n- Updates require service worker refresh cycle\n\n---\n\n## See Also\n\n- [Offline-First Architecture](../05-technical/architecture/offline-first.md)\n- [PWA Storage](../08-products/pwa/storage.md)", + "src/content/docs/07-decisions/adr-004-offline-first.md", + "6fc5aae1b2453f55", + { "html": 2229, "metadata": 2230 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-004-offline-first-architecture\">ADR-004: Offline-First Architecture\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-004-offline-first-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-004: Offline-First Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Accepted\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2024-02-05\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Quality professionals often work in manufacturing environments with unreliable network connectivity. The tool must work without internet access after initial installation.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Implement offline-first architecture:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>No backend required\u003C/strong>: All statistical processing in browser\u003C/li>\n\u003Cli>\u003Cstrong>Service Worker\u003C/strong>: Cache app shell and assets\u003C/li>\n\u003Cli>\u003Cstrong>Local-first data\u003C/strong>: All data stays in IndexedDB\u003C/li>\n\u003Cli>\u003Cstrong>Optional sync\u003C/strong>: Azure app can sync to OneDrive when online\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"benefits\">Benefits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#benefits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Benefits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Works in low/no connectivity environments\u003C/li>\n\u003Cli>No server costs or maintenance\u003C/li>\n\u003Cli>Data privacy (stays on user’s device)\u003C/li>\n\u003Cli>Instant load after first visit\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"trade-offs\">Trade-offs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#trade-offs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Trade-offs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Can’t do cross-device sync without explicit cloud integration\u003C/li>\n\u003Cli>Limited to browser’s computational capabilities\u003C/li>\n\u003Cli>Updates require service worker refresh cycle\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../05-technical/architecture/offline-first.md\">Offline-First Architecture\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/pwa/storage.md\">PWA Storage\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2231, + "localImagePaths": 2240, + "remoteImagePaths": 2241, + "frontmatter": 2242, + "imagePaths": 2243 + }, + [2232, 2234, 2235, 2236, 2237, 2238, 2239], + { "depth": 30, "slug": 2233, "text": 2221 }, + "adr-004-offline-first-architecture", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2156, "text": 2157 }, + { "depth": 79, "slug": 2159, "text": 2160 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2221 }, + [], + "07-decisions/adr-005-props-based-charts", + { "id": 2244, "data": 2246, "body": 2251, "filePath": 2252, "digest": 2253, "rendered": 2254 }, + { + "title": 2247, + "editUrl": 16, + "head": 2248, + "template": 18, + "sidebar": 2249, + "pagefind": 16, + "draft": 20 + }, + "ADR-005: Props-Based Charts (vs Context)", + [], + { "hidden": 20, "attrs": 2250 }, + {}, + "# ADR-005: Props-Based Charts (vs Context)\n\n**Status**: Accepted\n\n**Date**: 2024-02-15\n\n---\n\n## Context\n\nChart components need data (measurements, specs, stats). Two patterns:\n\n1. **Context-based**: Charts consume data from React Context\n2. **Props-based**: Charts receive all data through props\n\n---\n\n## Decision\n\nAll chart components in `@variscout/charts` are props-based:\n\n```typescript\n\u003CIChart\n data={measurements}\n specs={{ lsl: 98, usl: 102, target: 100 }}\n stats={calculatedStats}\n showBranding={true}\n/>\n```\n\n---\n\n## Consequences\n\n### Benefits\n\n- Charts are pure, testable, reusable\n- Same chart works in PWA, Excel, Azure with different data sources\n- Clear data flow, easy to reason about\n- Can render multiple charts with different data\n\n### Trade-offs\n\n- More props to pass through component tree\n- Parent components must manage data fetching/calculation\n- Some prop drilling in complex layouts\n\n---\n\n## See Also\n\n- [Charts Package Rules](../06-design-system/charts/overview.md)", + "src/content/docs/07-decisions/adr-005-props-based-charts.md", + "2f00a8085c5b791d", + { "html": 2255, "metadata": 2256 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-005-props-based-charts-vs-context\">ADR-005: Props-Based Charts (vs Context)\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-005-props-based-charts-vs-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-005: Props-Based Charts (vs Context)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Accepted\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2024-02-15\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Chart components need data (measurements, specs, stats). Two patterns:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Context-based\u003C/strong>: Charts consume data from React Context\u003C/li>\n\u003Cli>\u003Cstrong>Props-based\u003C/strong>: Charts receive all data through props\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All chart components in \u003Ccode dir=\"auto\">@variscout/charts\u003C/code> are props-based:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{measurements}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{{ lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">98\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">102\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, target: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{calculatedStats}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showBranding\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{true}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CIChart data={measurements} specs={{ lsl: 98, usl: 102, target: 100 }} stats={calculatedStats} showBranding={true}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"benefits\">Benefits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#benefits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Benefits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Charts are pure, testable, reusable\u003C/li>\n\u003Cli>Same chart works in PWA, Excel, Azure with different data sources\u003C/li>\n\u003Cli>Clear data flow, easy to reason about\u003C/li>\n\u003Cli>Can render multiple charts with different data\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"trade-offs\">Trade-offs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#trade-offs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Trade-offs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>More props to pass through component tree\u003C/li>\n\u003Cli>Parent components must manage data fetching/calculation\u003C/li>\n\u003Cli>Some prop drilling in complex layouts\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../06-design-system/charts/overview.md\">Charts Package Rules\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2257, + "localImagePaths": 2266, + "remoteImagePaths": 2267, + "frontmatter": 2268, + "imagePaths": 2269 + }, + [2258, 2260, 2261, 2262, 2263, 2264, 2265], + { "depth": 30, "slug": 2259, "text": 2247 }, + "adr-005-props-based-charts-vs-context", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2156, "text": 2157 }, + { "depth": 79, "slug": 2159, "text": 2160 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2247 }, + [], + "07-decisions/adr-006-edition-system", + { "id": 2270, "data": 2272, "body": 2277, "filePath": 2278, "digest": 2279, "rendered": 2280 }, + { + "title": 2273, + "editUrl": 16, + "head": 2274, + "template": 18, + "sidebar": 2275, + "pagefind": 16, + "draft": 20 + }, + "ADR-006: Edition System", + [], + { "hidden": 20, "attrs": 2276 }, + {}, + "# ADR-006: Edition System\n\n**Status**: Superseded by [ADR-007](adr-007-azure-marketplace-distribution.md)\n\n**Date**: 2024-03-01 (Updated: 2026-02-05)\n\n---\n\n## Historical Context\n\n> **Note**: This ADR documents the original Community/Licensed edition system using Paddle for payment processing and license keys. This approach has been superseded by Azure Marketplace distribution. See [ADR-007](adr-007-azure-marketplace-distribution.md) for the current strategy.\n\nThe original model supported:\n\n- **Community**: Free, full features, VariScout branding\n- **Licensed**: Paid (€99), no branding, theme customization\n\n---\n\n## Current Edition Model\n\n### Tier Structure\n\n| Tier | Product | Price | Users | Detection |\n| ------------ | --------- | ----------- | --------- | -------------------------- |\n| Free | Excel | €0 | All | Default (no Azure) |\n| Individual | Azure App | €99/year | 1 | ARM template param |\n| Team | Azure App | €499/year | Up to 10 | ARM template param |\n| Enterprise | Azure App | €1,790/year | Unlimited | ARM template param |\n| Full (Excel) | Excel | €0 | All | Graph API (Azure detected) |\n\n### Detection Mechanism\n\n**Azure App** (Primary Product):\n\nLicense tier is set at deployment time via ARM template parameters:\n\n```typescript\n// packages/core/src/edition.ts\nexport type Tier = 'free' | 'individual' | 'team' | 'enterprise';\n\nexport function getTier(): Tier {\n // Azure App: tier set via environment variable at deployment\n if (import.meta.env.VITE_LICENSE_TIER) {\n return import.meta.env.VITE_LICENSE_TIER as Tier;\n }\n\n // PWA: demo mode only\n return 'free';\n}\n\nexport function getMaxUsers(tier: Tier): number {\n switch (tier) {\n case 'individual':\n return 1;\n case 'team':\n return 10;\n case 'enterprise':\n return Infinity;\n default:\n return 1;\n }\n}\n```\n\n**Excel Add-in** (Secondary Product):\n\nTier detected via Microsoft Graph API:\n\n```typescript\n// apps/excel-addin/src/lib/licenseDetection.ts\nexport async function checkLicense(): Promise\u003C{ tier: 'free' | 'full' }> {\n const graphClient = await getGraphClient();\n\n // Check for VariScout Azure App registration in tenant\n const apps = await graphClient.api('/applications').filter(\"displayName eq 'VariScout'\").get();\n\n return {\n tier: apps.value.length > 0 ? 'full' : 'free',\n };\n}\n```\n\n---\n\n## Feature Gating\n\n### By Tier\n\n```typescript\nexport function isFeatureEnabled(feature: Feature, tier: Tier): boolean {\n const featureMatrix: Record\u003CFeature, Tier[]> = {\n 'basic-charts': ['free', 'individual', 'team', 'enterprise'],\n 'performance-mode': ['free', 'individual', 'team', 'enterprise'],\n 'unlimited-channels': ['individual', 'team', 'enterprise'],\n 'team-sharing': ['team', 'enterprise'],\n 'priority-support': ['enterprise'],\n };\n\n return featureMatrix[feature].includes(tier);\n}\n```\n\n### Excel-Specific Limits\n\n```typescript\nexport const EXCEL_FEATURE_LIMITS = {\n free: {\n maxChannels: 50,\n maxDrillDownDepth: 2,\n },\n full: {\n maxChannels: Infinity,\n maxDrillDownDepth: Infinity,\n },\n};\n```\n\n---\n\n## Consequences\n\n### Benefits\n\n- **No license keys**: Deployment = licensed (simpler UX)\n- **No backend**: Graph API replaces license validation server\n- **Microsoft billing**: Trusted, enterprise-ready\n- **Clear upgrade path**: Free Excel → Azure App tiers\n\n### Trade-offs\n\n- **Microsoft platform dependency**: Requires Azure deployment\n- **Less portable**: License tied to tenant, not user\n- **Graph API permission**: Requires Application.Read.All consent\n\n---\n\n## Migration from Old System\n\nExisting Paddle license keys are honored until expiry:\n\n```typescript\n// Legacy support (to be removed after migration period)\nexport function checkLegacyLicense(key: string): boolean {\n // Validate existing VS-XXXX-XXXX-XXXX format keys\n // Returns true if valid and not expired\n}\n```\n\n---\n\n## Build Commands\n\nThe original edition-specific builds are deprecated:\n\n```bash\n# DEPRECATED - These commands will be removed\npnpm build:pwa:community # Community edition\npnpm build:pwa:licensed # Licensed edition\n\n# CURRENT\npnpm build # Standard build for all apps\n```\n\nAzure App tier is determined at deployment time, not build time.\n\n---\n\n## See Also\n\n- [ADR-007: Azure Marketplace Distribution](adr-007-azure-marketplace-distribution.md) (current strategy)\n- [Products Overview](../08-products/index.md)\n- [Azure Pricing Tiers](../08-products/azure/pricing-tiers.md)\n- Excel License Detection (removed — Excel Add-in shelved Feb 2026)", + "src/content/docs/07-decisions/adr-006-edition-system.md", + "e2f41297a5361594", + { "html": 2281, "metadata": 2282 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-006-edition-system\">ADR-006: Edition System\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-006-edition-system\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-006: Edition System”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Superseded by \u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a>\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2024-03-01 (Updated: 2026-02-05)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"historical-context\">Historical Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#historical-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Historical Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note\u003C/strong>: This ADR documents the original Community/Licensed edition system using Paddle for payment processing and license keys. This approach has been superseded by Azure Marketplace distribution. See \u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a> for the current strategy.\u003C/p>\n\u003C/blockquote>\n\u003Cp>The original model supported:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Community\u003C/strong>: Free, full features, VariScout branding\u003C/li>\n\u003Cli>\u003Cstrong>Licensed\u003C/strong>: Paid (€99), no branding, theme customization\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"current-edition-model\">Current Edition Model\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#current-edition-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Current Edition Model”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tier-structure\">Tier Structure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tier-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier Structure”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tier\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Price\u003C/th>\u003Cth>Users\u003C/th>\u003Cth>Detection\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Free\u003C/td>\u003Ctd>Excel\u003C/td>\u003Ctd>€0\u003C/td>\u003Ctd>All\u003C/td>\u003Ctd>Default (no Azure)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Individual\u003C/td>\u003Ctd>Azure App\u003C/td>\u003Ctd>€99/year\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>ARM template param\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Team\u003C/td>\u003Ctd>Azure App\u003C/td>\u003Ctd>€499/year\u003C/td>\u003Ctd>Up to 10\u003C/td>\u003Ctd>ARM template param\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Enterprise\u003C/td>\u003Ctd>Azure App\u003C/td>\u003Ctd>€1,790/year\u003C/td>\u003Ctd>Unlimited\u003C/td>\u003Ctd>ARM template param\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Full (Excel)\u003C/td>\u003Ctd>Excel\u003C/td>\u003Ctd>€0\u003C/td>\u003Ctd>All\u003C/td>\u003Ctd>Graph API (Azure detected)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"detection-mechanism\">Detection Mechanism\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#detection-mechanism\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Detection Mechanism”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Azure App\u003C/strong> (Primary Product):\u003C/p>\n\u003Cp>License tier is set at deployment time via ARM template parameters:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/core/src/edition.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Tier \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">free\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">individual\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">team\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">enterprise\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getTier\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Tier\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Azure App: tier set via environment variable at deployment\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">meta\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">env\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VITE_LICENSE_TIER\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">meta\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">env\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VITE_LICENSE_TIER\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">as\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Tier\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PWA: demo mode only\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">free\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getMaxUsers\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">tier\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#FFCB8B\">Tier\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">switch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (tier) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">case\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">individual\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">case\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">team\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">10\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">case\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">enterprise\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Infinity\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">default\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export type Tier = 'free' | 'individual' | 'team' | 'enterprise';export function getTier(): Tier { // Azure App: tier set via environment variable at deployment if (import.meta.env.VITE_LICENSE_TIER) { return import.meta.env.VITE_LICENSE_TIER as Tier; } // PWA: demo mode only return 'free';}export function getMaxUsers(tier: Tier): number { switch (tier) { case 'individual': return 1; case 'team': return 10; case 'enterprise': return Infinity; default: return 1; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Excel Add-in\u003C/strong> (Secondary Product):\u003C/p>\n\u003Cp>Tier detected via Microsoft Graph API:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">apps/excel-addin/src/lib/licenseDetection.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">async\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">checkLicense\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Promise\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><{ tier\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">free\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">full\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">graphClient\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getGraphClient\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Check for VariScout Azure App registration in tenant\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">apps\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">graphClient\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">api\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">/applications\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">displayName eq 'VariScout'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">get\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tier: apps\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">length\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">full\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">free\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export async function checkLicense(): Promise\u003C{ tier: 'free' | 'full' }> { const graphClient = await getGraphClient(); // Check for VariScout Azure App registration in tenant const apps = await graphClient.api('/applications').filter("displayName eq 'VariScout'").get(); return { tier: apps.value.length > 0 ? 'full' : 'free', };}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-gating\">Feature Gating\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-gating\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Gating”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"by-tier\">By Tier\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#by-tier\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “By Tier”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isFeatureEnabled\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">feature\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Feature\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">tier\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#FFCB8B\">Tier\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">featureMatrix\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Record\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Feature\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Tier\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">> = {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">basic-charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">free\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">individual\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">team\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">enterprise\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">performance-mode\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">free\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">individual\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">team\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">enterprise\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">unlimited-channels\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">individual\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">team\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">enterprise\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">team-sharing\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">team\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">enterprise\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">priority-support\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">enterprise\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> featureMatrix[feature]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">includes\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(tier);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export function isFeatureEnabled(feature: Feature, tier: Tier): boolean { const featureMatrix: Record\u003CFeature, Tier[]> = { 'basic-charts': ['free', 'individual', 'team', 'enterprise'], 'performance-mode': ['free', 'individual', 'team', 'enterprise'], 'unlimited-channels': ['individual', 'team', 'enterprise'], 'team-sharing': ['team', 'enterprise'], 'priority-support': ['enterprise'], }; return featureMatrix[feature].includes(tier);}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"excel-specific-limits\">Excel-Specific Limits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#excel-specific-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Excel-Specific Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">EXCEL_FEATURE_LIMITS\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">free: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">maxChannels: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">50\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">maxDrillDownDepth: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">full: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">maxChannels: \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Infinity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">maxDrillDownDepth: \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Infinity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export const EXCEL_FEATURE_LIMITS = { free: { maxChannels: 50, maxDrillDownDepth: 2, }, full: { maxChannels: Infinity, maxDrillDownDepth: Infinity, },};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"benefits\">Benefits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#benefits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Benefits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>No license keys\u003C/strong>: Deployment = licensed (simpler UX)\u003C/li>\n\u003Cli>\u003Cstrong>No backend\u003C/strong>: Graph API replaces license validation server\u003C/li>\n\u003Cli>\u003Cstrong>Microsoft billing\u003C/strong>: Trusted, enterprise-ready\u003C/li>\n\u003Cli>\u003Cstrong>Clear upgrade path\u003C/strong>: Free Excel → Azure App tiers\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"trade-offs\">Trade-offs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#trade-offs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Trade-offs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Microsoft platform dependency\u003C/strong>: Requires Azure deployment\u003C/li>\n\u003Cli>\u003Cstrong>Less portable\u003C/strong>: License tied to tenant, not user\u003C/li>\n\u003Cli>\u003Cstrong>Graph API permission\u003C/strong>: Requires Application.Read.All consent\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"migration-from-old-system\">Migration from Old System\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#migration-from-old-system\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Migration from Old System”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Existing Paddle license keys are honored until expiry:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Legacy support (to be removed after migration period)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">checkLegacyLicense\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Validate existing VS-XXXX-XXXX-XXXX format keys\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns true if valid and not expired\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Legacy support (to be removed after migration period)export function checkLegacyLicense(key: string): boolean { // Validate existing VS-XXXX-XXXX-XXXX format keys // Returns true if valid and not expired}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"build-commands\">Build Commands\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#build-commands\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Build Commands”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The original edition-specific builds are deprecated:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># DEPRECATED - These commands will be removed\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build:pwa:community\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Community edition\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build:pwa:licensed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Licensed edition\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># CURRENT\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Standard build for all apps\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm build:pwa:community # Community editionpnpm build:pwa:licensed # Licensed editionpnpm build # Standard build for all apps\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Azure App tier is determined at deployment time, not build time.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007: Azure Marketplace Distribution\u003C/a> (current strategy)\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/index.md\">Products Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/azure/pricing-tiers.md\">Azure Pricing Tiers\u003C/a>\u003C/li>\n\u003Cli>Excel License Detection (removed — Excel Add-in shelved Feb 2026)\u003C/li>\n\u003C/ul>", + { + "headings": 2283, + "localImagePaths": 2317, + "remoteImagePaths": 2318, + "frontmatter": 2319, + "imagePaths": 2320 + }, + [2284, 2286, 2289, 2292, 2295, 2298, 2301, 2304, 2307, 2308, 2309, 2310, 2313, 2316], + { "depth": 30, "slug": 2285, "text": 2273 }, + "adr-006-edition-system", + { "depth": 33, "slug": 2287, "text": 2288 }, + "historical-context", + "Historical Context", + { "depth": 33, "slug": 2290, "text": 2291 }, + "current-edition-model", + "Current Edition Model", + { "depth": 79, "slug": 2293, "text": 2294 }, + "tier-structure", + "Tier Structure", + { "depth": 79, "slug": 2296, "text": 2297 }, + "detection-mechanism", + "Detection Mechanism", + { "depth": 33, "slug": 2299, "text": 2300 }, + "feature-gating", + "Feature Gating", + { "depth": 79, "slug": 2302, "text": 2303 }, + "by-tier", + "By Tier", + { "depth": 79, "slug": 2305, "text": 2306 }, + "excel-specific-limits", + "Excel-Specific Limits", + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2156, "text": 2157 }, + { "depth": 79, "slug": 2159, "text": 2160 }, + { "depth": 33, "slug": 2311, "text": 2312 }, + "migration-from-old-system", + "Migration from Old System", + { "depth": 33, "slug": 2314, "text": 2315 }, + "build-commands", + "Build Commands", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2273 }, + [], + "07-decisions/adr-007-azure-marketplace-distribution", + { "id": 2321, "data": 2323, "body": 2328, "filePath": 2329, "digest": 2330, "rendered": 2331 }, + { + "title": 2324, + "editUrl": 16, + "head": 2325, + "template": 18, + "sidebar": 2326, + "pagefind": 16, + "draft": 20 + }, + "ADR-007: Azure Marketplace Distribution Strategy", + [], + { "hidden": 20, "attrs": 2327 }, + {}, + "# ADR-007: Azure Marketplace Distribution Strategy\n\n**Status**: Accepted (Revised 2026-02-27)\n\n**Date**: 2026-02-05 (Original), 2026-02-13 (Revised), 2026-02-27 (Revised)\n\n---\n\n## Context\n\nVariScout has evolved from a single PWA product to a multi-platform offering. The previous licensing model used:\n\n- **Paddle** for payment processing (PWA license)\n- **Custom license keys** for feature gating\n- **Backend webhook** for key generation and validation\n\nThis approach had several limitations:\n\n1. **Backend dependency** - Required server infrastructure for license validation\n2. **Payment complexity** - Paddle's fees plus VAT handling complexity\n3. **No enterprise support** - Single-user licensing only\n4. **Limited distribution** - Manual installation via URL\n\n### Revision Context (2026-02-27)\n\nTeams integration creates a natural product tier split. Quality teams need mobile gemba access (photo evidence, chart sharing, commenting on findings) and shared channel file storage. This justifies a two-plan Marketplace model: Standard (personal, browser) and Team (collaborative, Teams-integrated). See [ADR-016](adr-016-teams-integration.md) for full technical design.\n\n### Revision Context (2026-02-13)\n\nA technical viability review against current Microsoft documentation revealed critical issues with the original plan:\n\n1. **Solution Templates are not transactable** - Microsoft will not bill customers for Solution Template offers. They support free/BYOL only.\n2. **Per-user pricing is unenforceable** - Managed Applications are per-deployment; there is no mechanism to enforce user-count tiers.\n3. **Graph API license detection for Excel was over-engineered** - The complexity and admin consent requirements outweighed the benefits.\n\nThese findings led to a simplified model: one paid product (Azure App as Managed Application) and one free product (Excel Add-in with no license detection).\n\n---\n\n## Decision\n\n**Adopt Azure Marketplace as the primary distribution channel using a Managed Application offer:**\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ VariScout on Azure Marketplace │\n│ │\n│ Offer: VariScout - Statistical Process Control │\n│ for Quality Teams │\n│ │\n│ Plan: \"VariScout Standard\" €99/month │\n│ Full analysis suite, local file storage (.vrs on your │\n│ computer). EasyAuth sign-in (User.Read only), │\n│ browser-based access │\n│ │\n│ Plan: \"VariScout Team\" €299/month (TBD) │\n│ Everything in Standard, plus: │\n│ - OneDrive + SharePoint channel file storage │\n│ - Teams integration (SSO, sidebar, Adaptive Cards) │\n│ - Mobile gemba companion (Field View + photo comments) │\n│ - Requires: admin consent for Files.ReadWrite.All │\n│ │\n│ Offer type: Managed Application │\n│ Billing: Microsoft (3% fee, monthly) │\n│ Customer access: Full control │\n│ Publisher access: Disabled (zero access) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n### Product Hierarchy\n\n| Product | Role | Distribution | Price |\n| ------------------------ | ------------------------------------ | ----------------- | ------------------------------------------------------------------------- |\n| **Azure App (Standard)** | Full analysis, local files | Azure Marketplace | €99/month (Managed Application) |\n| **Azure App (Team)** | + Teams, cloud collaboration, mobile | Azure Marketplace | €299/month (TBD — price under evaluation) |\n| **PWA** | FREE (training & education) | Public website | Free forever (core analysis + Green Belt, copy-paste input, session-only) |\n\n> **Note (Feb 2026):** Excel Add-in shelved — cost with no revenue, unproven funnel. The PWA serves the same funnel role (free, no friction, shows the methodology) at zero marginal cost. See original 3-product strategy below for historical context.\n\n### Two-Plan Technical Differentiation\n\nThe ARM template passes a `VARISCOUT_PLAN` environment variable (`standard` or `team`). The existing `getTier()` infrastructure resolves plan-appropriate feature sets — both plans deploy as `enterprise` tier, but the Team plan unlocks Teams-specific capabilities.\n\nSame ARM template is reused across both plans (Azure Marketplace supports up to 100 plans per offer). The plan variable controls:\n\n- Storage mode: Standard = File System Access API (local `.vrs` files, fallback to IndexedDB); Team = + OneDrive personal + SharePoint channel storage\n- Teams SDK initialization (Team plan only)\n- Channel file storage UI (Team plan only)\n- Mobile Field View route (Team plan only)\n- Photo capture in findings (Team plan only)\n- Admin consent guidance in settings (Team plan only)\n\nSee [ADR-016](adr-016-teams-integration.md) for full Teams integration technical design.\n\n### Pricing Rationale\n\n| Aspect | Standard | Team |\n| -------------- | ------------------------------------ | ----------------------- |\n| Price | €99/month | €299/month (TBD) |\n| Net (after 3%) | €96.03/month | €290.03/month |\n| Annual net | €1,152/year | €3,480/year |\n| Storage | Local files (File System Access API) | + OneDrive + SharePoint |\n| Auth scopes | `User.Read` only | + `Files.ReadWrite.All` |\n| Admin consent | None | Required (one-time) |\n\n| Aspect | Value |\n| ------- | -------------------------------------------------- |\n| Billing | Monthly only (Managed Application limitation) |\n| Model | Per-deployment (one subscription per Azure tenant) |\n\n> Customer pays their own Azure infrastructure costs (App Service Plan, etc.) separately. Microsoft handles VAT/GST — prices are set excluding tax, Microsoft adds tax at checkout based on customer's billing country (e.g., 24% ALV in Finland).\n\n**Why per-deployment pricing**: Managed Applications are per-deployment, not per-user. There is no mechanism to enforce user-count tiers within a tenant. Plans differentiate by capability (Standard vs Team), not by user count. Both plans include unlimited users in the tenant.\n\n---\n\n## Why Managed Application\n\n### Offer Type Comparison\n\n| Capability | Solution Template | Managed Application |\n| ---------------------------------- | :---------------: | :------------------: |\n| Microsoft-billed (transactable) | No | **Yes** (3% fee) |\n| Deploys to customer's subscription | Yes | **Yes** (managed RG) |\n| Data stays in customer's tenant | Yes | **Yes** |\n| Publisher access to customer | N/A | Optional (disabled) |\n| No backend needed | Yes | **Yes** |\n| Monthly pricing | N/A (free only) | **Yes** |\n\n### Permission Model\n\n| Setting | Configuration | Notes |\n| -------------------- | ------------- | ------------------------------------------- |\n| Publisher Management | **DISABLED** | Zero publisher access to customer resources |\n| Customer Access | **ENABLED** | Full customer control over their deployment |\n\nThese settings are **immutable after publishing** the offer in Partner Center.\n\n**Why disable publisher access**: VariScout is a client-side SPA with no backend. There is nothing for the publisher to manage. Disabling access builds customer trust and simplifies compliance.\n\n### Managed Application Package\n\nThe deployment package is a `.zip` file containing:\n\n```\nvariscout-managed-app.zip\n├── mainTemplate.json # ARM template for resources\n└── createUiDefinition.json # Azure portal deployment wizard\n```\n\n---\n\n## Consequences\n\n### Benefits\n\n1. **No backend required**\n - App deploys as Static Web App in customer's managed resource group\n - All processing in browser, data stays local\n - Zero infrastructure to maintain\n\n2. **Microsoft handles billing**\n - 3% transaction fee (lower than Paddle's ~5% + VAT complexity)\n - Automatic VAT handling in all Microsoft markets\n - Enterprise procurement integration (purchase orders, invoicing)\n - Monthly billing with automatic renewal\n\n3. **Simplified product model**\n - Two paid plans (Standard + Team), one free product (PWA)\n - No per-user tier confusion — plans differentiate by capability\n - No license detection complexity\n - GTM: \"Try it free at variscout.com. When you're ready for your team, get it on Azure Marketplace.\"\n\n4. **Distribution advantage**\n - Azure Marketplace visibility to enterprise buyers\n - AppSource visibility for Excel Add-in\n - Trust signal from Microsoft certification\n\n5. **Data sovereignty**\n - App deploys to customer's Azure tenant\n - Data never leaves their environment\n - Meets enterprise compliance requirements\n\n### Trade-offs\n\n1. **Microsoft platform dependency**\n - Tied to Azure/Microsoft 365 ecosystem\n - Subject to Microsoft certification requirements\n - Marketplace listing approval process\n\n2. **Monthly billing only**\n - Managed Applications do not support annual billing\n - Monthly billing may create higher churn risk\n - But also lower purchase friction (no large upfront commitment)\n\n3. **PWA as free training tool**\n - PWA repositioned as free variation analysis training and education tool\n - Core analysis (I-Chart, Boxplot, Pareto, Capability, Regression) included\n - No file upload, no save, no Performance Mode (Azure App differentiators)\n - Copy-paste from Excel/Sheets + pre-loaded sample datasets\n\n4. **Excel Add-in feature reduction**\n - Performance Mode removed from Excel (Azure App exclusive)\n - Intentional to create clear upgrade incentive\n - Core analysis remains fully functional\n\n5. **No per-user pricing**\n - Cannot charge differently based on team size\n - Single plan must be attractive to both small teams and large organizations\n - €99/month Standard is competitive: cheaper than most alternatives for teams >2 users\n\n---\n\n## Azure App Tier Configuration\n\nLicense tier is set by deployment — all Managed Application deployments get full features:\n\n```typescript\n// Deployment writes tier to app configuration\nconst tier = import.meta.env.VITE_LICENSE_TIER; // Always 'enterprise' for Managed App\n```\n\nThe existing `tier.ts` infrastructure remains, with Managed Application deployments always configured as the highest tier.\n\n---\n\n## Excel Add-in: Shelved (Feb 2026)\n\nThe Excel Add-in was originally planned as a free marketing funnel product on AppSource. It was shelved because:\n\n1. **Cost with no revenue** — AppSource certification, Office.js maintenance, Fluent UI theming\n2. **Unproven funnel** — No evidence Excel users convert to Azure App purchasers\n3. **PWA does the same job** — Free, no friction, shows the methodology, costs nothing extra to maintain\n4. **Simpler GTM** — Two products (free PWA + paid Azure) is easier to explain than three\n\nThe codebase (`apps/excel-addin/`) was removed. Historical documentation preserved in this ADR for context.\n\n---\n\n## Migration Path\n\n### For PWA Users\n\n1. PWA is a genuine free product for training and education\n2. Core analysis + Green Belt tools always available\n3. Copy-paste from Excel/Sheets for own data analysis\n4. Upgrade to Azure App for file upload, save, Performance Mode, and team features\n\n### For New Customers\n\n1. Start with free PWA at variscout.com (training & education)\n2. Azure Marketplace for full-featured deployment (from €99/month)\n3. Clear upgrade path from free PWA to Azure App\n\n---\n\n## Implementation Phases\n\n### Phase 1: Documentation (This Revision)\n\n- Updated all documentation to reflect Managed Application model\n- Simplified Excel Add-in strategy (free forever, no license detection)\n- Updated pricing to single plan at €150/month\n\n### Phase 2: Core Tier Infrastructure (Complete)\n\n- Created `packages/core/src/tier.ts` with tier configuration\n- Implemented `getTier()`, `isPaidTier()`, `getMaxChannels()` functions\n- Created `packages/hooks/src/useTier.ts` React hook\n- Added `TierBadge` and `UpgradePrompt` UI components\n- Integrated tier-aware channel limits (5 free / 1,500 paid)\n\n### Phase 3: Azure Marketplace (Q2 2026)\n\n- Partner Center account setup\n- Managed Application offer creation\n- Deployment package (mainTemplate.json + createUiDefinition.json)\n- Standard plan at €99/month\n- Certification and launch\n\n### Phase 4: Excel Add-in Shelved (Feb 2026)\n\n- Excel Add-in codebase removed\n- AppSource submission cancelled\n- PWA serves as the sole free funnel product\n\n### Phase 5: Team Plan & Teams Integration (TBD)\n\n- Add second Marketplace plan (\"VariScout Team\" at €299/month, price TBD)\n- `VARISCOUT_PLAN` environment variable in ARM template\n- Teams SDK integration (SSO, channel tabs, Adaptive Cards)\n- Shared channel file storage (SharePoint) with optimistic merge\n- Mobile Field View (`/field` route) for gemba investigations\n- Photo comments on findings (camera capture + channel storage)\n- Azure Function for On-Behalf-Of token exchange\n- See [ADR-016](adr-016-teams-integration.md) for phased delivery breakdown\n\n---\n\n## Related Decisions\n\n- [ADR-006: Edition System](adr-006-edition-system.md) - Superseded, kept for historical context\n- [ADR-004: Offline-First](adr-004-offline-first.md) - Unchanged, still applies\n- [ADR-016: Teams Integration](adr-016-teams-integration.md) - Technical design for Team plan capabilities\n\n---\n\n## See Also\n\n- [Azure Marketplace Guide](../08-products/azure/marketplace.md)\n- [Pricing Tiers](../08-products/azure/pricing-tiers.md)\n- [ARM Template](../08-products/azure/arm-template.md)", + "src/content/docs/07-decisions/adr-007-azure-marketplace-distribution.md", + "386a12655f925132", + { "html": 2332, "metadata": 2333 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-007-azure-marketplace-distribution-strategy\">ADR-007: Azure Marketplace Distribution Strategy\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-007-azure-marketplace-distribution-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-007: Azure Marketplace Distribution Strategy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Accepted (Revised 2026-02-27)\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2026-02-05 (Original), 2026-02-13 (Revised), 2026-02-27 (Revised)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout has evolved from a single PWA product to a multi-platform offering. The previous licensing model used:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Paddle\u003C/strong> for payment processing (PWA license)\u003C/li>\n\u003Cli>\u003Cstrong>Custom license keys\u003C/strong> for feature gating\u003C/li>\n\u003Cli>\u003Cstrong>Backend webhook\u003C/strong> for key generation and validation\u003C/li>\n\u003C/ul>\n\u003Cp>This approach had several limitations:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Backend dependency\u003C/strong> - Required server infrastructure for license validation\u003C/li>\n\u003Cli>\u003Cstrong>Payment complexity\u003C/strong> - Paddle’s fees plus VAT handling complexity\u003C/li>\n\u003Cli>\u003Cstrong>No enterprise support\u003C/strong> - Single-user licensing only\u003C/li>\n\u003Cli>\u003Cstrong>Limited distribution\u003C/strong> - Manual installation via URL\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"revision-context-2026-02-27\">Revision Context (2026-02-27)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#revision-context-2026-02-27\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Revision Context (2026-02-27)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Teams integration creates a natural product tier split. Quality teams need mobile gemba access (photo evidence, chart sharing, commenting on findings) and shared channel file storage. This justifies a two-plan Marketplace model: Standard (personal, browser) and Team (collaborative, Teams-integrated). See \u003Ca href=\"adr-016-teams-integration.md\">ADR-016\u003C/a> for full technical design.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"revision-context-2026-02-13\">Revision Context (2026-02-13)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#revision-context-2026-02-13\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Revision Context (2026-02-13)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A technical viability review against current Microsoft documentation revealed critical issues with the original plan:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Solution Templates are not transactable\u003C/strong> - Microsoft will not bill customers for Solution Template offers. They support free/BYOL only.\u003C/li>\n\u003Cli>\u003Cstrong>Per-user pricing is unenforceable\u003C/strong> - Managed Applications are per-deployment; there is no mechanism to enforce user-count tiers.\u003C/li>\n\u003Cli>\u003Cstrong>Graph API license detection for Excel was over-engineered\u003C/strong> - The complexity and admin consent requirements outweighed the benefits.\u003C/li>\n\u003C/ol>\n\u003Cp>These findings led to a simplified model: one paid product (Azure App as Managed Application) and one free product (Excel Add-in with no license detection).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Adopt Azure Marketplace as the primary distribution channel using a Managed Application offer:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ VariScout on Azure Marketplace │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Offer: VariScout - Statistical Process Control │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ for Quality Teams │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Plan: \"VariScout Standard\" €99/month │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Full analysis suite, local file storage (.vrs on your │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ computer). EasyAuth sign-in (User.Read only), │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ browser-based access │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Plan: \"VariScout Team\" €299/month (TBD) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Everything in Standard, plus: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - OneDrive + SharePoint channel file storage │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Teams integration (SSO, sidebar, Adaptive Cards) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Mobile gemba companion (Field View + photo comments) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Requires: admin consent for Files.ReadWrite.All │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Offer type: Managed Application │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Billing: Microsoft (3% fee, monthly) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Customer access: Full control │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Publisher access: Disabled (zero access) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────┐│ VariScout on Azure Marketplace ││ ││ Offer: VariScout - Statistical Process Control ││ for Quality Teams ││ ││ Plan: "VariScout Standard" €99/month ││ Full analysis suite, local file storage (.vrs on your ││ computer). EasyAuth sign-in (User.Read only), ││ browser-based access ││ ││ Plan: "VariScout Team" €299/month (TBD) ││ Everything in Standard, plus: ││ - OneDrive + SharePoint channel file storage ││ - Teams integration (SSO, sidebar, Adaptive Cards) ││ - Mobile gemba companion (Field View + photo comments) ││ - Requires: admin consent for Files.ReadWrite.All ││ ││ Offer type: Managed Application ││ Billing: Microsoft (3% fee, monthly) ││ Customer access: Full control ││ Publisher access: Disabled (zero access) │└─────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"product-hierarchy\">Product Hierarchy\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#product-hierarchy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Hierarchy”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth>Role\u003C/th>\u003Cth>Distribution\u003C/th>\u003Cth>Price\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Azure App (Standard)\u003C/strong>\u003C/td>\u003Ctd>Full analysis, local files\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>€99/month (Managed Application)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Azure App (Team)\u003C/strong>\u003C/td>\u003Ctd>+ Teams, cloud collaboration, mobile\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>€299/month (TBD — price under evaluation)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>PWA\u003C/strong>\u003C/td>\u003Ctd>FREE (training & education)\u003C/td>\u003Ctd>Public website\u003C/td>\u003Ctd>Free forever (core analysis + Green Belt, copy-paste input, session-only)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note (Feb 2026):\u003C/strong> Excel Add-in shelved — cost with no revenue, unproven funnel. The PWA serves the same funnel role (free, no friction, shows the methodology) at zero marginal cost. See original 3-product strategy below for historical context.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"two-plan-technical-differentiation\">Two-Plan Technical Differentiation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#two-plan-technical-differentiation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two-Plan Technical Differentiation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The ARM template passes a \u003Ccode dir=\"auto\">VARISCOUT_PLAN\u003C/code> environment variable (\u003Ccode dir=\"auto\">standard\u003C/code> or \u003Ccode dir=\"auto\">team\u003C/code>). The existing \u003Ccode dir=\"auto\">getTier()\u003C/code> infrastructure resolves plan-appropriate feature sets — both plans deploy as \u003Ccode dir=\"auto\">enterprise\u003C/code> tier, but the Team plan unlocks Teams-specific capabilities.\u003C/p>\n\u003Cp>Same ARM template is reused across both plans (Azure Marketplace supports up to 100 plans per offer). The plan variable controls:\u003C/p>\n\u003Cul>\n\u003Cli>Storage mode: Standard = File System Access API (local \u003Ccode dir=\"auto\">.vrs\u003C/code> files, fallback to IndexedDB); Team = + OneDrive personal + SharePoint channel storage\u003C/li>\n\u003Cli>Teams SDK initialization (Team plan only)\u003C/li>\n\u003Cli>Channel file storage UI (Team plan only)\u003C/li>\n\u003Cli>Mobile Field View route (Team plan only)\u003C/li>\n\u003Cli>Photo capture in findings (Team plan only)\u003C/li>\n\u003Cli>Admin consent guidance in settings (Team plan only)\u003C/li>\n\u003C/ul>\n\u003Cp>See \u003Ca href=\"adr-016-teams-integration.md\">ADR-016\u003C/a> for full Teams integration technical design.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pricing-rationale\">Pricing Rationale\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pricing-rationale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pricing Rationale”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Standard\u003C/th>\u003Cth>Team\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Price\u003C/td>\u003Ctd>€99/month\u003C/td>\u003Ctd>€299/month (TBD)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Net (after 3%)\u003C/td>\u003Ctd>€96.03/month\u003C/td>\u003Ctd>€290.03/month\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Annual net\u003C/td>\u003Ctd>€1,152/year\u003C/td>\u003Ctd>€3,480/year\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Storage\u003C/td>\u003Ctd>Local files (File System Access API)\u003C/td>\u003Ctd>+ OneDrive + SharePoint\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Auth scopes\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">User.Read\u003C/code> only\u003C/td>\u003Ctd>+ \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Admin consent\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>Required (one-time)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Value\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Billing\u003C/td>\u003Ctd>Monthly only (Managed Application limitation)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Model\u003C/td>\u003Ctd>Per-deployment (one subscription per Azure tenant)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>Customer pays their own Azure infrastructure costs (App Service Plan, etc.) separately. Microsoft handles VAT/GST — prices are set excluding tax, Microsoft adds tax at checkout based on customer’s billing country (e.g., 24% ALV in Finland).\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Why per-deployment pricing\u003C/strong>: Managed Applications are per-deployment, not per-user. There is no mechanism to enforce user-count tiers within a tenant. Plans differentiate by capability (Standard vs Team), not by user count. Both plans include unlimited users in the tenant.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-managed-application\">Why Managed Application\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-managed-application\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Managed Application”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"offer-type-comparison\">Offer Type Comparison\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#offer-type-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Offer Type Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth align=\"center\">Solution Template\u003C/th>\u003Cth align=\"center\">Managed Application\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Microsoft-billed (transactable)\u003C/td>\u003Ctd align=\"center\">No\u003C/td>\u003Ctd align=\"center\">\u003Cstrong>Yes\u003C/strong> (3% fee)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Deploys to customer’s subscription\u003C/td>\u003Ctd align=\"center\">Yes\u003C/td>\u003Ctd align=\"center\">\u003Cstrong>Yes\u003C/strong> (managed RG)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data stays in customer’s tenant\u003C/td>\u003Ctd align=\"center\">Yes\u003C/td>\u003Ctd align=\"center\">\u003Cstrong>Yes\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Publisher access to customer\u003C/td>\u003Ctd align=\"center\">N/A\u003C/td>\u003Ctd align=\"center\">Optional (disabled)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No backend needed\u003C/td>\u003Ctd align=\"center\">Yes\u003C/td>\u003Ctd align=\"center\">\u003Cstrong>Yes\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Monthly pricing\u003C/td>\u003Ctd align=\"center\">N/A (free only)\u003C/td>\u003Ctd align=\"center\">\u003Cstrong>Yes\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"permission-model\">Permission Model\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#permission-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Permission Model”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Setting\u003C/th>\u003Cth>Configuration\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Publisher Management\u003C/td>\u003Ctd>\u003Cstrong>DISABLED\u003C/strong>\u003C/td>\u003Ctd>Zero publisher access to customer resources\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Customer Access\u003C/td>\u003Ctd>\u003Cstrong>ENABLED\u003C/strong>\u003C/td>\u003Ctd>Full customer control over their deployment\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>These settings are \u003Cstrong>immutable after publishing\u003C/strong> the offer in Partner Center.\u003C/p>\n\u003Cp>\u003Cstrong>Why disable publisher access\u003C/strong>: VariScout is a client-side SPA with no backend. There is nothing for the publisher to manage. Disabling access builds customer trust and simplifies compliance.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"managed-application-package\">Managed Application Package\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#managed-application-package\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Managed Application Package”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The deployment package is a \u003Ccode dir=\"auto\">.zip\u003C/code> file containing:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">variscout-managed-app.zip\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── mainTemplate.json # ARM template for resources\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── createUiDefinition.json # Azure portal deployment wizard\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"variscout-managed-app.zip├── mainTemplate.json # ARM template for resources└── createUiDefinition.json # Azure portal deployment wizard\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"benefits\">Benefits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#benefits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Benefits”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>No backend required\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>App deploys as Static Web App in customer’s managed resource group\u003C/li>\n\u003Cli>All processing in browser, data stays local\u003C/li>\n\u003Cli>Zero infrastructure to maintain\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Microsoft handles billing\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>3% transaction fee (lower than Paddle’s ~5% + VAT complexity)\u003C/li>\n\u003Cli>Automatic VAT handling in all Microsoft markets\u003C/li>\n\u003Cli>Enterprise procurement integration (purchase orders, invoicing)\u003C/li>\n\u003Cli>Monthly billing with automatic renewal\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Simplified product model\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Two paid plans (Standard + Team), one free product (PWA)\u003C/li>\n\u003Cli>No per-user tier confusion — plans differentiate by capability\u003C/li>\n\u003Cli>No license detection complexity\u003C/li>\n\u003Cli>GTM: “Try it free at variscout.com. When you’re ready for your team, get it on Azure Marketplace.”\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Distribution advantage\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Azure Marketplace visibility to enterprise buyers\u003C/li>\n\u003Cli>AppSource visibility for Excel Add-in\u003C/li>\n\u003Cli>Trust signal from Microsoft certification\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Data sovereignty\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>App deploys to customer’s Azure tenant\u003C/li>\n\u003Cli>Data never leaves their environment\u003C/li>\n\u003Cli>Meets enterprise compliance requirements\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"trade-offs\">Trade-offs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#trade-offs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Trade-offs”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Microsoft platform dependency\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Tied to Azure/Microsoft 365 ecosystem\u003C/li>\n\u003Cli>Subject to Microsoft certification requirements\u003C/li>\n\u003Cli>Marketplace listing approval process\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Monthly billing only\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Managed Applications do not support annual billing\u003C/li>\n\u003Cli>Monthly billing may create higher churn risk\u003C/li>\n\u003Cli>But also lower purchase friction (no large upfront commitment)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>PWA as free training tool\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>PWA repositioned as free variation analysis training and education tool\u003C/li>\n\u003Cli>Core analysis (I-Chart, Boxplot, Pareto, Capability, Regression) included\u003C/li>\n\u003Cli>No file upload, no save, no Performance Mode (Azure App differentiators)\u003C/li>\n\u003Cli>Copy-paste from Excel/Sheets + pre-loaded sample datasets\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Excel Add-in feature reduction\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Performance Mode removed from Excel (Azure App exclusive)\u003C/li>\n\u003Cli>Intentional to create clear upgrade incentive\u003C/li>\n\u003Cli>Core analysis remains fully functional\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>No per-user pricing\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Cannot charge differently based on team size\u003C/li>\n\u003Cli>Single plan must be attractive to both small teams and large organizations\u003C/li>\n\u003Cli>€99/month Standard is competitive: cheaper than most alternatives for teams >2 users\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"azure-app-tier-configuration\">Azure App Tier Configuration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-tier-configuration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App Tier Configuration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>License tier is set by deployment — all Managed Application deployments get full features:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Deployment writes tier to app configuration\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tier\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = import.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">meta\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">env\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VITE_LICENSE_TIER\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Always 'enterprise' for Managed App\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Deployment writes tier to app configurationconst tier = import.meta.env.VITE_LICENSE_TIER; // Always 'enterprise' for Managed App\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The existing \u003Ccode dir=\"auto\">tier.ts\u003C/code> infrastructure remains, with Managed Application deployments always configured as the highest tier.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"excel-add-in-shelved-feb-2026\">Excel Add-in: Shelved (Feb 2026)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#excel-add-in-shelved-feb-2026\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Excel Add-in: Shelved (Feb 2026)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Excel Add-in was originally planned as a free marketing funnel product on AppSource. It was shelved because:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Cost with no revenue\u003C/strong> — AppSource certification, Office.js maintenance, Fluent UI theming\u003C/li>\n\u003Cli>\u003Cstrong>Unproven funnel\u003C/strong> — No evidence Excel users convert to Azure App purchasers\u003C/li>\n\u003Cli>\u003Cstrong>PWA does the same job\u003C/strong> — Free, no friction, shows the methodology, costs nothing extra to maintain\u003C/li>\n\u003Cli>\u003Cstrong>Simpler GTM\u003C/strong> — Two products (free PWA + paid Azure) is easier to explain than three\u003C/li>\n\u003C/ol>\n\u003Cp>The codebase (\u003Ccode dir=\"auto\">apps/excel-addin/\u003C/code>) was removed. Historical documentation preserved in this ADR for context.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"migration-path\">Migration Path\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#migration-path\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Migration Path”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"for-pwa-users\">For PWA Users\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#for-pwa-users\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “For PWA Users”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>PWA is a genuine free product for training and education\u003C/li>\n\u003Cli>Core analysis + Green Belt tools always available\u003C/li>\n\u003Cli>Copy-paste from Excel/Sheets for own data analysis\u003C/li>\n\u003Cli>Upgrade to Azure App for file upload, save, Performance Mode, and team features\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"for-new-customers\">For New Customers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#for-new-customers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “For New Customers”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Start with free PWA at variscout.com (training & education)\u003C/li>\n\u003Cli>Azure Marketplace for full-featured deployment (from €99/month)\u003C/li>\n\u003Cli>Clear upgrade path from free PWA to Azure App\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation-phases\">Implementation Phases\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-phases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation Phases”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-1-documentation-this-revision\">Phase 1: Documentation (This Revision)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-1-documentation-this-revision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 1: Documentation (This Revision)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Updated all documentation to reflect Managed Application model\u003C/li>\n\u003Cli>Simplified Excel Add-in strategy (free forever, no license detection)\u003C/li>\n\u003Cli>Updated pricing to single plan at €150/month\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-2-core-tier-infrastructure-complete\">Phase 2: Core Tier Infrastructure (Complete)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-core-tier-infrastructure-complete\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2: Core Tier Infrastructure (Complete)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Created \u003Ccode dir=\"auto\">packages/core/src/tier.ts\u003C/code> with tier configuration\u003C/li>\n\u003Cli>Implemented \u003Ccode dir=\"auto\">getTier()\u003C/code>, \u003Ccode dir=\"auto\">isPaidTier()\u003C/code>, \u003Ccode dir=\"auto\">getMaxChannels()\u003C/code> functions\u003C/li>\n\u003Cli>Created \u003Ccode dir=\"auto\">packages/hooks/src/useTier.ts\u003C/code> React hook\u003C/li>\n\u003Cli>Added \u003Ccode dir=\"auto\">TierBadge\u003C/code> and \u003Ccode dir=\"auto\">UpgradePrompt\u003C/code> UI components\u003C/li>\n\u003Cli>Integrated tier-aware channel limits (5 free / 1,500 paid)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-3-azure-marketplace-q2-2026\">Phase 3: Azure Marketplace (Q2 2026)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3-azure-marketplace-q2-2026\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3: Azure Marketplace (Q2 2026)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Partner Center account setup\u003C/li>\n\u003Cli>Managed Application offer creation\u003C/li>\n\u003Cli>Deployment package (mainTemplate.json + createUiDefinition.json)\u003C/li>\n\u003Cli>Standard plan at €99/month\u003C/li>\n\u003Cli>Certification and launch\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-4-excel-add-in-shelved-feb-2026\">Phase 4: Excel Add-in Shelved (Feb 2026)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-4-excel-add-in-shelved-feb-2026\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 4: Excel Add-in Shelved (Feb 2026)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Excel Add-in codebase removed\u003C/li>\n\u003Cli>AppSource submission cancelled\u003C/li>\n\u003Cli>PWA serves as the sole free funnel product\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-5-team-plan--teams-integration-tbd\">Phase 5: Team Plan & Teams Integration (TBD)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-5-team-plan--teams-integration-tbd\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 5: Team Plan & Teams Integration (TBD)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Add second Marketplace plan (“VariScout Team” at €299/month, price TBD)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">VARISCOUT_PLAN\u003C/code> environment variable in ARM template\u003C/li>\n\u003Cli>Teams SDK integration (SSO, channel tabs, Adaptive Cards)\u003C/li>\n\u003Cli>Shared channel file storage (SharePoint) with optimistic merge\u003C/li>\n\u003Cli>Mobile Field View (\u003Ccode dir=\"auto\">/field\u003C/code> route) for gemba investigations\u003C/li>\n\u003Cli>Photo comments on findings (camera capture + channel storage)\u003C/li>\n\u003Cli>Azure Function for On-Behalf-Of token exchange\u003C/li>\n\u003Cli>See \u003Ca href=\"adr-016-teams-integration.md\">ADR-016\u003C/a> for phased delivery breakdown\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-decisions\">Related Decisions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-decisions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Decisions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"adr-006-edition-system.md\">ADR-006: Edition System\u003C/a> - Superseded, kept for historical context\u003C/li>\n\u003Cli>\u003Ca href=\"adr-004-offline-first.md\">ADR-004: Offline-First\u003C/a> - Unchanged, still applies\u003C/li>\n\u003Cli>\u003Ca href=\"adr-016-teams-integration.md\">ADR-016: Teams Integration\u003C/a> - Technical design for Team plan capabilities\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../08-products/azure/marketplace.md\">Azure Marketplace Guide\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/azure/pricing-tiers.md\">Pricing Tiers\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/azure/arm-template.md\">ARM Template\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2334, + "localImagePaths": 2406, + "remoteImagePaths": 2407, + "frontmatter": 2408, + "imagePaths": 2409 + }, + [ + 2335, 2337, 2338, 2341, 2344, 2345, 2348, 2351, 2354, 2357, 2360, 2363, 2366, 2367, 2368, 2369, + 2372, 2375, 2378, 2381, 2384, 2387, 2390, 2393, 2396, 2399, 2402, 2405 + ], + { "depth": 30, "slug": 2336, "text": 2324 }, + "adr-007-azure-marketplace-distribution-strategy", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 79, "slug": 2339, "text": 2340 }, + "revision-context-2026-02-27", + "Revision Context (2026-02-27)", + { "depth": 79, "slug": 2342, "text": 2343 }, + "revision-context-2026-02-13", + "Revision Context (2026-02-13)", + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2346, "text": 2347 }, + "product-hierarchy", + "Product Hierarchy", + { "depth": 79, "slug": 2349, "text": 2350 }, + "two-plan-technical-differentiation", + "Two-Plan Technical Differentiation", + { "depth": 79, "slug": 2352, "text": 2353 }, + "pricing-rationale", + "Pricing Rationale", + { "depth": 33, "slug": 2355, "text": 2356 }, + "why-managed-application", + "Why Managed Application", + { "depth": 79, "slug": 2358, "text": 2359 }, + "offer-type-comparison", + "Offer Type Comparison", + { "depth": 79, "slug": 2361, "text": 2362 }, + "permission-model", + "Permission Model", + { "depth": 79, "slug": 2364, "text": 2365 }, + "managed-application-package", + "Managed Application Package", + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2156, "text": 2157 }, + { "depth": 79, "slug": 2159, "text": 2160 }, + { "depth": 33, "slug": 2370, "text": 2371 }, + "azure-app-tier-configuration", + "Azure App Tier Configuration", + { "depth": 33, "slug": 2373, "text": 2374 }, + "excel-add-in-shelved-feb-2026", + "Excel Add-in: Shelved (Feb 2026)", + { "depth": 33, "slug": 2376, "text": 2377 }, + "migration-path", + "Migration Path", + { "depth": 79, "slug": 2379, "text": 2380 }, + "for-pwa-users", + "For PWA Users", + { "depth": 79, "slug": 2382, "text": 2383 }, + "for-new-customers", + "For New Customers", + { "depth": 33, "slug": 2385, "text": 2386 }, + "implementation-phases", + "Implementation Phases", + { "depth": 79, "slug": 2388, "text": 2389 }, + "phase-1-documentation-this-revision", + "Phase 1: Documentation (This Revision)", + { "depth": 79, "slug": 2391, "text": 2392 }, + "phase-2-core-tier-infrastructure-complete", + "Phase 2: Core Tier Infrastructure (Complete)", + { "depth": 79, "slug": 2394, "text": 2395 }, + "phase-3-azure-marketplace-q2-2026", + "Phase 3: Azure Marketplace (Q2 2026)", + { "depth": 79, "slug": 2397, "text": 2398 }, + "phase-4-excel-add-in-shelved-feb-2026", + "Phase 4: Excel Add-in Shelved (Feb 2026)", + { "depth": 79, "slug": 2400, "text": 2401 }, + "phase-5-team-plan--teams-integration-tbd", + "Phase 5: Team Plan & Teams Integration (TBD)", + { "depth": 33, "slug": 2403, "text": 2404 }, + "related-decisions", + "Related Decisions", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2324 }, + [], + "07-decisions/adr-008-website-content-architecture", + { "id": 2410, "data": 2412, "body": 2417, "filePath": 2418, "digest": 2419, "rendered": 2420 }, + { + "title": 2413, + "editUrl": 16, + "head": 2414, + "template": 18, + "sidebar": 2415, + "pagefind": 16, + "draft": 20 + }, + "ADR-008: Website Content Architecture", + [], + { "hidden": 20, "attrs": 2416 }, + {}, + "# ADR-008: Website Content Architecture\n\n**Status**: Accepted\n\n**Date**: 2026-02-13\n\n---\n\n## Context\n\nVariScout's marketing website (variscout.com) needs to evolve from a basic product site into a comprehensive content platform that serves three distinct audiences:\n\n1. **Cold visitors** — Quality professionals searching Google for SPC concepts, capability analysis, or specific industry problems\n2. **Warm evaluators** — Professionals comparing tools, looking for proof that VariScout solves their specific use case\n3. **App users** — Current PWA/Azure/Excel users who arrive via \"Learn more\" links from HelpTooltip (i) icons\n\nThe 13 strategic use cases identified in `docs/02-journeys/use-cases/` need to become rich, interactive landing pages. The existing tool pages (7), learn topics (11), glossary terms (35+), and case studies (10) need better cross-linking to form a cohesive content web.\n\n### Benchmarks Considered\n\nSix design philosophies were evaluated against world-class benchmarks:\n\n| Philosophy | Benchmark | Strength | Weakness for VariScout |\n| ---------------------------- | ---------------------------- | ------------------------------- | ----------------------- |\n| Playground (tool-first) | Desmos, Observable | Maximum conversion, viral | Weak SEO, no narrative |\n| Academy (education-first) | Moz, Ahrefs, Khan Academy | Strongest SEO, authority | Slow conversion |\n| Showcase (problem-first) | Stripe, Linear, Notion | Highest professional conversion | Weak for education |\n| Community (user-generated) | Figma, Canva, Webflow | Scales organically | Requires critical mass |\n| Progressive Reveal (layered) | Loom, Mixpanel, Datadog | Serves all intents | Complex navigation |\n| Swiss Army (tool collection) | Ahrefs Tools, OmniCalculator | Maximum SEO surface | Fragments product story |\n\n### Minitab's Three-Layer Architecture\n\nMinitab separates content across three properties:\n\n1. **In-App Assistant** — Decision trees, simplified dialogs, embedded definitions\n2. **support.minitab.com** — 4-page reference per topic (Before You Start -> How To -> Interpret -> Methods)\n3. **minitab.com** — Marketing site with product pages, pricing, testimonials\n\nVariScout unifies all three on one domain (better for SEO) and adds interactive charts (which Minitab lacks on the web).\n\n---\n\n## Decision\n\nAdopt the **\"Guided Problem Playground\"** philosophy — a hybrid of Showcase + Playground + Contextual Learning — organized into **three content surfaces** on one domain.\n\n### Three Surfaces\n\n**Surface 1: Showcase (Acquisition)**\n\n- Pages: Homepage, 13 use case pages, product pages, pricing\n- Audience: Cold visitors from search, referrals, social\n- Character: Problem-first headlines, live interactive demos, professional framing\n- Primary CTA: \"Try with your data\" -> PWA\n\n**Surface 2: Reference (Learning & Help)**\n\n- Pages: 7 tool pages, 11 learn topics, 35+ glossary terms\n- Audience: Both cold searchers AND warm app users (via HelpTooltip \"Learn more\")\n- Character: Clean, focused, reference-first with live charts\n- Primary CTA: \"See this in context\" -> relevant use case or case study\n\n**Surface 3: Proof (Case Studies)**\n\n- Pages: 10 case studies\n- Audience: Evaluators comparing tools, curious visitors\n- Character: 3-act narrative with interactive data exploration\n- Primary CTA: \"Try it yourself\" -> PWA with same dataset\n\n### Three Pillars\n\n1. **Problem-First** — Every use case page opens with a professional's pain point, not a feature list\n2. **Live Proof** — The demo is the actual chart with real data, not a screenshot or video\n3. **Contextual Depth** — Learning is woven in via HelpTooltip (i) and collapsible sections, not a separate academy\n\n### Cross-Linking Strategy\n\nAll content types link bidirectionally:\n\n- Use cases -> tool pages, case studies, glossary terms\n- Tool pages -> case studies (\"See it in action\"), use cases (\"Industries using this\")\n- Learn pages -> case studies (\"See it in practice\")\n- Case studies -> use cases, tool pages\n- Glossary -> tool pages, learn pages (already exists)\n\n### Data Architecture\n\nContent follows the established TypeScript data file pattern:\n\n- `useCaseData.ts` — 13 use case entries (new)\n- `toolsData.ts` — 7 tools (add `relatedCases` field)\n- `learnData.ts` — 10 topics (add `relatedCases` field)\n- `glossaryData.ts` — 35+ terms (unchanged for now)\n\n---\n\n## Consequences\n\n### Positive\n\n- 13 new SEO-optimized landing pages targeting high-value keyword clusters\n- Bidirectional cross-links increase time-on-site and internal link equity\n- Live chart demos differentiate from competitors (Minitab, JMP have static screenshots)\n- Existing content (tools, learn, glossary, cases) gains new traffic through cross-links\n- \"Guided Problem Playground\" serves both education and professional audiences\n\n### Negative\n\n- 6 new sample datasets needed for use cases without matching data\n- Significant content effort per use case (problem narrative, journey, before/after)\n- Navigation complexity increases with \"Solutions\" dropdown\n- Cross-link maintenance burden grows as content types multiply\n\n### Risks\n\n- Use case pages may cannibalize existing tool page traffic (mitigated: different intent)\n- Navigation could become confusing with three surfaces (mitigated: clear URL structure and dropdown design)\n\n---\n\n## Alternatives Rejected\n\n- **Pure Academy** — Too slow for professional conversion; education should be embedded, not structural\n- **Pure Playground** — Weak SEO; no narrative context for search traffic\n- **Community model** — Requires critical mass that VariScout doesn't yet have\n- **Separate subdomain** — Splits domain authority; one domain is better for SEO\n\n---\n\n## References\n\n- [Use Cases Documentation](../02-journeys/use-cases/index.md)\n- [Website Design Philosophy](../08-products/website/design-philosophy.md)\n- [Website Content Architecture](../08-products/website/content-architecture.md)", + "src/content/docs/07-decisions/adr-008-website-content-architecture.md", + "2f9c7eba3d2898eb", + { "html": 2421, "metadata": 2422 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-008-website-content-architecture\">ADR-008: Website Content Architecture\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-008-website-content-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-008: Website Content Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Accepted\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2026-02-13\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s marketing website (variscout.com) needs to evolve from a basic product site into a comprehensive content platform that serves three distinct audiences:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Cold visitors\u003C/strong> — Quality professionals searching Google for SPC concepts, capability analysis, or specific industry problems\u003C/li>\n\u003Cli>\u003Cstrong>Warm evaluators\u003C/strong> — Professionals comparing tools, looking for proof that VariScout solves their specific use case\u003C/li>\n\u003Cli>\u003Cstrong>App users\u003C/strong> — Current PWA/Azure/Excel users who arrive via “Learn more” links from HelpTooltip (i) icons\u003C/li>\n\u003C/ol>\n\u003Cp>The 13 strategic use cases identified in \u003Ccode dir=\"auto\">docs/02-journeys/use-cases/\u003C/code> need to become rich, interactive landing pages. The existing tool pages (7), learn topics (11), glossary terms (35+), and case studies (10) need better cross-linking to form a cohesive content web.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"benchmarks-considered\">Benchmarks Considered\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#benchmarks-considered\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Benchmarks Considered”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Six design philosophies were evaluated against world-class benchmarks:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Philosophy\u003C/th>\u003Cth>Benchmark\u003C/th>\u003Cth>Strength\u003C/th>\u003Cth>Weakness for VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Playground (tool-first)\u003C/td>\u003Ctd>Desmos, Observable\u003C/td>\u003Ctd>Maximum conversion, viral\u003C/td>\u003Ctd>Weak SEO, no narrative\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Academy (education-first)\u003C/td>\u003Ctd>Moz, Ahrefs, Khan Academy\u003C/td>\u003Ctd>Strongest SEO, authority\u003C/td>\u003Ctd>Slow conversion\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Showcase (problem-first)\u003C/td>\u003Ctd>Stripe, Linear, Notion\u003C/td>\u003Ctd>Highest professional conversion\u003C/td>\u003Ctd>Weak for education\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Community (user-generated)\u003C/td>\u003Ctd>Figma, Canva, Webflow\u003C/td>\u003Ctd>Scales organically\u003C/td>\u003Ctd>Requires critical mass\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Progressive Reveal (layered)\u003C/td>\u003Ctd>Loom, Mixpanel, Datadog\u003C/td>\u003Ctd>Serves all intents\u003C/td>\u003Ctd>Complex navigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Swiss Army (tool collection)\u003C/td>\u003Ctd>Ahrefs Tools, OmniCalculator\u003C/td>\u003Ctd>Maximum SEO surface\u003C/td>\u003Ctd>Fragments product story\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"minitabs-three-layer-architecture\">Minitab’s Three-Layer Architecture\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#minitabs-three-layer-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Minitab’s Three-Layer Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Minitab separates content across three properties:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>In-App Assistant\u003C/strong> — Decision trees, simplified dialogs, embedded definitions\u003C/li>\n\u003Cli>\u003Cstrong>support.minitab.com\u003C/strong> — 4-page reference per topic (Before You Start -> How To -> Interpret -> Methods)\u003C/li>\n\u003Cli>\u003Cstrong>minitab.com\u003C/strong> — Marketing site with product pages, pricing, testimonials\u003C/li>\n\u003C/ol>\n\u003Cp>VariScout unifies all three on one domain (better for SEO) and adds interactive charts (which Minitab lacks on the web).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Adopt the \u003Cstrong>“Guided Problem Playground”\u003C/strong> philosophy — a hybrid of Showcase + Playground + Contextual Learning — organized into \u003Cstrong>three content surfaces\u003C/strong> on one domain.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"three-surfaces\">Three Surfaces\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#three-surfaces\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Three Surfaces”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Surface 1: Showcase (Acquisition)\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Pages: Homepage, 13 use case pages, product pages, pricing\u003C/li>\n\u003Cli>Audience: Cold visitors from search, referrals, social\u003C/li>\n\u003Cli>Character: Problem-first headlines, live interactive demos, professional framing\u003C/li>\n\u003Cli>Primary CTA: “Try with your data” -> PWA\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Surface 2: Reference (Learning & Help)\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Pages: 7 tool pages, 11 learn topics, 35+ glossary terms\u003C/li>\n\u003Cli>Audience: Both cold searchers AND warm app users (via HelpTooltip “Learn more”)\u003C/li>\n\u003Cli>Character: Clean, focused, reference-first with live charts\u003C/li>\n\u003Cli>Primary CTA: “See this in context” -> relevant use case or case study\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Surface 3: Proof (Case Studies)\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Pages: 10 case studies\u003C/li>\n\u003Cli>Audience: Evaluators comparing tools, curious visitors\u003C/li>\n\u003Cli>Character: 3-act narrative with interactive data exploration\u003C/li>\n\u003Cli>Primary CTA: “Try it yourself” -> PWA with same dataset\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"three-pillars\">Three Pillars\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#three-pillars\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Three Pillars”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Problem-First\u003C/strong> — Every use case page opens with a professional’s pain point, not a feature list\u003C/li>\n\u003Cli>\u003Cstrong>Live Proof\u003C/strong> — The demo is the actual chart with real data, not a screenshot or video\u003C/li>\n\u003Cli>\u003Cstrong>Contextual Depth\u003C/strong> — Learning is woven in via HelpTooltip (i) and collapsible sections, not a separate academy\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cross-linking-strategy\">Cross-Linking Strategy\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cross-linking-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Linking Strategy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All content types link bidirectionally:\u003C/p>\n\u003Cul>\n\u003Cli>Use cases -> tool pages, case studies, glossary terms\u003C/li>\n\u003Cli>Tool pages -> case studies (“See it in action”), use cases (“Industries using this”)\u003C/li>\n\u003Cli>Learn pages -> case studies (“See it in practice”)\u003C/li>\n\u003Cli>Case studies -> use cases, tool pages\u003C/li>\n\u003Cli>Glossary -> tool pages, learn pages (already exists)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-architecture\">Data Architecture\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Content follows the established TypeScript data file pattern:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">useCaseData.ts\u003C/code> — 13 use case entries (new)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">toolsData.ts\u003C/code> — 7 tools (add \u003Ccode dir=\"auto\">relatedCases\u003C/code> field)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">learnData.ts\u003C/code> — 10 topics (add \u003Ccode dir=\"auto\">relatedCases\u003C/code> field)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">glossaryData.ts\u003C/code> — 35+ terms (unchanged for now)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"positive\">Positive\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#positive\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Positive”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>13 new SEO-optimized landing pages targeting high-value keyword clusters\u003C/li>\n\u003Cli>Bidirectional cross-links increase time-on-site and internal link equity\u003C/li>\n\u003Cli>Live chart demos differentiate from competitors (Minitab, JMP have static screenshots)\u003C/li>\n\u003Cli>Existing content (tools, learn, glossary, cases) gains new traffic through cross-links\u003C/li>\n\u003Cli>“Guided Problem Playground” serves both education and professional audiences\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"negative\">Negative\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#negative\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Negative”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>6 new sample datasets needed for use cases without matching data\u003C/li>\n\u003Cli>Significant content effort per use case (problem narrative, journey, before/after)\u003C/li>\n\u003Cli>Navigation complexity increases with “Solutions” dropdown\u003C/li>\n\u003Cli>Cross-link maintenance burden grows as content types multiply\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"risks\">Risks\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#risks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Risks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Use case pages may cannibalize existing tool page traffic (mitigated: different intent)\u003C/li>\n\u003Cli>Navigation could become confusing with three surfaces (mitigated: clear URL structure and dropdown design)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"alternatives-rejected\">Alternatives Rejected\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#alternatives-rejected\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Alternatives Rejected”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Pure Academy\u003C/strong> — Too slow for professional conversion; education should be embedded, not structural\u003C/li>\n\u003Cli>\u003Cstrong>Pure Playground\u003C/strong> — Weak SEO; no narrative context for search traffic\u003C/li>\n\u003Cli>\u003Cstrong>Community model\u003C/strong> — Requires critical mass that VariScout doesn’t yet have\u003C/li>\n\u003Cli>\u003Cstrong>Separate subdomain\u003C/strong> — Splits domain authority; one domain is better for SEO\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"references\">References\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../02-journeys/use-cases/index.md\">Use Cases Documentation\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/website/design-philosophy.md\">Website Design Philosophy\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/website/content-architecture.md\">Website Content Architecture\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2423, + "localImagePaths": 2458, + "remoteImagePaths": 2459, + "frontmatter": 2460, + "imagePaths": 2461 + }, + [2424, 2426, 2427, 2430, 2433, 2434, 2437, 2440, 2441, 2444, 2445, 2448, 2451, 2454, 2457], + { "depth": 30, "slug": 2425, "text": 2413 }, + "adr-008-website-content-architecture", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 79, "slug": 2428, "text": 2429 }, + "benchmarks-considered", + "Benchmarks Considered", + { "depth": 79, "slug": 2431, "text": 2432 }, + "minitabs-three-layer-architecture", + "Minitab’s Three-Layer Architecture", + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2435, "text": 2436 }, + "three-surfaces", + "Three Surfaces", + { "depth": 79, "slug": 2438, "text": 2439 }, + "three-pillars", + "Three Pillars", + { "depth": 79, "slug": 931, "text": 932 }, + { "depth": 79, "slug": 2442, "text": 2443 }, + "data-architecture", + "Data Architecture", + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2446, "text": 2447 }, + "positive", + "Positive", + { "depth": 79, "slug": 2449, "text": 2450 }, + "negative", + "Negative", + { "depth": 79, "slug": 2452, "text": 2453 }, + "risks", + "Risks", + { "depth": 33, "slug": 2455, "text": 2456 }, + "alternatives-rejected", + "Alternatives Rejected", + { "depth": 33, "slug": 878, "text": 879 }, + [], + [], + { "title": 2413 }, + [], + "07-decisions/adr-009-boxplot-violin-mode", + { "id": 2462, "data": 2464, "body": 2469, "filePath": 2470, "digest": 2471, "rendered": 2472 }, + { + "title": 2465, + "editUrl": 16, + "head": 2466, + "template": 18, + "sidebar": 2467, + "pagefind": 16, + "draft": 20 + }, + "ADR-009: Boxplot Violin Mode", + [], + { "hidden": 20, "attrs": 2468 }, + {}, + "# ADR-009: Boxplot Violin Mode\n\n**Status:** Accepted\n**Date:** 2026-02-16\n**Deciders:** Product team\n\n## Context\n\nBoxplots are the primary chart in the FLOW lens for factor comparison. They show quartiles, median, whiskers, and outliers but completely hide the distribution shape. Bimodal data, skewness, and clustering are invisible in standard box elements.\n\nQuality professionals need to see distribution shape to identify mixed populations (e.g., two operators with different settings creating bimodal output) before drilling down.\n\n## Decision\n\nAdd a violin plot toggle to boxplot charts that overlays KDE-based density curves behind the box elements.\n\n### Key choices:\n\n1. **Toggle over separate chart** -- Distribution shape is context for boxplot comparison, not a separate analysis step. Adding it as a toggle keeps the workflow linear.\n\n2. **Gaussian kernel with Silverman's rule-of-thumb bandwidth** -- Industry standard, well-understood, no tuning parameters. Formula: `h = 0.9 * min(stdDev, IQR/1.34) * n^(-1/5)`.\n\n3. **`@visx/stats` ViolinPlot component** -- Already installed (`^3.12.0`), renders mirrored SVG path from `{ value, count }[]` data. No new dependencies.\n\n4. **Controlled via `displayOptions.showViolin`** -- Follows the established pattern for user-togglable chart features (like `showContributionLabels`, `showControlLimits`).\n\n5. **Platform parity: PWA + Azure, not Excel** -- Excel Add-in provides core analysis only per [ADR-007](adr-007-azure-marketplace-distribution.md).\n\n## Implementation\n\n- `calculateKDE()` added to `@variscout/core/stats.ts` (pure math, no React dependency)\n - Gaussian kernel with Silverman's rule-of-thumb bandwidth (matches R/ggplot2 and Plotly)\n - Evaluation range extends 3 bandwidths beyond data (matches R/ggplot2 `cut=3` default)\n - 100 evaluation points (smooth curves for bimodal distributions, negligible cost)\n- `showViolin` prop added to `BoxplotProps` and `PerformanceBoxplotProps` in `@variscout/charts`\n- **Violin-primary rendering** (industry standard, matching Seaborn/Plotly/ggplot2):\n - Density curve is the dominant shape (wide, 0.35 fill opacity, 0.7 stroke opacity)\n - Thin inner IQR box (20% of band width) shows Q1-Q3 range inside the violin\n - Median line spans thin box only\n - Mean diamond centered inside violin\n - Whiskers, whisker caps, and outlier circles are hidden (replaced by the density curve)\n- Memoized KDE computation per group/channel\n- Settings toggle: \"Show distribution shape\" in PWA Settings Panel\n\n## Consequences\n\n- Users can identify bimodal distributions and skewness before committing to a drill-down path\n- No performance impact when disabled (KDE not computed)\n- Violin-primary rendering matches industry tools (Seaborn, Plotly, ggplot2) — familiar to quality professionals\n- Persists across drill-down navigation via `displayOptions` state\n\n## See Also\n\n- [Boxplot Feature](../03-features/analysis/boxplot.md)\n- [Boxplot Design System](../06-design-system/charts/boxplot.md)\n- [FLOW Lens](../01-vision/four-lenses/flow.md)", + "src/content/docs/07-decisions/adr-009-boxplot-violin-mode.md", + "3e0ef33a884812d8", + { "html": 2473, "metadata": 2474 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-009-boxplot-violin-mode\">ADR-009: Boxplot Violin Mode\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-009-boxplot-violin-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-009: Boxplot Violin Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status:\u003C/strong> Accepted\n\u003Cstrong>Date:\u003C/strong> 2026-02-16\n\u003Cstrong>Deciders:\u003C/strong> Product team\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Boxplots are the primary chart in the FLOW lens for factor comparison. They show quartiles, median, whiskers, and outliers but completely hide the distribution shape. Bimodal data, skewness, and clustering are invisible in standard box elements.\u003C/p>\n\u003Cp>Quality professionals need to see distribution shape to identify mixed populations (e.g., two operators with different settings creating bimodal output) before drilling down.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Add a violin plot toggle to boxplot charts that overlays KDE-based density curves behind the box elements.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-choices\">Key choices:\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-choices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key choices:”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Toggle over separate chart\u003C/strong> — Distribution shape is context for boxplot comparison, not a separate analysis step. Adding it as a toggle keeps the workflow linear.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Gaussian kernel with Silverman’s rule-of-thumb bandwidth\u003C/strong> — Industry standard, well-understood, no tuning parameters. Formula: \u003Ccode dir=\"auto\">h = 0.9 * min(stdDev, IQR/1.34) * n^(-1/5)\u003C/code>.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>\u003Ccode dir=\"auto\">@visx/stats\u003C/code> ViolinPlot component\u003C/strong> — Already installed (\u003Ccode dir=\"auto\">^3.12.0\u003C/code>), renders mirrored SVG path from \u003Ccode dir=\"auto\">{ value, count }[]\u003C/code> data. No new dependencies.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Controlled via \u003Ccode dir=\"auto\">displayOptions.showViolin\u003C/code>\u003C/strong> — Follows the established pattern for user-togglable chart features (like \u003Ccode dir=\"auto\">showContributionLabels\u003C/code>, \u003Ccode dir=\"auto\">showControlLimits\u003C/code>).\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Platform parity: PWA + Azure, not Excel\u003C/strong> — Excel Add-in provides core analysis only per \u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a>.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation\">Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">calculateKDE()\u003C/code> added to \u003Ccode dir=\"auto\">@variscout/core/stats.ts\u003C/code> (pure math, no React dependency)\n\u003Cul>\n\u003Cli>Gaussian kernel with Silverman’s rule-of-thumb bandwidth (matches R/ggplot2 and Plotly)\u003C/li>\n\u003Cli>Evaluation range extends 3 bandwidths beyond data (matches R/ggplot2 \u003Ccode dir=\"auto\">cut=3\u003C/code> default)\u003C/li>\n\u003Cli>100 evaluation points (smooth curves for bimodal distributions, negligible cost)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">showViolin\u003C/code> prop added to \u003Ccode dir=\"auto\">BoxplotProps\u003C/code> and \u003Ccode dir=\"auto\">PerformanceBoxplotProps\u003C/code> in \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Violin-primary rendering\u003C/strong> (industry standard, matching Seaborn/Plotly/ggplot2):\n\u003Cul>\n\u003Cli>Density curve is the dominant shape (wide, 0.35 fill opacity, 0.7 stroke opacity)\u003C/li>\n\u003Cli>Thin inner IQR box (20% of band width) shows Q1-Q3 range inside the violin\u003C/li>\n\u003Cli>Median line spans thin box only\u003C/li>\n\u003Cli>Mean diamond centered inside violin\u003C/li>\n\u003Cli>Whiskers, whisker caps, and outlier circles are hidden (replaced by the density curve)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>Memoized KDE computation per group/channel\u003C/li>\n\u003Cli>Settings toggle: “Show distribution shape” in PWA Settings Panel\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Users can identify bimodal distributions and skewness before committing to a drill-down path\u003C/li>\n\u003Cli>No performance impact when disabled (KDE not computed)\u003C/li>\n\u003Cli>Violin-primary rendering matches industry tools (Seaborn, Plotly, ggplot2) — familiar to quality professionals\u003C/li>\n\u003Cli>Persists across drill-down navigation via \u003Ccode dir=\"auto\">displayOptions\u003C/code> state\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../03-features/analysis/boxplot.md\">Boxplot Feature\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../06-design-system/charts/boxplot.md\">Boxplot Design System\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../01-vision/four-lenses/flow.md\">FLOW Lens\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2475, + "localImagePaths": 2486, + "remoteImagePaths": 2487, + "frontmatter": 2488, + "imagePaths": 2489 + }, + [2476, 2478, 2479, 2480, 2483, 2484, 2485], + { "depth": 30, "slug": 2477, "text": 2465 }, + "adr-009-boxplot-violin-mode", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2481, "text": 2482 }, + "key-choices", + "Key choices:", + { "depth": 33, "slug": 1885, "text": 1886 }, + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2465 }, + [], + "07-decisions/adr-010-gagerr-deferral", + { "id": 2490, "data": 2492, "body": 2497, "filePath": 2498, "digest": 2499, "rendered": 2500 }, + { + "title": 2493, + "editUrl": 16, + "head": 2494, + "template": 18, + "sidebar": 2495, + "pagefind": 16, + "draft": 20 + }, + "ADR-010: Defer Gage R&R from Azure App v1", + [], + { "hidden": 20, "attrs": 2496 }, + {}, + "# ADR-010: Defer Gage R&R from Azure App v1\n\n**Status:** Superseded\n**Date:** 2026-02-16\n**Supersedes:** None\n**Related:** [ADR-007](adr-007-azure-marketplace-distribution.md) (distribution strategy)\n\n---\n\n## Context\n\nVariScout includes a Gage R&R (Measurement System Analysis) implementation shared across the PWA and Azure App via `@variscout/core`, `@variscout/charts`, and `@variscout/ui`. A systematic evaluation revealed the current implementation is solid for learning but MVP-level for paying customers.\n\n### What Works Well (Learning Context)\n\n- ANOVA math is correct (%GRR via variance components)\n- Interaction plot visualises operator-by-part patterns\n- Auto-detection of operator/part columns reduces setup friction\n- Educational tooltips explain MSA concepts in context\n- Sufficient for Green Belt training exercises\n\n### Gap Analysis for Production MSA\n\nGaps are ordered by impact on paying users:\n\n#### Tier 1 - Expected by any MSA practitioner\n\n| Gap | Impact |\n| ------------------------------------------- | ------------------------------------------------------- |\n| No %Tolerance (%GRR relative to spec range) | Cannot assess measurement system acceptability per AIAG |\n| No NDC (Number of Distinct Categories) | Missing key acceptance criterion (NDC >= 5) |\n| No F-tests with p-values | Cannot determine statistical significance of sources |\n| No X-bar/R control charts | Standard MSA deliverable missing |\n\n#### Tier 2 - Expected by quality engineers\n\n| Gap | Impact |\n| ------------------------------- | ---------------------------------------------- |\n| No confidence intervals on %GRR | Cannot quantify uncertainty in the measurement |\n| No formal report export | Engineers need documented results for audits |\n| No multi-study comparison | Cannot track measurement system over time |\n\n#### Tier 3 - Competitive differentiation\n\n| Gap | Impact |\n| ------------------------------------ | ------------------------------- |\n| No crossed vs nested study selection | Limits study design flexibility |\n| No attribute agreement analysis | Only handles continuous data |\n| No linearity/bias study | Incomplete MSA coverage |\n\n### Competitive Landscape\n\nMinitab, JMP, and dedicated MSA tools all include Tier 1 features as baseline. Shipping without them would be immediately noticed by quality professionals evaluating the Azure App at EUR 150/month.\n\n## Decision\n\n**Defer Gage R&R from Azure App v1. Keep it in the PWA (free, learning-appropriate).**\n\n### Rationale\n\n1. **Credibility risk**: Half-baked MSA undermines trust in the entire tool. Quality professionals will judge VariScout's statistical rigour by its weakest feature.\n2. **PWA fit**: The current implementation is genuinely useful for training. Green Belt students learning MSA concepts benefit from the interactive visualization.\n3. **Low demand signal**: No customer has asked for MSA yet. Build it properly when they do.\n4. **Reversible**: The code stays in place (shared packages, Azure GageRRPanel.tsx). Re-enabling is a one-line change in Dashboard.tsx.\n\n## Implementation\n\n- Remove `'gagerr'` from Azure Dashboard tab navigation\n- Keep `GageRRPanel.tsx` and its tests in the Azure app codebase (not wired into navigation)\n- Keep all shared MSA code in `@variscout/core`, `@variscout/charts`, `@variscout/ui`\n- PWA Gage R&R tab remains unchanged\n- Update feature-parity matrix to reflect PWA-only availability\n\n## Re-enablement Criteria\n\nWhen customer demand materialises, implement at minimum Tier 1 gaps before re-enabling in Azure App:\n\n1. %Tolerance calculation and display\n2. NDC (Number of Distinct Categories)\n3. F-tests with p-values for each variance source\n4. X-bar and R control charts\n\nThen re-add `'gagerr'` to `DashboardTab` union in `Dashboard.tsx`.\n\n## Consequences\n\n### Positive\n\n- Azure App ships only features that meet professional quality standards\n- No wasted effort building production MSA before demand exists\n- PWA retains a valuable differentiator for training use\n\n### Negative\n\n- Feature parity between PWA and Azure is slightly asymmetric (PWA has a feature Azure doesn't)\n- If a prospect specifically needs MSA, they'll see it in the free tool but not the paid one (mitigated: Azure is positioned for SPC workflow, not standalone MSA)\n\n### Neutral\n\n- Shared package code (`@variscout/core` GageRR calculations) is maintained regardless\n- GageRRPanel.tsx stays in Azure codebase, just not navigable\n\n---\n\n## Post-Decision Update\n\n**Update (2026-02-16):** Decision evolved beyond deferral. Gage R&R was fully removed from all products, shared packages, and documentation (commit 87bb072). The feature proved unnecessary — no customer demand, and PWA serves training needs without it. ADR kept as historical record of the evaluation and gap analysis.", + "src/content/docs/07-decisions/adr-010-gagerr-deferral.md", + "a92b5b3f7052ee9b", + { "html": 2501, "metadata": 2502 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-010-defer-gage-rr-from-azure-app-v1\">ADR-010: Defer Gage R&R from Azure App v1\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-010-defer-gage-rr-from-azure-app-v1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-010: Defer Gage R&R from Azure App v1”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status:\u003C/strong> Superseded\n\u003Cstrong>Date:\u003C/strong> 2026-02-16\n\u003Cstrong>Supersedes:\u003C/strong> None\n\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a> (distribution strategy)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout includes a Gage R&R (Measurement System Analysis) implementation shared across the PWA and Azure App via \u003Ccode dir=\"auto\">@variscout/core\u003C/code>, \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>, and \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>. A systematic evaluation revealed the current implementation is solid for learning but MVP-level for paying customers.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-works-well-learning-context\">What Works Well (Learning Context)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-works-well-learning-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Works Well (Learning Context)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>ANOVA math is correct (%GRR via variance components)\u003C/li>\n\u003Cli>Interaction plot visualises operator-by-part patterns\u003C/li>\n\u003Cli>Auto-detection of operator/part columns reduces setup friction\u003C/li>\n\u003Cli>Educational tooltips explain MSA concepts in context\u003C/li>\n\u003Cli>Sufficient for Green Belt training exercises\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"gap-analysis-for-production-msa\">Gap Analysis for Production MSA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#gap-analysis-for-production-msa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Gap Analysis for Production MSA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Gaps are ordered by impact on paying users:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"tier-1---expected-by-any-msa-practitioner\">Tier 1 - Expected by any MSA practitioner\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#tier-1---expected-by-any-msa-practitioner\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier 1 - Expected by any MSA practitioner”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Gap\u003C/th>\u003Cth>Impact\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No %Tolerance (%GRR relative to spec range)\u003C/td>\u003Ctd>Cannot assess measurement system acceptability per AIAG\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No NDC (Number of Distinct Categories)\u003C/td>\u003Ctd>Missing key acceptance criterion (NDC >= 5)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No F-tests with p-values\u003C/td>\u003Ctd>Cannot determine statistical significance of sources\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No X-bar/R control charts\u003C/td>\u003Ctd>Standard MSA deliverable missing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"tier-2---expected-by-quality-engineers\">Tier 2 - Expected by quality engineers\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#tier-2---expected-by-quality-engineers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier 2 - Expected by quality engineers”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Gap\u003C/th>\u003Cth>Impact\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No confidence intervals on %GRR\u003C/td>\u003Ctd>Cannot quantify uncertainty in the measurement\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No formal report export\u003C/td>\u003Ctd>Engineers need documented results for audits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No multi-study comparison\u003C/td>\u003Ctd>Cannot track measurement system over time\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"tier-3---competitive-differentiation\">Tier 3 - Competitive differentiation\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#tier-3---competitive-differentiation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier 3 - Competitive differentiation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Gap\u003C/th>\u003Cth>Impact\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No crossed vs nested study selection\u003C/td>\u003Ctd>Limits study design flexibility\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No attribute agreement analysis\u003C/td>\u003Ctd>Only handles continuous data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No linearity/bias study\u003C/td>\u003Ctd>Incomplete MSA coverage\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"competitive-landscape\">Competitive Landscape\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-landscape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Landscape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Minitab, JMP, and dedicated MSA tools all include Tier 1 features as baseline. Shipping without them would be immediately noticed by quality professionals evaluating the Azure App at EUR 150/month.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Defer Gage R&R from Azure App v1. Keep it in the PWA (free, learning-appropriate).\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"rationale\">Rationale\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#rationale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Rationale”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Credibility risk\u003C/strong>: Half-baked MSA undermines trust in the entire tool. Quality professionals will judge VariScout’s statistical rigour by its weakest feature.\u003C/li>\n\u003Cli>\u003Cstrong>PWA fit\u003C/strong>: The current implementation is genuinely useful for training. Green Belt students learning MSA concepts benefit from the interactive visualization.\u003C/li>\n\u003Cli>\u003Cstrong>Low demand signal\u003C/strong>: No customer has asked for MSA yet. Build it properly when they do.\u003C/li>\n\u003Cli>\u003Cstrong>Reversible\u003C/strong>: The code stays in place (shared packages, Azure GageRRPanel.tsx). Re-enabling is a one-line change in Dashboard.tsx.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation\">Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Remove \u003Ccode dir=\"auto\">'gagerr'\u003C/code> from Azure Dashboard tab navigation\u003C/li>\n\u003Cli>Keep \u003Ccode dir=\"auto\">GageRRPanel.tsx\u003C/code> and its tests in the Azure app codebase (not wired into navigation)\u003C/li>\n\u003Cli>Keep all shared MSA code in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>, \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>, \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/li>\n\u003Cli>PWA Gage R&R tab remains unchanged\u003C/li>\n\u003Cli>Update feature-parity matrix to reflect PWA-only availability\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"re-enablement-criteria\">Re-enablement Criteria\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#re-enablement-criteria\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Re-enablement Criteria”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When customer demand materialises, implement at minimum Tier 1 gaps before re-enabling in Azure App:\u003C/p>\n\u003Col>\n\u003Cli>%Tolerance calculation and display\u003C/li>\n\u003Cli>NDC (Number of Distinct Categories)\u003C/li>\n\u003Cli>F-tests with p-values for each variance source\u003C/li>\n\u003Cli>X-bar and R control charts\u003C/li>\n\u003C/ol>\n\u003Cp>Then re-add \u003Ccode dir=\"auto\">'gagerr'\u003C/code> to \u003Ccode dir=\"auto\">DashboardTab\u003C/code> union in \u003Ccode dir=\"auto\">Dashboard.tsx\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"positive\">Positive\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#positive\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Positive”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Azure App ships only features that meet professional quality standards\u003C/li>\n\u003Cli>No wasted effort building production MSA before demand exists\u003C/li>\n\u003Cli>PWA retains a valuable differentiator for training use\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"negative\">Negative\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#negative\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Negative”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Feature parity between PWA and Azure is slightly asymmetric (PWA has a feature Azure doesn’t)\u003C/li>\n\u003Cli>If a prospect specifically needs MSA, they’ll see it in the free tool but not the paid one (mitigated: Azure is positioned for SPC workflow, not standalone MSA)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"neutral\">Neutral\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#neutral\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Neutral”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Shared package code (\u003Ccode dir=\"auto\">@variscout/core\u003C/code> GageRR calculations) is maintained regardless\u003C/li>\n\u003Cli>GageRRPanel.tsx stays in Azure codebase, just not navigable\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"post-decision-update\">Post-Decision Update\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#post-decision-update\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Post-Decision Update”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Update (2026-02-16):\u003C/strong> Decision evolved beyond deferral. Gage R&R was fully removed from all products, shared packages, and documentation (commit 87bb072). The feature proved unnecessary — no customer demand, and PWA serves training needs without it. ADR kept as historical record of the evaluation and gap analysis.\u003C/p>", + { + "headings": 2503, + "localImagePaths": 2542, + "remoteImagePaths": 2543, + "frontmatter": 2544, + "imagePaths": 2545 + }, + [ + 2504, 2506, 2507, 2510, 2513, 2516, 2519, 2522, 2525, 2526, 2529, 2530, 2533, 2534, 2535, 2536, + 2539 + ], + { "depth": 30, "slug": 2505, "text": 2493 }, + "adr-010-defer-gage-rr-from-azure-app-v1", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 79, "slug": 2508, "text": 2509 }, + "what-works-well-learning-context", + "What Works Well (Learning Context)", + { "depth": 79, "slug": 2511, "text": 2512 }, + "gap-analysis-for-production-msa", + "Gap Analysis for Production MSA", + { "depth": 621, "slug": 2514, "text": 2515 }, + "tier-1---expected-by-any-msa-practitioner", + "Tier 1 - Expected by any MSA practitioner", + { "depth": 621, "slug": 2517, "text": 2518 }, + "tier-2---expected-by-quality-engineers", + "Tier 2 - Expected by quality engineers", + { "depth": 621, "slug": 2520, "text": 2521 }, + "tier-3---competitive-differentiation", + "Tier 3 - Competitive differentiation", + { "depth": 79, "slug": 2523, "text": 2524 }, + "competitive-landscape", + "Competitive Landscape", + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2527, "text": 2528 }, + "rationale", + "Rationale", + { "depth": 33, "slug": 1885, "text": 1886 }, + { "depth": 33, "slug": 2531, "text": 2532 }, + "re-enablement-criteria", + "Re-enablement Criteria", + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2446, "text": 2447 }, + { "depth": 79, "slug": 2449, "text": 2450 }, + { "depth": 79, "slug": 2537, "text": 2538 }, + "neutral", + "Neutral", + { "depth": 33, "slug": 2540, "text": 2541 }, + "post-decision-update", + "Post-Decision Update", + [], + [], + { "title": 2493 }, + [], + "07-decisions/adr-011-ai-development-tooling", + { "id": 2546, "data": 2548, "body": 2553, "filePath": 2554, "digest": 2555, "rendered": 2556 }, + { + "title": 2549, + "editUrl": 16, + "head": 2550, + "template": 18, + "sidebar": 2551, + "pagefind": 16, + "draft": 20 + }, + "ADR-011: AI Development Tooling (ruflo)", + [], + { "hidden": 20, "attrs": 2552 }, + {}, + "# ADR-011: AI Development Tooling (ruflo)\n\n**Status:** Accepted\n**Date:** 2026-02-18\n**Deciders:** Product team\n\n## Context\n\nVariScout is a 5-package TypeScript monorepo with 1,475 unit tests and 19 Playwright E2E specs. Development uses Claude Code as the primary AI coding assistant.\n\nRecurring friction points:\n\n1. **Cross-session context loss** -- Each Claude Code session starts without knowledge of previous decisions, file locations, or architectural constraints. The same questions about tier system, removed features, and import rules get re-answered.\n2. **Codebase navigation overhead** -- Finding the right file in a monorepo with 5 packages and 3 apps requires multiple searches per task.\n3. **Security scanning** -- OWASP audits and CVE checks were manual, inconsistent, and easy to forget before releases.\n\n## Decision\n\nUse ruflo (formerly claude-flow) as an MCP-integrated development tooling layer. It runs as a local MCP server that Claude Code connects to on session start, providing:\n\n1. **Vector-indexed codebase search** -- HNSW embeddings (all-MiniLM-L6-v2, 384-dim) for semantic file search. \"Find Cpk calculation\" returns `stats.ts` without needing exact grep patterns.\n2. **Persistent cross-session memory** -- Namespaced key-value store (architecture, conventions, decisions, testing) with semantic search. Survives session restarts.\n3. **Automated security scanning** -- OWASP Top 10 audits and CVE checks via CLI commands.\n4. **Background daemon workers** -- Periodic codebase mapping, security audits, memory consolidation, and test gap analysis.\n\n### Key choices\n\n1. **Dev tooling only** -- ruflo is never a runtime dependency. It does not appear in any `package.json`. It runs via `npx` and its data files (`.ruflo/`, `.swarm/`) are gitignored.\n\n2. **Hybrid memory backend** -- sql.js for structured storage + HNSW indexing for semantic vector search. 150x-12,500x faster than linear scan for similarity queries.\n\n3. **5 background workers** -- `map` (codebase structure), `audit` (security), `optimize` (performance hints), `consolidate` (memory dedup), `testgaps` (coverage analysis). Workers are staggered and resource-throttled (max 2 concurrent, CPU/memory guards).\n\n4. **autoStart on session open** -- MCP server starts automatically when Claude Code opens via `autoStart: true` in `.mcp.json`. SessionStart hook starts the daemon.\n\n5. **Swarm orchestration available but secondary** -- Multi-agent swarm capabilities exist for large refactors but are not the primary workflow. Most VariScout tasks are sequential monorepo changes.\n\n## Implementation\n\n- MCP server config: `.mcp.json` (autoStart: true)\n- Runtime config: `.ruflo/config.yaml`\n- Daemon state: `.ruflo/daemon-state.json`\n- Memory DB: `.swarm/memory.db`\n- Hooks: `.claude/settings.json` (PreToolUse, PostToolUse, SessionStart, UserPromptSubmit)\n- Worker exclusions: `.venv/**`, `node_modules/**`, `dist/**`, `site/**`, `*.min.js`, `*.min.css`\n\n## Consequences\n\n### Positive\n\n- Semantic codebase search eliminates multi-step grep workflows\n- Persistent memory reduces repeated context-building across sessions\n- Automated security audits catch CVEs before releases\n- Background workers maintain codebase intelligence passively\n\n### Negative\n\n- Additional dev dependency (npx, ~5s startup on first session)\n- Daemon uses background resources (mitigated by CPU/memory guards)\n- Learning curve for CLI commands and memory namespaces\n\n### Neutral\n\n- Zero impact on application code, build pipeline, or deployment\n- All data files are gitignored -- no repo bloat\n- Does not replace manual testing or code review\n\n## See Also\n\n- [ruflo Technical Reference](../05-technical/implementation/ruflo.md)\n- [Security Scanning](../05-technical/implementation/security-scanning.md)\n- [ADR-007: Azure Marketplace Distribution](adr-007-azure-marketplace-distribution.md)\n- [ADR-013: Architecture Evaluation — DDD and Swarms](adr-013-architecture-evaluation-ddd-swarms.md)", + "src/content/docs/07-decisions/adr-011-ai-development-tooling.md", + "534bfbd29a32e018", + { "html": 2557, "metadata": 2558 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-011-ai-development-tooling-ruflo\">ADR-011: AI Development Tooling (ruflo)\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-011-ai-development-tooling-ruflo\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-011: AI Development Tooling (ruflo)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status:\u003C/strong> Accepted\n\u003Cstrong>Date:\u003C/strong> 2026-02-18\n\u003Cstrong>Deciders:\u003C/strong> Product team\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is a 5-package TypeScript monorepo with 1,475 unit tests and 19 Playwright E2E specs. Development uses Claude Code as the primary AI coding assistant.\u003C/p>\n\u003Cp>Recurring friction points:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Cross-session context loss\u003C/strong> — Each Claude Code session starts without knowledge of previous decisions, file locations, or architectural constraints. The same questions about tier system, removed features, and import rules get re-answered.\u003C/li>\n\u003Cli>\u003Cstrong>Codebase navigation overhead\u003C/strong> — Finding the right file in a monorepo with 5 packages and 3 apps requires multiple searches per task.\u003C/li>\n\u003Cli>\u003Cstrong>Security scanning\u003C/strong> — OWASP audits and CVE checks were manual, inconsistent, and easy to forget before releases.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use ruflo (formerly claude-flow) as an MCP-integrated development tooling layer. It runs as a local MCP server that Claude Code connects to on session start, providing:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Vector-indexed codebase search\u003C/strong> — HNSW embeddings (all-MiniLM-L6-v2, 384-dim) for semantic file search. “Find Cpk calculation” returns \u003Ccode dir=\"auto\">stats.ts\u003C/code> without needing exact grep patterns.\u003C/li>\n\u003Cli>\u003Cstrong>Persistent cross-session memory\u003C/strong> — Namespaced key-value store (architecture, conventions, decisions, testing) with semantic search. Survives session restarts.\u003C/li>\n\u003Cli>\u003Cstrong>Automated security scanning\u003C/strong> — OWASP Top 10 audits and CVE checks via CLI commands.\u003C/li>\n\u003Cli>\u003Cstrong>Background daemon workers\u003C/strong> — Periodic codebase mapping, security audits, memory consolidation, and test gap analysis.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-choices\">Key choices\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-choices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key choices”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Dev tooling only\u003C/strong> — ruflo is never a runtime dependency. It does not appear in any \u003Ccode dir=\"auto\">package.json\u003C/code>. It runs via \u003Ccode dir=\"auto\">npx\u003C/code> and its data files (\u003Ccode dir=\"auto\">.ruflo/\u003C/code>, \u003Ccode dir=\"auto\">.swarm/\u003C/code>) are gitignored.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Hybrid memory backend\u003C/strong> — sql.js for structured storage + HNSW indexing for semantic vector search. 150x-12,500x faster than linear scan for similarity queries.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>5 background workers\u003C/strong> — \u003Ccode dir=\"auto\">map\u003C/code> (codebase structure), \u003Ccode dir=\"auto\">audit\u003C/code> (security), \u003Ccode dir=\"auto\">optimize\u003C/code> (performance hints), \u003Ccode dir=\"auto\">consolidate\u003C/code> (memory dedup), \u003Ccode dir=\"auto\">testgaps\u003C/code> (coverage analysis). Workers are staggered and resource-throttled (max 2 concurrent, CPU/memory guards).\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>autoStart on session open\u003C/strong> — MCP server starts automatically when Claude Code opens via \u003Ccode dir=\"auto\">autoStart: true\u003C/code> in \u003Ccode dir=\"auto\">.mcp.json\u003C/code>. SessionStart hook starts the daemon.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Swarm orchestration available but secondary\u003C/strong> — Multi-agent swarm capabilities exist for large refactors but are not the primary workflow. Most VariScout tasks are sequential monorepo changes.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation\">Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>MCP server config: \u003Ccode dir=\"auto\">.mcp.json\u003C/code> (autoStart: true)\u003C/li>\n\u003Cli>Runtime config: \u003Ccode dir=\"auto\">.ruflo/config.yaml\u003C/code>\u003C/li>\n\u003Cli>Daemon state: \u003Ccode dir=\"auto\">.ruflo/daemon-state.json\u003C/code>\u003C/li>\n\u003Cli>Memory DB: \u003Ccode dir=\"auto\">.swarm/memory.db\u003C/code>\u003C/li>\n\u003Cli>Hooks: \u003Ccode dir=\"auto\">.claude/settings.json\u003C/code> (PreToolUse, PostToolUse, SessionStart, UserPromptSubmit)\u003C/li>\n\u003Cli>Worker exclusions: \u003Ccode dir=\"auto\">.venv/**\u003C/code>, \u003Ccode dir=\"auto\">node_modules/**\u003C/code>, \u003Ccode dir=\"auto\">dist/**\u003C/code>, \u003Ccode dir=\"auto\">site/**\u003C/code>, \u003Ccode dir=\"auto\">*.min.js\u003C/code>, \u003Ccode dir=\"auto\">*.min.css\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"positive\">Positive\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#positive\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Positive”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Semantic codebase search eliminates multi-step grep workflows\u003C/li>\n\u003Cli>Persistent memory reduces repeated context-building across sessions\u003C/li>\n\u003Cli>Automated security audits catch CVEs before releases\u003C/li>\n\u003Cli>Background workers maintain codebase intelligence passively\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"negative\">Negative\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#negative\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Negative”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Additional dev dependency (npx, ~5s startup on first session)\u003C/li>\n\u003Cli>Daemon uses background resources (mitigated by CPU/memory guards)\u003C/li>\n\u003Cli>Learning curve for CLI commands and memory namespaces\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"neutral\">Neutral\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#neutral\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Neutral”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Zero impact on application code, build pipeline, or deployment\u003C/li>\n\u003Cli>All data files are gitignored — no repo bloat\u003C/li>\n\u003Cli>Does not replace manual testing or code review\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../05-technical/implementation/ruflo.md\">ruflo Technical Reference\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../05-technical/implementation/security-scanning.md\">Security Scanning\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007: Azure Marketplace Distribution\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"adr-013-architecture-evaluation-ddd-swarms.md\">ADR-013: Architecture Evaluation — DDD and Swarms\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2559, + "localImagePaths": 2572, + "remoteImagePaths": 2573, + "frontmatter": 2574, + "imagePaths": 2575 + }, + [2560, 2562, 2563, 2564, 2566, 2567, 2568, 2569, 2570, 2571], + { "depth": 30, "slug": 2561, "text": 2549 }, + "adr-011-ai-development-tooling-ruflo", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2481, "text": 2565 }, + "Key choices", + { "depth": 33, "slug": 1885, "text": 1886 }, + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2446, "text": 2447 }, + { "depth": 79, "slug": 2449, "text": 2450 }, + { "depth": 79, "slug": 2537, "text": 2538 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2549 }, + [], + "07-decisions/adr-012-pwa-browser-only", + { "id": 2576, "data": 2578, "body": 2583, "filePath": 2584, "digest": 2585, "rendered": 2586 }, + { + "title": 2579, + "editUrl": 16, + "head": 2580, + "template": 18, + "sidebar": 2581, + "pagefind": 16, + "draft": 20 + }, + "ADR-012: PWA Browser-Only, Zero Data Collection", + [], + { "hidden": 20, "attrs": 2582 }, + {}, + "# ADR-012: PWA Browser-Only, Zero Data Collection\n\n**Status**: Accepted\n\n**Date**: 2026-02-18\n\n## Context\n\nVariScout's PWA serves as a free training and education tool. Two principles have been true in practice but never formally documented:\n\n1. **The PWA is browser-only** — users access it as a regular website in their browser tab. There is no \"Add to Home Screen\" installation and no standalone app mode.\n2. **Zero user data collection** — no analytics, no telemetry, no cookies, no tracking of any kind. The only localStorage used is for theme preference and UI state (panel width).\n\nThe codebase had contradictions: `vite-plugin-pwa` was configured with `display: standalone` (which enables browser install prompts), an `InstallPrompt.tsx` component and `useIsInstalled`/`useInstallPrompt` hooks existed as dead code, and several docs referenced PWA installation. Meanwhile, the zero-data-collection stance was already true in code but undocumented.\n\n## Decision\n\n### Decision 1: PWA is a browser-only tool, not an installable app\n\n- Users open VariScout in a browser tab. That's it.\n- No install prompts, no standalone mode, no home screen icons.\n- The manifest `display` mode is set to `browser` (not `standalone`).\n\n### Decision 2: Zero user data collection\n\n- No analytics (Google Analytics, Plausible, Mixpanel, etc.)\n- No telemetry or error reporting services\n- No cookies (the PWA has no server-side component)\n- No tracking pixels, fingerprinting, or session recording\n- localStorage is used only for theme preference and UI state — never for user identification\n\n### What we keep\n\n- **Service Worker** for offline caching: `vite-plugin-pwa` generates a Service Worker that precaches static assets. This means the PWA loads fast on repeat visits and works offline. This is about performance, not installation.\n- **Web App Manifest**: Still present for metadata (name, icons, theme color) but with `display: browser` so browsers don't offer install prompts.\n\n### What we removed\n\n- `InstallPrompt.tsx` component (dead code)\n- `useIsInstalled` and `useInstallPrompt` hooks (dead code)\n- `display: 'standalone'` from manifest config\n- Documentation references to \"Add to Home Screen\" and PWA installation\n\n## Rationale\n\n**Simplicity**: A free training tool that runs in a browser tab is the simplest mental model. Users don't need to understand what a PWA is, how installation works, or why their \"installed\" app looks different from a bookmark.\n\n**Trust**: A free tool for quality professionals shouldn't feel like surveillance. Zero data collection means we can honestly say \"we know nothing about you\" — which aligns with the offline-first, no-backend architecture.\n\n**Maintenance**: Install prompts, standalone display mode, and the associated UX (update notifications, offline indicators in standalone mode) add code and testing surface for no business value. The Azure App is the paid product; the PWA is a funnel, not a platform.\n\n**Consistency**: The PWA is session-only (no saved projects, no persistence beyond theme). Offering \"installation\" implies a level of commitment and continuity that doesn't match the session-only data model.\n\n## Consequences\n\n### Easier\n\n- Simpler codebase (no install prompt logic, no standalone detection)\n- Simpler documentation (no need to explain installation to users)\n- Privacy story is clean and verifiable (\"view source — there's no tracking code\")\n- No need to handle service worker update UX in standalone mode\n\n### Harder\n\n- Users who want a desktop shortcut must create a browser bookmark manually\n- No offline indicator in standalone mode (but Service Worker caching still works in-browser)\n- If we ever want to support installation in the future, we'd need to re-add the manifest display mode and install UX\n\n## See Also\n\n- [ADR-004: Offline-First](adr-004-offline-first.md) — Service Worker caching remains\n- [ADR-007: Azure Marketplace Distribution](adr-007-azure-marketplace-distribution.md) — the paid product strategy\n- [PWA Product Spec](../08-products/pwa/index.md)", + "src/content/docs/07-decisions/adr-012-pwa-browser-only.md", + "538a3bb012c3f4f2", + { "html": 2587, "metadata": 2588 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-012-pwa-browser-only-zero-data-collection\">ADR-012: PWA Browser-Only, Zero Data Collection\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-012-pwa-browser-only-zero-data-collection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-012: PWA Browser-Only, Zero Data Collection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Accepted\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2026-02-18\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s PWA serves as a free training and education tool. Two principles have been true in practice but never formally documented:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>The PWA is browser-only\u003C/strong> — users access it as a regular website in their browser tab. There is no “Add to Home Screen” installation and no standalone app mode.\u003C/li>\n\u003Cli>\u003Cstrong>Zero user data collection\u003C/strong> — no analytics, no telemetry, no cookies, no tracking of any kind. The only localStorage used is for theme preference and UI state (panel width).\u003C/li>\n\u003C/ol>\n\u003Cp>The codebase had contradictions: \u003Ccode dir=\"auto\">vite-plugin-pwa\u003C/code> was configured with \u003Ccode dir=\"auto\">display: standalone\u003C/code> (which enables browser install prompts), an \u003Ccode dir=\"auto\">InstallPrompt.tsx\u003C/code> component and \u003Ccode dir=\"auto\">useIsInstalled\u003C/code>/\u003Ccode dir=\"auto\">useInstallPrompt\u003C/code> hooks existed as dead code, and several docs referenced PWA installation. Meanwhile, the zero-data-collection stance was already true in code but undocumented.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"decision-1-pwa-is-a-browser-only-tool-not-an-installable-app\">Decision 1: PWA is a browser-only tool, not an installable app\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#decision-1-pwa-is-a-browser-only-tool-not-an-installable-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision 1: PWA is a browser-only tool, not an installable app”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Users open VariScout in a browser tab. That’s it.\u003C/li>\n\u003Cli>No install prompts, no standalone mode, no home screen icons.\u003C/li>\n\u003Cli>The manifest \u003Ccode dir=\"auto\">display\u003C/code> mode is set to \u003Ccode dir=\"auto\">browser\u003C/code> (not \u003Ccode dir=\"auto\">standalone\u003C/code>).\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"decision-2-zero-user-data-collection\">Decision 2: Zero user data collection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#decision-2-zero-user-data-collection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision 2: Zero user data collection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>No analytics (Google Analytics, Plausible, Mixpanel, etc.)\u003C/li>\n\u003Cli>No telemetry or error reporting services\u003C/li>\n\u003Cli>No cookies (the PWA has no server-side component)\u003C/li>\n\u003Cli>No tracking pixels, fingerprinting, or session recording\u003C/li>\n\u003Cli>localStorage is used only for theme preference and UI state — never for user identification\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-we-keep\">What we keep\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-we-keep\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What we keep”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Service Worker\u003C/strong> for offline caching: \u003Ccode dir=\"auto\">vite-plugin-pwa\u003C/code> generates a Service Worker that precaches static assets. This means the PWA loads fast on repeat visits and works offline. This is about performance, not installation.\u003C/li>\n\u003Cli>\u003Cstrong>Web App Manifest\u003C/strong>: Still present for metadata (name, icons, theme color) but with \u003Ccode dir=\"auto\">display: browser\u003C/code> so browsers don’t offer install prompts.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-we-removed\">What we removed\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-we-removed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What we removed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">InstallPrompt.tsx\u003C/code> component (dead code)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useIsInstalled\u003C/code> and \u003Ccode dir=\"auto\">useInstallPrompt\u003C/code> hooks (dead code)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">display: 'standalone'\u003C/code> from manifest config\u003C/li>\n\u003Cli>Documentation references to “Add to Home Screen” and PWA installation\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"rationale\">Rationale\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#rationale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Rationale”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Simplicity\u003C/strong>: A free training tool that runs in a browser tab is the simplest mental model. Users don’t need to understand what a PWA is, how installation works, or why their “installed” app looks different from a bookmark.\u003C/p>\n\u003Cp>\u003Cstrong>Trust\u003C/strong>: A free tool for quality professionals shouldn’t feel like surveillance. Zero data collection means we can honestly say “we know nothing about you” — which aligns with the offline-first, no-backend architecture.\u003C/p>\n\u003Cp>\u003Cstrong>Maintenance\u003C/strong>: Install prompts, standalone display mode, and the associated UX (update notifications, offline indicators in standalone mode) add code and testing surface for no business value. The Azure App is the paid product; the PWA is a funnel, not a platform.\u003C/p>\n\u003Cp>\u003Cstrong>Consistency\u003C/strong>: The PWA is session-only (no saved projects, no persistence beyond theme). Offering “installation” implies a level of commitment and continuity that doesn’t match the session-only data model.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"easier\">Easier\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#easier\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Easier”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Simpler codebase (no install prompt logic, no standalone detection)\u003C/li>\n\u003Cli>Simpler documentation (no need to explain installation to users)\u003C/li>\n\u003Cli>Privacy story is clean and verifiable (“view source — there’s no tracking code”)\u003C/li>\n\u003Cli>No need to handle service worker update UX in standalone mode\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"harder\">Harder\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#harder\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Harder”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Users who want a desktop shortcut must create a browser bookmark manually\u003C/li>\n\u003Cli>No offline indicator in standalone mode (but Service Worker caching still works in-browser)\u003C/li>\n\u003Cli>If we ever want to support installation in the future, we’d need to re-add the manifest display mode and install UX\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"adr-004-offline-first.md\">ADR-004: Offline-First\u003C/a> — Service Worker caching remains\u003C/li>\n\u003Cli>\u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007: Azure Marketplace Distribution\u003C/a> — the paid product strategy\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/pwa/index.md\">PWA Product Spec\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2589, + "localImagePaths": 2615, + "remoteImagePaths": 2616, + "frontmatter": 2617, + "imagePaths": 2618 + }, + [2590, 2592, 2593, 2594, 2597, 2600, 2603, 2606, 2607, 2608, 2611, 2614], + { "depth": 30, "slug": 2591, "text": 2579 }, + "adr-012-pwa-browser-only-zero-data-collection", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2595, "text": 2596 }, + "decision-1-pwa-is-a-browser-only-tool-not-an-installable-app", + "Decision 1: PWA is a browser-only tool, not an installable app", + { "depth": 79, "slug": 2598, "text": 2599 }, + "decision-2-zero-user-data-collection", + "Decision 2: Zero user data collection", + { "depth": 79, "slug": 2601, "text": 2602 }, + "what-we-keep", + "What we keep", + { "depth": 79, "slug": 2604, "text": 2605 }, + "what-we-removed", + "What we removed", + { "depth": 33, "slug": 2527, "text": 2528 }, + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2609, "text": 2610 }, + "easier", + "Easier", + { "depth": 79, "slug": 2612, "text": 2613 }, + "harder", + "Harder", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2579 }, + [], + "07-decisions/adr-013-architecture-evaluation-ddd-swarms", + { "id": 2619, "data": 2621, "body": 2626, "filePath": 2627, "digest": 2628, "rendered": 2629 }, + { + "title": 2622, + "editUrl": 16, + "head": 2623, + "template": 18, + "sidebar": 2624, + "pagefind": 16, + "draft": 20 + }, + "ADR-013: Architecture Evaluation — DDD and AI Swarms", + [], + { "hidden": 20, "attrs": 2625 }, + {}, + "# ADR-013: Architecture Evaluation — DDD and AI Swarms\n\n**Status:** Accepted\n**Date:** 2026-02-18\n**Deciders:** Product team\n\n## Context\n\nAfter updating ruflo (formerly claude-flow) to v3alpha (ADR-011), we evaluated whether two architectural approaches could benefit VariScout:\n\n1. **Domain-Driven Design (DDD)** — tactical patterns (aggregates, repositories, domain events, value objects) applied to the existing package structure.\n2. **AI swarm orchestration** — multi-agent coordination as an architectural layer for the application itself, or as a development workflow tool.\n\nThe evaluation was prompted by ruflo's expanded swarm capabilities and its DDD-oriented internal architecture.\n\n## Decision\n\n**Keep the current package-per-layer architecture. Do not adopt DDD tactical patterns. Use AI swarms for three specific development workflows only.**\n\n### Why the current architecture already embodies DDD's valuable principles\n\nVariScout's monorepo structure already implements the most impactful DDD concepts:\n\n- **Pure domain layer** — `@variscout/core` contains statistics, parsing, tier logic, and glossary with zero React or UI dependencies. This is equivalent to a DDD domain layer.\n- **Ubiquitous language** — Domain terms (Cpk, eta-squared, control limits, specification limits) are used consistently from types through to UI labels. The glossary system (`packages/core/src/glossary/`) formalizes this.\n- **Bounded contexts via packages** — Each package (`core`, `charts`, `hooks`, `ui`, `data`) has clear responsibilities and one-way dependency flow. `core` never imports from `charts`; apps never leak into packages.\n- **Single Responsibility** — `stats.ts` was split into 13 domain modules (`packages/core/src/stats/`) for maintainability, mirroring DDD's module pattern.\n\n### Why tactical DDD would be over-engineering\n\n- **No concurrent writes** — VariScout is a single-user, offline-first browser application. There are no competing transactions, eventual consistency concerns, or distributed state conflicts that DDD aggregates are designed to manage.\n- **Algorithmic complexity, not domain-invariant complexity** — The hard problems in VariScout are statistical (KDE, ANOVA, regression) not domain-invariant (business rule enforcement across entity clusters). Aggregates and domain events add ceremony without solving real problems.\n- **No persistence abstraction needed** — Data flows one-way: file/paste → parse → context → charts. There is no ORM, no database schema evolution, no repository pattern benefit over the current `useDataState` hook.\n- **5-package monorepo** — The codebase is small enough that package boundaries provide sufficient modularity. Adding DDD layers inside packages would create indirection without reducing coupling.\n\n### Swarm workflows adopted (development tooling only)\n\nThree swarm patterns have practical value as **development workflows**, not as application architecture:\n\n1. **Parallel test execution** — Run vitest across all 5 packages concurrently using Task agents. Faster feedback than sequential `pnpm test`.\n2. **Security scanning** — Targeted OWASP scans on Azure auth (`easyAuth.ts`) and storage (`storage.ts`) modules using ruflo security tools.\n3. **Read-only code review** — Multi-agent review of cross-package changes (e.g., a new shared hook touching `core`, `hooks`, and both apps) without modifying code.\n\nThese workflows use existing ruflo capabilities and Claude Code Task agents. No new configuration files or runtime dependencies are added.\n\n## Consequences\n\n### Positive\n\n- **Documented rationale** — Future contributors can understand why DDD was evaluated and rejected, avoiding repeated discussions.\n- **Practical swarm value** — Three concrete workflows that reduce development friction without architectural overhead.\n- **Architecture validated** — The evaluation confirms the current structure is appropriate for the problem domain and team size.\n\n### Negative\n\n- **Swarm cost** — Multi-agent workflows consume more API tokens than single-agent equivalents. Use judiciously for tasks that genuinely benefit from parallelism.\n\n### Neutral\n\n- **No code changes** — This is a documentation-only decision. No application code, build pipeline, or deployment is affected.\n- **Reversible** — If VariScout evolves to require multi-user collaboration or server-side processing, DDD tactical patterns can be reconsidered at that point.\n\n## See Also\n\n- [ADR-011: AI Development Tooling](adr-011-ai-development-tooling.md)\n- [ADR-001: Monorepo with pnpm](adr-001-monorepo.md)\n- [Architecture Overview](../05-technical/architecture.md)", + "src/content/docs/07-decisions/adr-013-architecture-evaluation-ddd-swarms.md", + "dd2cc6946a6f9abf", + { "html": 2630, "metadata": 2631 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-013-architecture-evaluation--ddd-and-ai-swarms\">ADR-013: Architecture Evaluation — DDD and AI Swarms\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-013-architecture-evaluation--ddd-and-ai-swarms\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-013: Architecture Evaluation — DDD and AI Swarms”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status:\u003C/strong> Accepted\n\u003Cstrong>Date:\u003C/strong> 2026-02-18\n\u003Cstrong>Deciders:\u003C/strong> Product team\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After updating ruflo (formerly claude-flow) to v3alpha (ADR-011), we evaluated whether two architectural approaches could benefit VariScout:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Domain-Driven Design (DDD)\u003C/strong> — tactical patterns (aggregates, repositories, domain events, value objects) applied to the existing package structure.\u003C/li>\n\u003Cli>\u003Cstrong>AI swarm orchestration\u003C/strong> — multi-agent coordination as an architectural layer for the application itself, or as a development workflow tool.\u003C/li>\n\u003C/ol>\n\u003Cp>The evaluation was prompted by ruflo’s expanded swarm capabilities and its DDD-oriented internal architecture.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Keep the current package-per-layer architecture. Do not adopt DDD tactical patterns. Use AI swarms for three specific development workflows only.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-the-current-architecture-already-embodies-ddds-valuable-principles\">Why the current architecture already embodies DDD’s valuable principles\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-the-current-architecture-already-embodies-ddds-valuable-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why the current architecture already embodies DDD’s valuable principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s monorepo structure already implements the most impactful DDD concepts:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Pure domain layer\u003C/strong> — \u003Ccode dir=\"auto\">@variscout/core\u003C/code> contains statistics, parsing, tier logic, and glossary with zero React or UI dependencies. This is equivalent to a DDD domain layer.\u003C/li>\n\u003Cli>\u003Cstrong>Ubiquitous language\u003C/strong> — Domain terms (Cpk, eta-squared, control limits, specification limits) are used consistently from types through to UI labels. The glossary system (\u003Ccode dir=\"auto\">packages/core/src/glossary/\u003C/code>) formalizes this.\u003C/li>\n\u003Cli>\u003Cstrong>Bounded contexts via packages\u003C/strong> — Each package (\u003Ccode dir=\"auto\">core\u003C/code>, \u003Ccode dir=\"auto\">charts\u003C/code>, \u003Ccode dir=\"auto\">hooks\u003C/code>, \u003Ccode dir=\"auto\">ui\u003C/code>, \u003Ccode dir=\"auto\">data\u003C/code>) has clear responsibilities and one-way dependency flow. \u003Ccode dir=\"auto\">core\u003C/code> never imports from \u003Ccode dir=\"auto\">charts\u003C/code>; apps never leak into packages.\u003C/li>\n\u003Cli>\u003Cstrong>Single Responsibility\u003C/strong> — \u003Ccode dir=\"auto\">stats.ts\u003C/code> was split into 13 domain modules (\u003Ccode dir=\"auto\">packages/core/src/stats/\u003C/code>) for maintainability, mirroring DDD’s module pattern.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-tactical-ddd-would-be-over-engineering\">Why tactical DDD would be over-engineering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-tactical-ddd-would-be-over-engineering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why tactical DDD would be over-engineering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>No concurrent writes\u003C/strong> — VariScout is a single-user, offline-first browser application. There are no competing transactions, eventual consistency concerns, or distributed state conflicts that DDD aggregates are designed to manage.\u003C/li>\n\u003Cli>\u003Cstrong>Algorithmic complexity, not domain-invariant complexity\u003C/strong> — The hard problems in VariScout are statistical (KDE, ANOVA, regression) not domain-invariant (business rule enforcement across entity clusters). Aggregates and domain events add ceremony without solving real problems.\u003C/li>\n\u003Cli>\u003Cstrong>No persistence abstraction needed\u003C/strong> — Data flows one-way: file/paste → parse → context → charts. There is no ORM, no database schema evolution, no repository pattern benefit over the current \u003Ccode dir=\"auto\">useDataState\u003C/code> hook.\u003C/li>\n\u003Cli>\u003Cstrong>5-package monorepo\u003C/strong> — The codebase is small enough that package boundaries provide sufficient modularity. Adding DDD layers inside packages would create indirection without reducing coupling.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"swarm-workflows-adopted-development-tooling-only\">Swarm workflows adopted (development tooling only)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#swarm-workflows-adopted-development-tooling-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Swarm workflows adopted (development tooling only)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Three swarm patterns have practical value as \u003Cstrong>development workflows\u003C/strong>, not as application architecture:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Parallel test execution\u003C/strong> — Run vitest across all 5 packages concurrently using Task agents. Faster feedback than sequential \u003Ccode dir=\"auto\">pnpm test\u003C/code>.\u003C/li>\n\u003Cli>\u003Cstrong>Security scanning\u003C/strong> — Targeted OWASP scans on Azure auth (\u003Ccode dir=\"auto\">easyAuth.ts\u003C/code>) and storage (\u003Ccode dir=\"auto\">storage.ts\u003C/code>) modules using ruflo security tools.\u003C/li>\n\u003Cli>\u003Cstrong>Read-only code review\u003C/strong> — Multi-agent review of cross-package changes (e.g., a new shared hook touching \u003Ccode dir=\"auto\">core\u003C/code>, \u003Ccode dir=\"auto\">hooks\u003C/code>, and both apps) without modifying code.\u003C/li>\n\u003C/ol>\n\u003Cp>These workflows use existing ruflo capabilities and Claude Code Task agents. No new configuration files or runtime dependencies are added.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"positive\">Positive\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#positive\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Positive”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Documented rationale\u003C/strong> — Future contributors can understand why DDD was evaluated and rejected, avoiding repeated discussions.\u003C/li>\n\u003Cli>\u003Cstrong>Practical swarm value\u003C/strong> — Three concrete workflows that reduce development friction without architectural overhead.\u003C/li>\n\u003Cli>\u003Cstrong>Architecture validated\u003C/strong> — The evaluation confirms the current structure is appropriate for the problem domain and team size.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"negative\">Negative\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#negative\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Negative”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Swarm cost\u003C/strong> — Multi-agent workflows consume more API tokens than single-agent equivalents. Use judiciously for tasks that genuinely benefit from parallelism.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"neutral\">Neutral\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#neutral\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Neutral”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>No code changes\u003C/strong> — This is a documentation-only decision. No application code, build pipeline, or deployment is affected.\u003C/li>\n\u003Cli>\u003Cstrong>Reversible\u003C/strong> — If VariScout evolves to require multi-user collaboration or server-side processing, DDD tactical patterns can be reconsidered at that point.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"adr-011-ai-development-tooling.md\">ADR-011: AI Development Tooling\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"adr-001-monorepo.md\">ADR-001: Monorepo with pnpm\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../05-technical/architecture.md\">Architecture Overview\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2632, + "localImagePaths": 2651, + "remoteImagePaths": 2652, + "frontmatter": 2653, + "imagePaths": 2654 + }, + [2633, 2635, 2636, 2637, 2640, 2643, 2646, 2647, 2648, 2649, 2650], + { "depth": 30, "slug": 2634, "text": 2622 }, + "adr-013-architecture-evaluation--ddd-and-ai-swarms", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2638, "text": 2639 }, + "why-the-current-architecture-already-embodies-ddds-valuable-principles", + "Why the current architecture already embodies DDD’s valuable principles", + { "depth": 79, "slug": 2641, "text": 2642 }, + "why-tactical-ddd-would-be-over-engineering", + "Why tactical DDD would be over-engineering", + { "depth": 79, "slug": 2644, "text": 2645 }, + "swarm-workflows-adopted-development-tooling-only", + "Swarm workflows adopted (development tooling only)", + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2446, "text": 2447 }, + { "depth": 79, "slug": 2449, "text": 2450 }, + { "depth": 79, "slug": 2537, "text": 2538 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2622 }, + [], + "07-decisions/adr-014-regression-deferral", + { "id": 2655, "data": 2657, "body": 2662, "filePath": 2663, "digest": 2664, "rendered": 2665 }, + { + "title": 2658, + "editUrl": 16, + "head": 2659, + "template": 18, + "sidebar": 2660, + "pagefind": 16, + "draft": 20 + }, + "ADR-014: Defer Regression to Phase 2", + [], + { "hidden": 20, "attrs": 2661 }, + {}, + "# ADR-014: Defer Regression to Phase 2\n\n**Status:** Accepted\n**Date:** 2026-02-25\n**Related:** [ADR-007](adr-007-azure-marketplace-distribution.md) (distribution strategy), [ADR-010](adr-010-gagerr-deferral.md) (Gage R&R deferral precedent)\n\n---\n\n## Context\n\nRegression spans simple linear, GLM (multi-predictor), model reduction, and model-driven simulation across ~3,300 lines of feature code distributed through UI components, hooks, and shared packages:\n\n- **UI layer**: RegressionPanelBase, SimpleRegressionView, AdvancedRegressionView, ExpandedScatterModal (~1,400 lines in `@variscout/ui`)\n- **Hooks**: useRegressionState (~400 lines in `@variscout/hooks`), regression persistence in .vrs files\n- **Simulation**: ModelDrivenSimulator (~350 lines in `@variscout/ui`), simulateFromModel in `@variscout/core`\n- **Mindmap interaction mode**: Bridge from Mindmap factors to Regression predictors (~200 lines)\n- **App wrappers**: PWA and Azure RegressionPanel wrappers, Dashboard tab wiring, toolbar integration\n- **Tests**: Regression-specific test files across hooks, UI, and app packages\n- **Glossary**: Regression-specific terms (R-squared, adjusted R-squared, predictor, interaction term, etc.)\n\nFor the Azure Marketplace v1 launch, the core analysis workflow is complete and valuable without regression:\n\n- I-Chart with Nelson Rules and staged analysis\n- Boxplot with ANOVA, violin mode, and category sorting\n- Pareto chart with contribution ranking\n- Capability analysis (Cp/Cpk histogram + probability plot)\n- Performance Mode (multi-channel comparison)\n- Mindmap drilldown with narrative\n- What-If direct-adjustment simulation\n- Full drill-down navigation with filter breadcrumbs\n\nRegression adds analytical depth but also adds certification surface area, user complexity, and maintenance burden. No customer has requested regression modelling. The Investigation-to-Action workflow (Mindmap -> Regression -> What-If) is elegant but presumes users who already understand GLM concepts -- a small subset of the target audience.\n\n## Decision\n\n**Defer regression from both PWA and Azure apps. Remove UI, keep core math for Phase 2 reuse.**\n\n### What Gets Removed\n\n| Layer | Files/Components | Rationale |\n| ------------------------ | --------------------------------------------------------------------------------------- | ----------------------------------------------------- |\n| UI components | RegressionPanelBase, SimpleRegressionView, AdvancedRegressionView, ExpandedScatterModal | No regression UI in either app |\n| Hooks | useRegressionState | No regression state to manage |\n| Simulation | ModelDrivenSimulator, simulateFromModel | Model-driven simulation depends on regression results |\n| Mindmap interaction mode | initialPredictors bridge, interaction mode toggle | Simplify Mindmap to drilldown + narrative only |\n| App wiring | Dashboard Regression tab, toolbar buttons, persistence fields | Remove all entry points |\n| Tests | Regression-specific test files | Tests for removed code |\n| Glossary | Regression-specific terms | Terms for absent features |\n\n### What Stays\n\n| Item | Rationale |\n| ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |\n| Core math files (regression.ts, multiRegression.ts, interaction.ts, modelReduction.ts, matrix.ts) | Preserved for Phase 2 reuse; exports removed from package index so tree-shaking excludes from builds |\n| ScatterPlot chart component | General-purpose chart, used outside regression context |\n| WhatIfSimulator (direct-adjustment mode) | Standalone value; users adjust factors directly without needing a fitted model |\n| simulateDirectAdjustment, calculateProjectedStats | Support direct What-If mode |\n| Mindmap (drilldown + narrative modes) | Core investigation tool; only interaction mode removed |\n| ANOVA | Independent statistical feature, not part of regression |\n\n## Implementation\n\n1. Remove regression exports from `@variscout/core` index (keep source files)\n2. Remove RegressionPanelBase and related views from `@variscout/ui`\n3. Remove useRegressionState from `@variscout/hooks`\n4. Remove ModelDrivenSimulator from `@variscout/ui`\n5. Remove Mindmap interaction mode (simplify to drilldown + narrative)\n6. Remove simulateFromModel from `@variscout/core` variation exports\n7. Remove regression tab and toolbar entry points from PWA and Azure Dashboard\n8. Remove regression persistence fields from AnalysisState (.vrs format)\n9. Remove regression-specific test files\n10. Remove regression glossary terms from `@variscout/core`\n11. Update feature-parity matrix and documentation\n\n## Re-enablement Criteria (Phase 2)\n\nRe-introduce regression when all of the following are met:\n\n1. **Post-marketplace certification** -- Azure App is listed and generating revenue\n2. **Customer demand signal** -- At least one paying customer requests regression or investigation workflow\n3. **UX validation** -- Regression workflow tested with target persona (Green Belt Gary) for discoverability and comprehension\n\nPhase 2 implementation can re-export core math files and rebuild UI layer on the preserved foundation.\n\n## Consequences\n\n### Positive\n\n- Reduced MVP scope -- fewer features to certify, document, and support at launch\n- Simpler user experience -- core analysis workflow without advanced statistical modelling\n- Smaller bundle size -- ~3,300 lines excluded from production builds\n- Lower certification surface area for Azure Marketplace submission\n- What-If direct mode still provides actionable simulation without requiring regression knowledge\n\n### Negative\n\n- Investigation-to-Action workflow (Mindmap -> Regression -> What-If) loses its middle step; the bridge from investigation to simulation becomes manual\n- Users who understand GLM lose a power feature (mitigated: no such users have been identified in the target audience)\n- Core math files remain in repo without test coverage (mitigated: re-enable tests when re-enabling feature)\n\n### Neutral\n\n- Core math files (regression.ts, multiRegression.ts, etc.) stay in the repository, unexported -- no maintenance cost, no build cost\n- ScatterPlot chart component continues to work for general-purpose use\n- WhatIfSimulator direct mode is unaffected", + "src/content/docs/07-decisions/adr-014-regression-deferral.md", + "9d923ccf3c8cd761", + { "html": 2666, "metadata": 2667 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-014-defer-regression-to-phase-2\">ADR-014: Defer Regression to Phase 2\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-014-defer-regression-to-phase-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-014: Defer Regression to Phase 2”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status:\u003C/strong> Accepted\n\u003Cstrong>Date:\u003C/strong> 2026-02-25\n\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a> (distribution strategy), \u003Ca href=\"adr-010-gagerr-deferral.md\">ADR-010\u003C/a> (Gage R&R deferral precedent)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Regression spans simple linear, GLM (multi-predictor), model reduction, and model-driven simulation across ~3,300 lines of feature code distributed through UI components, hooks, and shared packages:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>UI layer\u003C/strong>: RegressionPanelBase, SimpleRegressionView, AdvancedRegressionView, ExpandedScatterModal (~1,400 lines in \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>)\u003C/li>\n\u003Cli>\u003Cstrong>Hooks\u003C/strong>: useRegressionState (~400 lines in \u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>), regression persistence in .vrs files\u003C/li>\n\u003Cli>\u003Cstrong>Simulation\u003C/strong>: ModelDrivenSimulator (~350 lines in \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>), simulateFromModel in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Mindmap interaction mode\u003C/strong>: Bridge from Mindmap factors to Regression predictors (~200 lines)\u003C/li>\n\u003Cli>\u003Cstrong>App wrappers\u003C/strong>: PWA and Azure RegressionPanel wrappers, Dashboard tab wiring, toolbar integration\u003C/li>\n\u003Cli>\u003Cstrong>Tests\u003C/strong>: Regression-specific test files across hooks, UI, and app packages\u003C/li>\n\u003Cli>\u003Cstrong>Glossary\u003C/strong>: Regression-specific terms (R-squared, adjusted R-squared, predictor, interaction term, etc.)\u003C/li>\n\u003C/ul>\n\u003Cp>For the Azure Marketplace v1 launch, the core analysis workflow is complete and valuable without regression:\u003C/p>\n\u003Cul>\n\u003Cli>I-Chart with Nelson Rules and staged analysis\u003C/li>\n\u003Cli>Boxplot with ANOVA, violin mode, and category sorting\u003C/li>\n\u003Cli>Pareto chart with contribution ranking\u003C/li>\n\u003Cli>Capability analysis (Cp/Cpk histogram + probability plot)\u003C/li>\n\u003Cli>Performance Mode (multi-channel comparison)\u003C/li>\n\u003Cli>Mindmap drilldown with narrative\u003C/li>\n\u003Cli>What-If direct-adjustment simulation\u003C/li>\n\u003Cli>Full drill-down navigation with filter breadcrumbs\u003C/li>\n\u003C/ul>\n\u003Cp>Regression adds analytical depth but also adds certification surface area, user complexity, and maintenance burden. No customer has requested regression modelling. The Investigation-to-Action workflow (Mindmap -> Regression -> What-If) is elegant but presumes users who already understand GLM concepts — a small subset of the target audience.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Defer regression from both PWA and Azure apps. Remove UI, keep core math for Phase 2 reuse.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-gets-removed\">What Gets Removed\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-gets-removed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Gets Removed”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Layer\u003C/th>\u003Cth>Files/Components\u003C/th>\u003Cth>Rationale\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>UI components\u003C/td>\u003Ctd>RegressionPanelBase, SimpleRegressionView, AdvancedRegressionView, ExpandedScatterModal\u003C/td>\u003Ctd>No regression UI in either app\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hooks\u003C/td>\u003Ctd>useRegressionState\u003C/td>\u003Ctd>No regression state to manage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Simulation\u003C/td>\u003Ctd>ModelDrivenSimulator, simulateFromModel\u003C/td>\u003Ctd>Model-driven simulation depends on regression results\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mindmap interaction mode\u003C/td>\u003Ctd>initialPredictors bridge, interaction mode toggle\u003C/td>\u003Ctd>Simplify Mindmap to drilldown + narrative only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>App wiring\u003C/td>\u003Ctd>Dashboard Regression tab, toolbar buttons, persistence fields\u003C/td>\u003Ctd>Remove all entry points\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tests\u003C/td>\u003Ctd>Regression-specific test files\u003C/td>\u003Ctd>Tests for removed code\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Glossary\u003C/td>\u003Ctd>Regression-specific terms\u003C/td>\u003Ctd>Terms for absent features\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-stays\">What Stays\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-stays\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Stays”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Item\u003C/th>\u003Cth>Rationale\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Core math files (regression.ts, multiRegression.ts, interaction.ts, modelReduction.ts, matrix.ts)\u003C/td>\u003Ctd>Preserved for Phase 2 reuse; exports removed from package index so tree-shaking excludes from builds\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ScatterPlot chart component\u003C/td>\u003Ctd>General-purpose chart, used outside regression context\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>WhatIfSimulator (direct-adjustment mode)\u003C/td>\u003Ctd>Standalone value; users adjust factors directly without needing a fitted model\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>simulateDirectAdjustment, calculateProjectedStats\u003C/td>\u003Ctd>Support direct What-If mode\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mindmap (drilldown + narrative modes)\u003C/td>\u003Ctd>Core investigation tool; only interaction mode removed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ANOVA\u003C/td>\u003Ctd>Independent statistical feature, not part of regression\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation\">Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Remove regression exports from \u003Ccode dir=\"auto\">@variscout/core\u003C/code> index (keep source files)\u003C/li>\n\u003Cli>Remove RegressionPanelBase and related views from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/li>\n\u003Cli>Remove useRegressionState from \u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/li>\n\u003Cli>Remove ModelDrivenSimulator from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/li>\n\u003Cli>Remove Mindmap interaction mode (simplify to drilldown + narrative)\u003C/li>\n\u003Cli>Remove simulateFromModel from \u003Ccode dir=\"auto\">@variscout/core\u003C/code> variation exports\u003C/li>\n\u003Cli>Remove regression tab and toolbar entry points from PWA and Azure Dashboard\u003C/li>\n\u003Cli>Remove regression persistence fields from AnalysisState (.vrs format)\u003C/li>\n\u003Cli>Remove regression-specific test files\u003C/li>\n\u003Cli>Remove regression glossary terms from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/li>\n\u003Cli>Update feature-parity matrix and documentation\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"re-enablement-criteria-phase-2\">Re-enablement Criteria (Phase 2)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#re-enablement-criteria-phase-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Re-enablement Criteria (Phase 2)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Re-introduce regression when all of the following are met:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Post-marketplace certification\u003C/strong> — Azure App is listed and generating revenue\u003C/li>\n\u003Cli>\u003Cstrong>Customer demand signal\u003C/strong> — At least one paying customer requests regression or investigation workflow\u003C/li>\n\u003Cli>\u003Cstrong>UX validation\u003C/strong> — Regression workflow tested with target persona (Green Belt Gary) for discoverability and comprehension\u003C/li>\n\u003C/ol>\n\u003Cp>Phase 2 implementation can re-export core math files and rebuild UI layer on the preserved foundation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"positive\">Positive\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#positive\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Positive”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Reduced MVP scope — fewer features to certify, document, and support at launch\u003C/li>\n\u003Cli>Simpler user experience — core analysis workflow without advanced statistical modelling\u003C/li>\n\u003Cli>Smaller bundle size — ~3,300 lines excluded from production builds\u003C/li>\n\u003Cli>Lower certification surface area for Azure Marketplace submission\u003C/li>\n\u003Cli>What-If direct mode still provides actionable simulation without requiring regression knowledge\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"negative\">Negative\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#negative\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Negative”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Investigation-to-Action workflow (Mindmap -> Regression -> What-If) loses its middle step; the bridge from investigation to simulation becomes manual\u003C/li>\n\u003Cli>Users who understand GLM lose a power feature (mitigated: no such users have been identified in the target audience)\u003C/li>\n\u003Cli>Core math files remain in repo without test coverage (mitigated: re-enable tests when re-enabling feature)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"neutral\">Neutral\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#neutral\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Neutral”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Core math files (regression.ts, multiRegression.ts, etc.) stay in the repository, unexported — no maintenance cost, no build cost\u003C/li>\n\u003Cli>ScatterPlot chart component continues to work for general-purpose use\u003C/li>\n\u003Cli>WhatIfSimulator direct mode is unaffected\u003C/li>\n\u003C/ul>", + { + "headings": 2668, + "localImagePaths": 2687, + "remoteImagePaths": 2688, + "frontmatter": 2689, + "imagePaths": 2690 + }, + [2669, 2671, 2672, 2673, 2676, 2679, 2680, 2683, 2684, 2685, 2686], + { "depth": 30, "slug": 2670, "text": 2658 }, + "adr-014-defer-regression-to-phase-2", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2674, "text": 2675 }, + "what-gets-removed", + "What Gets Removed", + { "depth": 79, "slug": 2677, "text": 2678 }, + "what-stays", + "What Stays", + { "depth": 33, "slug": 1885, "text": 1886 }, + { "depth": 33, "slug": 2681, "text": 2682 }, + "re-enablement-criteria-phase-2", + "Re-enablement Criteria (Phase 2)", + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2446, "text": 2447 }, + { "depth": 79, "slug": 2449, "text": 2450 }, + { "depth": 79, "slug": 2537, "text": 2538 }, + [], + [], + { "title": 2658 }, + [], + "07-decisions/adr-015-investigation-board", + { "id": 2691, "data": 2693, "body": 2698, "filePath": 2699, "digest": 2700, "rendered": 2701 }, + { + "title": 2694, + "editUrl": 16, + "head": 2695, + "template": 18, + "sidebar": 2696, + "pagefind": 16, + "draft": 20 + }, + "ADR-015: Investigation Board — Finding Status & Comments", + [], + { "hidden": 20, "attrs": 2697 }, + {}, + "# ADR-015: Investigation Board — Finding Status & Comments\n\n**Status:** Accepted (revised 2026-02-26)\n**Date:** 2026-02-26\n**Related:** ADR-014 (regression deferral — Phase 2 boundary)\n\n---\n\n## Context\n\nThe Findings system (db9c380) captures bookmarked filter states during drill-down.\nCurrently a flat list: pin → note → restore. Quality engineers need to track the\nlifecycle of each finding — was it investigated? How significant is the contribution?\nWhat was learned along the way?\n\nWithout this, analysts either:\n\n- Keep mental notes about which findings they've followed up on\n- Use external tools (spreadsheets, sticky notes) to track investigation status\n- Lose context when returning to a project after days/weeks\n\nThis creates a gap in the investigation workflow: findings are captured but there's\nno structured way to track the analysis that happens between pinning and acting.\n\n## Decision\n\nAdd lightweight investigation tracking to findings: analysis-focused statuses,\noptional classification tags, comment threads, and a grouped board view. This is\nNOT project management — no assignees, no due dates, no priority levels.\n\n### Statuses (Investigation lifecycle)\n\n| Status | Meaning | When to use |\n| ------------- | ------------------------------------- | ------------------------ |\n| Observed | Pattern spotted, not yet investigated | Auto-set on pin |\n| Investigating | Actively drilling into this | Analyst is working on it |\n| Analyzed | Analysis completed | Ready to classify |\n\n### Tags (Analyzed finding classification)\n\nAnalyzed findings can optionally be tagged to indicate their significance:\n\n| Tag | Meaning | Color |\n| ---------- | ---------------------------------------------- | ------ |\n| Key Driver | Significant variation contributor — actionable | Green |\n| Low Impact | Minor or negligible contribution | Gray |\n| _(none)_ | Analysis done, not yet classified | Purple |\n\nTags reflect _contribution magnitude_, not causal certainty. VariScout quantifies\ncontribution, not causation.\n\n### Comments\n\nEach finding gains a timestamped comment thread — the investigation log. Captures\nwhat was checked, when, and what was learned. Not a chat system — a sequential\nrecord of investigation steps.\n\n### Board View\n\nTwo layouts for the grouped-by-status view:\n\n- Panel (≤500px): Accordion — collapsible sections per status (3 columns)\n- Popout window (≥500px): Horizontal columns with native drag-and-drop\n\n### Scope boundary\n\nThis enriches the investigation workflow. It does NOT:\n\n- Add task management features (assignees, due dates, priorities)\n- Affect the What-If Simulator (independent tool)\n\n### Migration\n\nPersisted `.vrs` files may contain the old 4-status model (`confirmed`/`dismissed`).\nOn load, `migrateFindings()` maps:\n\n- `confirmed` → `analyzed` + tag `key-driver`\n- `dismissed` → `analyzed` + tag `low-impact`\n\n## Consequences\n\n### Easier\n\n- Track investigation progress across sessions (Azure)\n- Classify findings by contribution magnitude (Key Driver / Low Impact)\n- Audit trail: low-impact findings document what was ruled out\n- Key Driver findings become natural shortlist for action\n- Teaching tool: trainers can ask \"show me your key drivers\"\n\n### Harder\n\n- More UI surface area to maintain (status badge, tag badge, comments, board view)\n- FindingsAction protocol grows (7 action types including set-tag)\n\n---\n\n## Revision: Unified Observations (2026-03-02)\n\n### Change\n\nChart text annotations are now unified with the Findings system via `FindingSource`.\nPreviously, text annotations on charts were transient visual elements stored in\n`DisplayOptions` (alongside color highlights). They are now stored as `Finding`\nobjects in `AnalysisState`, with a `source` field linking each finding to its\noriginating chart element.\n\n### FindingSource\n\n```typescript\ninterface FindingSource {\n chartType: 'boxplot' | 'pareto' | 'ichart';\n category?: string; // Boxplot/Pareto category name\n anchorX?: number; // I-Chart: 0–1 fraction of chart width\n anchorY?: number; // I-Chart: 0–1 fraction of chart height\n}\n```\n\n`Finding.source` is optional — breadcrumb-pinned findings have no source (they\ncapture filter state, not chart position). Chart observations always have a source.\n\n### What changed\n\n| Aspect | Before | After |\n| --------------------- | ---------------------------- | -------------------------------------- |\n| Text annotation store | `DisplayOptions` (transient) | `Finding[]` in `AnalysisState` |\n| Color highlights | `DisplayOptions` | `DisplayOptions` (unchanged) |\n| Persistence | Lost on project reload (PWA) | Persisted with findings (Azure .vrs) |\n| Context menu label | \"Add note\" | \"Add observation\" |\n| ChartAnnotationLayer | Reads `ChartAnnotation[]` | Reads `Finding[]` (filtered by source) |\n| Status visibility | None | Status dot on annotation box |", + "src/content/docs/07-decisions/adr-015-investigation-board.md", + "102ff4062509a60f", + { "html": 2702, "metadata": 2703 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-015-investigation-board--finding-status--comments\">ADR-015: Investigation Board — Finding Status & Comments\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-015-investigation-board--finding-status--comments\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-015: Investigation Board — Finding Status & Comments”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status:\u003C/strong> Accepted (revised 2026-02-26)\n\u003Cstrong>Date:\u003C/strong> 2026-02-26\n\u003Cstrong>Related:\u003C/strong> ADR-014 (regression deferral — Phase 2 boundary)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Findings system (db9c380) captures bookmarked filter states during drill-down.\nCurrently a flat list: pin → note → restore. Quality engineers need to track the\nlifecycle of each finding — was it investigated? How significant is the contribution?\nWhat was learned along the way?\u003C/p>\n\u003Cp>Without this, analysts either:\u003C/p>\n\u003Cul>\n\u003Cli>Keep mental notes about which findings they’ve followed up on\u003C/li>\n\u003Cli>Use external tools (spreadsheets, sticky notes) to track investigation status\u003C/li>\n\u003Cli>Lose context when returning to a project after days/weeks\u003C/li>\n\u003C/ul>\n\u003Cp>This creates a gap in the investigation workflow: findings are captured but there’s\nno structured way to track the analysis that happens between pinning and acting.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Add lightweight investigation tracking to findings: analysis-focused statuses,\noptional classification tags, comment threads, and a grouped board view. This is\nNOT project management — no assignees, no due dates, no priority levels.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"statuses-investigation-lifecycle\">Statuses (Investigation lifecycle)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#statuses-investigation-lifecycle\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Statuses (Investigation lifecycle)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Status\u003C/th>\u003Cth>Meaning\u003C/th>\u003Cth>When to use\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Observed\u003C/td>\u003Ctd>Pattern spotted, not yet investigated\u003C/td>\u003Ctd>Auto-set on pin\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Investigating\u003C/td>\u003Ctd>Actively drilling into this\u003C/td>\u003Ctd>Analyst is working on it\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analyzed\u003C/td>\u003Ctd>Analysis completed\u003C/td>\u003Ctd>Ready to classify\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tags-analyzed-finding-classification\">Tags (Analyzed finding classification)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tags-analyzed-finding-classification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tags (Analyzed finding classification)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Analyzed findings can optionally be tagged to indicate their significance:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tag\u003C/th>\u003Cth>Meaning\u003C/th>\u003Cth>Color\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Key Driver\u003C/td>\u003Ctd>Significant variation contributor — actionable\u003C/td>\u003Ctd>Green\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Low Impact\u003C/td>\u003Ctd>Minor or negligible contribution\u003C/td>\u003Ctd>Gray\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cem>(none)\u003C/em>\u003C/td>\u003Ctd>Analysis done, not yet classified\u003C/td>\u003Ctd>Purple\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Tags reflect \u003Cem>contribution magnitude\u003C/em>, not causal certainty. VariScout quantifies\ncontribution, not causation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"comments\">Comments\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#comments\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Comments”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each finding gains a timestamped comment thread — the investigation log. Captures\nwhat was checked, when, and what was learned. Not a chat system — a sequential\nrecord of investigation steps.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"board-view\">Board View\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#board-view\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Board View”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Two layouts for the grouped-by-status view:\u003C/p>\n\u003Cul>\n\u003Cli>Panel (≤500px): Accordion — collapsible sections per status (3 columns)\u003C/li>\n\u003Cli>Popout window (≥500px): Horizontal columns with native drag-and-drop\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"scope-boundary\">Scope boundary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#scope-boundary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scope boundary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This enriches the investigation workflow. It does NOT:\u003C/p>\n\u003Cul>\n\u003Cli>Add task management features (assignees, due dates, priorities)\u003C/li>\n\u003Cli>Affect the What-If Simulator (independent tool)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"migration\">Migration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#migration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Migration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Persisted \u003Ccode dir=\"auto\">.vrs\u003C/code> files may contain the old 4-status model (\u003Ccode dir=\"auto\">confirmed\u003C/code>/\u003Ccode dir=\"auto\">dismissed\u003C/code>).\nOn load, \u003Ccode dir=\"auto\">migrateFindings()\u003C/code> maps:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">confirmed\u003C/code> → \u003Ccode dir=\"auto\">analyzed\u003C/code> + tag \u003Ccode dir=\"auto\">key-driver\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">dismissed\u003C/code> → \u003Ccode dir=\"auto\">analyzed\u003C/code> + tag \u003Ccode dir=\"auto\">low-impact\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"easier\">Easier\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#easier\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Easier”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Track investigation progress across sessions (Azure)\u003C/li>\n\u003Cli>Classify findings by contribution magnitude (Key Driver / Low Impact)\u003C/li>\n\u003Cli>Audit trail: low-impact findings document what was ruled out\u003C/li>\n\u003Cli>Key Driver findings become natural shortlist for action\u003C/li>\n\u003Cli>Teaching tool: trainers can ask “show me your key drivers”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"harder\">Harder\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#harder\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Harder”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>More UI surface area to maintain (status badge, tag badge, comments, board view)\u003C/li>\n\u003Cli>FindingsAction protocol grows (7 action types including set-tag)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"revision-unified-observations-2026-03-02\">Revision: Unified Observations (2026-03-02)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#revision-unified-observations-2026-03-02\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Revision: Unified Observations (2026-03-02)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"change\">Change\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#change\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Change”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Chart text annotations are now unified with the Findings system via \u003Ccode dir=\"auto\">FindingSource\u003C/code>.\nPreviously, text annotations on charts were transient visual elements stored in\n\u003Ccode dir=\"auto\">DisplayOptions\u003C/code> (alongside color highlights). They are now stored as \u003Ccode dir=\"auto\">Finding\u003C/code>\nobjects in \u003Ccode dir=\"auto\">AnalysisState\u003C/code>, with a \u003Ccode dir=\"auto\">source\u003C/code> field linking each finding to its\noriginating chart element.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"findingsource\">FindingSource\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#findingsource\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “FindingSource”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FindingSource {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartType\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ichart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">category\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Boxplot/Pareto category name\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">anchorX\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// I-Chart: 0–1 fraction of chart width\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">anchorY\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// I-Chart: 0–1 fraction of chart height\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface FindingSource { chartType: 'boxplot' | 'pareto' | 'ichart'; category?: string; // Boxplot/Pareto category name anchorX?: number; // I-Chart: 0–1 fraction of chart width anchorY?: number; // I-Chart: 0–1 fraction of chart height}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">Finding.source\u003C/code> is optional — breadcrumb-pinned findings have no source (they\ncapture filter state, not chart position). Chart observations always have a source.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-changed\">What changed\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-changed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What changed”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Before\u003C/th>\u003Cth>After\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Text annotation store\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DisplayOptions\u003C/code> (transient)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Finding[]\u003C/code> in \u003Ccode dir=\"auto\">AnalysisState\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Color highlights\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DisplayOptions\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DisplayOptions\u003C/code> (unchanged)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Persistence\u003C/td>\u003Ctd>Lost on project reload (PWA)\u003C/td>\u003Ctd>Persisted with findings (Azure .vrs)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Context menu label\u003C/td>\u003Ctd>”Add note\"\u003C/td>\u003Ctd>\"Add observation”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ChartAnnotationLayer\u003C/td>\u003Ctd>Reads \u003Ccode dir=\"auto\">ChartAnnotation[]\u003C/code>\u003C/td>\u003Ctd>Reads \u003Ccode dir=\"auto\">Finding[]\u003C/code> (filtered by source)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Status visibility\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>Status dot on annotation box\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 2704, + "localImagePaths": 2742, + "remoteImagePaths": 2743, + "frontmatter": 2744, + "imagePaths": 2745 + }, + [2705, 2707, 2708, 2709, 2712, 2715, 2718, 2721, 2724, 2727, 2728, 2729, 2730, 2733, 2736, 2739], + { "depth": 30, "slug": 2706, "text": 2694 }, + "adr-015-investigation-board--finding-status--comments", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2710, "text": 2711 }, + "statuses-investigation-lifecycle", + "Statuses (Investigation lifecycle)", + { "depth": 79, "slug": 2713, "text": 2714 }, + "tags-analyzed-finding-classification", + "Tags (Analyzed finding classification)", + { "depth": 79, "slug": 2716, "text": 2717 }, + "comments", + "Comments", + { "depth": 79, "slug": 2719, "text": 2720 }, + "board-view", + "Board View", + { "depth": 79, "slug": 2722, "text": 2723 }, + "scope-boundary", + "Scope boundary", + { "depth": 79, "slug": 2725, "text": 2726 }, + "migration", + "Migration", + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2609, "text": 2610 }, + { "depth": 79, "slug": 2612, "text": 2613 }, + { "depth": 33, "slug": 2731, "text": 2732 }, + "revision-unified-observations-2026-03-02", + "Revision: Unified Observations (2026-03-02)", + { "depth": 79, "slug": 2734, "text": 2735 }, + "change", + "Change", + { "depth": 79, "slug": 2737, "text": 2738 }, + "findingsource", + "FindingSource", + { "depth": 79, "slug": 2740, "text": 2741 }, + "what-changed", + "What changed", + [], + [], + { "title": 2694 }, + [], + "07-decisions/adr-016-security-evaluation", + { "id": 2746, "data": 2748, "body": 2753, "filePath": 2754, "digest": 2755, "rendered": 2756 }, + { + "title": 2749, + "editUrl": 16, + "head": 2750, + "template": 18, + "sidebar": 2751, + "pagefind": 16, + "draft": 20 + }, + "ADR-016 Security Evaluation: Teams Integration", + [], + { "hidden": 20, "attrs": 2752 }, + {}, + "# ADR-016 Security Evaluation: Teams Integration\n\n**Status**: Draft\n\n**Date**: 2026-02-27\n\n**Related**: [ADR-016](adr-016-teams-integration.md) (Teams Integration), [ADR-007](adr-007-azure-marketplace-distribution.md) (Marketplace Distribution), [ADR-015](adr-015-investigation-board.md) (Investigation Board)\n\n**Scope**: Security evaluation of the proposed Teams integration design from three external perspectives: Microsoft certification, enterprise IT procurement, and a Finnish manufacturer buyer.\n\n---\n\n## 1. Executive Summary\n\nVariScout is a client-side statistical process control tool deployed as an Azure Managed Application to the customer's own tenant. There is no publisher-operated backend — all statistical computation runs in the browser, data is stored in the customer's OneDrive/IndexedDB, and the publisher has zero access to customer resources. ADR-016 proposes adding Microsoft Teams integration, which escalates Graph API permissions from `User.Read` + `Files.ReadWrite` to include `Files.ReadWrite.All` and `Channel.ReadBasic.All`, adds a ~50-line Azure Function for OBO token exchange, and introduces photo uploads to channel SharePoint storage.\n\n### Key Security Claims\n\n| # | Claim | Evidence | File Reference |\n| --- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |\n| 1 | Publisher has zero access to customer resources | `publisherManagement` disabled in ARM template, immutable after publishing | `infra/mainTemplate.json` (no publisher authorization block) |\n| 2 | Data never leaves the customer's Azure tenant | Graph API calls go to `graph.microsoft.com/v1.0/me/drive/` — customer's own OneDrive/SharePoint | `apps/azure/src/services/storage.ts:104,108` |\n| 3 | Authentication is platform-managed, not custom | EasyAuth (`authsettingsV2`) handles all auth; app code only reads `/.auth/me` | `infra/mainTemplate.json:93-127`, `apps/azure/src/auth/easyAuth.ts` |\n| 4 | Secrets use ARM `secureString`, CI uses OIDC | `clientSecret` parameter is `secureString`; GitHub Actions uses federated identity (no stored credentials) | `infra/mainTemplate.json:31-35`, `.github/workflows/deploy-azure-staging.yml:13,46-49` |\n| 5 | Storage model is strictly additive (no DELETE calls) | `storage.ts` contains only `PUT` (save) and `GET` (load/list) Graph API calls; no `DELETE` endpoint | `apps/azure/src/services/storage.ts:172-264` |\n\n### Verdict by Perspective\n\n- **Microsoft**: Should pass certification. Scope escalation is a standard pattern for Teams apps; requires clear justification during review.\n- **Enterprise IT**: Strong data sovereignty story. Gaps in security headers and incident response process should be closed before marketplace submission.\n- **Finnish manufacturer**: Likely to approve with a clear admin consent guide and Finnish-language privacy notice. Data-stays-in-your-tenant is the decisive factor.\n\n---\n\n## 2. Security Baseline (Pre-Teams)\n\nWhat's already in place, verified against the codebase:\n\n| Area | Detail | Reference |\n| ----------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |\n| Authentication | EasyAuth platform-managed (Azure AD); Standard: `User.Read`; Team: + `Files.ReadWrite` scopes | `infra/mainTemplate.json:96-125`, `apps/azure/src/auth/easyAuth.ts` |\n| Transport | HTTPS-only (`httpsOnly: true`), TLS 1.2+ (`minTlsVersion: \"1.2\"`) | `infra/mainTemplate.json:70,88` |\n| FTP | Disabled (`ftpsState: \"Disabled\"`) | `infra/mainTemplate.json:89` |\n| Secrets in ARM | `clientSecret` uses `secureString` parameter type | `infra/mainTemplate.json:31-35` |\n| CI/CD credentials | OIDC federated identity — no stored secrets for Azure login | `.github/workflows/deploy-azure-staging.yml:13,46-49` |\n| Data sovereignty | Deployed to customer's managed RG; publisher has zero access | `infra/mainTemplate.json` (no publisher authorization) |\n| Client storage | IndexedDB via Dexie (browser sandbox), offline-first with cloud sync | `apps/azure/src/services/storage.ts` |\n| Token management | Proactive refresh (5-minute window), error classification with retry backoff | `apps/azure/src/auth/easyAuth.ts:96-134`, `apps/azure/src/services/storage.ts:70-100` |\n| Health endpoint | Excluded from auth (`excludedPaths: [\"/health\"]`) — no data exposure | `infra/mainTemplate.json:106` |\n| Telemetry | None — no analytics, no tracking, no outbound calls except Graph API | Entire codebase |\n\n### Known Gaps\n\n| Gap | Severity | Detail |\n| -------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------- |\n| No Content Security Policy (CSP) | Medium | `server.js` sets no CSP header; XSS protection relies on React's built-in escaping only |\n| No security headers | Medium | No `Strict-Transport-Security`, `X-Frame-Options`, `X-Content-Type-Options`, or `Referrer-Policy` in `server.js` |\n| No Key Vault integration | Low | `clientSecret` stored as App Service app setting (encrypted at rest by platform, but not in Key Vault) |\n| No managed identity | Low | App Service uses client secret for auth, not managed identity |\n| No SECURITY.md | Medium | No vulnerability disclosure policy, no security contact |\n| IndexedDB unencrypted | Low | Browser-managed encryption; data at rest not application-encrypted (standard for web apps) |\n| No `pnpm audit` in CI | Medium | Dependency vulnerabilities not automatically caught in pipeline |\n| No SBOM generation | Low | No Software Bill of Materials for supply chain transparency |\n\n---\n\n## 3. Teams Integration Security Delta\n\nWhat ADR-016 adds to the attack surface:\n\n### New Permission Scopes\n\n| Scope | Type | Consent | Current | With Teams |\n| ----------------------- | --------- | --------- | ------- | ---------- |\n| `User.Read` | Delegated | User | Yes | Yes |\n| `Files.ReadWrite` | Delegated | User | Yes | Yes |\n| `Files.ReadWrite.All` | Delegated | **Admin** | No | **Yes** |\n| `Channel.ReadBasic.All` | Delegated | **Admin** | No | **Yes** |\n\n`Files.ReadWrite.All` (delegated) does NOT grant access to all files in the organization. It allows the app to access files the signed-in user already has access to. The \"All\" means \"all file locations\" (OneDrive + SharePoint), not \"all users' files.\" Per-channel scoping is enforced by Teams membership — the natural access control.\n\n### New Runtime Dependency\n\n`@microsoft/teams-js` (~40KB gzipped) — maintained by Microsoft, published on npm. Single purpose: detect Teams context and enable SSO. No server-side component.\n\n### New Infrastructure (Phase 6)\n\nAzure Function for On-Behalf-Of (OBO) token exchange:\n\n- ~50 lines, stateless, single-purpose\n- Exchanges Teams SSO token for Graph API access token\n- Deployed via ARM template alongside App Service\n- Fallback: EasyAuth redirect if OBO exchange fails\n\n### New Data Flows\n\n| Flow | Direction | Data | Storage Location |\n| --------------------- | ---------- | ---------------------- | ------------------------------------------- |\n| Channel project files | Read/Write | `.vrs` JSON files | Channel SharePoint document library |\n| Photo upload | Write-only | JPEG images | Channel SharePoint (`Photos/{analysisId}/`) |\n| Photo thumbnails | Embedded | ~50KB base64 per photo | Inside `.vrs` file (for cross-user preview) |\n| Channel listing | Read-only | Channel names + IDs | Not stored (runtime only) |\n\n### New Client-Side Processing\n\n- Two-layer EXIF/GPS metadata stripping before upload: canvas re-encode + explicit byte-level `stripExifFromBlob` (removes all APP1 markers from JPEG binary)\n- Base64 thumbnail generation (~50KB per photo)\n- Optimistic merge for concurrent `.vrs` edits (conflict detection via `eTag`)\n\n### Strongest Security Property\n\n**Additive-only storage model**: No `DELETE` calls to Graph API. Conflicts create copies (`\"(conflict copy).vrs\"`). Photos are immutable once uploaded. This is auditable — IT admins can verify the app contains no `DELETE /drive/items/{id}` calls.\n\n---\n\n## 4. Perspective: Microsoft\n\n### 4.1 Marketplace Certification Impact\n\nADR-016 does not change the Managed Application certification flow documented in [`certification-guide.md`](../08-products/azure/certification-guide.md). The Standard plan ships first (no new scopes, no Teams). The Team plan adds:\n\n| Certification Layer | Impact | Assessment |\n| ------------------------------ | -------- | ----------------------------------------------------------- |\n| Layer 1: Publisher eligibility | None | Same publisher account |\n| Layer 2: Content validation | Minor | Updated listing text, new screenshots for Teams features |\n| Layer 3: Technical validation | Moderate | New ARM resources (Azure Function), scope escalation review |\n\nThe Azure Function adds a new ARM resource (`Microsoft.Web/sites` with Functions runtime) to `mainTemplate.json`. This is a standard pattern and should pass arm-ttk validation.\n\n### 4.2 Teams App Store (If Submitted)\n\nIf VariScout is submitted to the Teams App Store (separate from Azure Marketplace):\n\n| Requirement | Status | Notes |\n| ------------------------- | --------- | ------------------------------------------------------------ |\n| Publisher Verification | Required | Verify Entra ID (RDMAIC Oy) via Partner Center |\n| Publisher Attestation | Required | Self-reported security practices questionnaire |\n| M365 App Certification | Optional | Paid, SOC 2 equivalent — consider for enterprise credibility |\n| SSO requirement | Satisfied | OBO flow provides silent SSO in Teams context |\n| Permissions justification | Required | Each Graph scope must have documented business justification |\n\nPublisher Verification is a one-time process (~2 weeks) linking the Entra ID tenant to the Partner Center account. This is a prerequisite for any Teams app published to the store.\n\n### 4.3 Graph API Permission Review\n\nMicrosoft reviews Graph API permission requests during Teams App Store certification. Key justifications:\n\n| Scope | Justification | Why Not Narrower? |\n| ----------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `Files.ReadWrite.All` | Read/write `.vrs` project files and photos in channel SharePoint document libraries | `Files.ReadWrite` only covers personal OneDrive; channel SharePoint requires `.All`. `Sites.ReadWrite.All` would be broader (includes all SharePoint sites). |\n| `Channel.ReadBasic.All` | List channels the user belongs to for storage location selection | Minimum scope for channel enumeration. Does not read channel messages. |\n\n**Why delegated, not application**: Application permissions would allow access without a signed-in user — inappropriate for an interactive analysis tool. Delegated permissions are scoped to the signed-in user's own access.\n\n**No-delete commitment**: `Files.ReadWrite.All` technically includes delete capability, but VariScout never exercises it. Microsoft cannot enforce this at the scope level (no write-without-delete scope exists), but the app's codebase is auditable. The storage model is documented as strictly additive in ADR-016.\n\n### 4.4 Microsoft Security Baseline Assessment\n\n| Area | Rating | Detail |\n| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------- |\n| Identity | GREEN | EasyAuth (platform-managed) + OBO flow (standard Microsoft pattern) |\n| Data | GREEN | Customer tenant isolation, publisher zero access, delegated-only permissions |\n| Network | AMBER | No VNet integration, no WAF. Acceptable for SPA — no server-side data processing to protect. App Service has built-in DDoS protection. |\n| Monitoring | AMBER | No App Insights by default. Customer can add it to their managed RG. Recommend documenting how in admin guide. |\n| Secrets | GREEN | ARM `secureString` for client secret; OIDC for CI/CD (no stored credentials) |\n| Transport | GREEN | HTTPS-only, TLS 1.2+, FTP disabled |\n\n---\n\n## 5. Perspective: Enterprise IT & Procurement\n\n### 5.1 Security Questionnaire Answers\n\nCommon security questionnaire sections mapped to VariScout's architecture:\n\n| Question Area | Answer Pattern |\n| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| **Where is data stored?** | In your own Azure tenant (OneDrive/SharePoint/IndexedDB). The publisher has zero access to your resources. We are not a sub-processor — your data never transits our systems. |\n| **What data do you collect?** | None. No telemetry, no analytics, no usage tracking. The app makes no outbound calls except to Microsoft Graph API (your own tenant). |\n| **How is data encrypted?** | In transit: TLS 1.2+ (HTTPS-only). At rest: Azure Storage encryption (platform-managed, your tenant). IndexedDB: browser-managed encryption. |\n| **What is your authentication model?** | Azure AD via EasyAuth (platform-managed by App Service). No custom auth code, no password storage, no session tokens in cookies. |\n| **Do you have access to our data?** | No. Publisher management is disabled in the Managed Application. This setting is immutable after marketplace publication. |\n| **What permissions does the app require?** | Standard plan: `User.Read` only (local storage, no OneDrive). Team plan adds: `Files.ReadWrite` (personal OneDrive), `Files.ReadWrite.All` (delegated, admin consent — for channel SharePoint), `Channel.ReadBasic.All` (channel listing). |\n| **Do you have a SOC 2 report?** | No formal audit. Architecture makes many SOC 2 controls not applicable (no multi-tenant backend, no data processing, no access to customer data). |\n| **How do you handle incidents?** | Gap — no formal incident response process. See hardening checklist (Section 8). |\n| **What is your dependency management process?** | Gap — no automated `pnpm audit` in CI pipeline. See hardening checklist. |\n\n### 5.2 Compliance Posture\n\n| Framework | Assessment |\n| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **SOC 2** | Architecture is inherently strong (no multi-tenant infrastructure to audit). No formal SOC 2 report — expensive for a small publisher and less meaningful when the publisher has no access to customer data. Consider Publisher Attestation (Teams App Store) as a lighter-weight alternative. |\n| **ISO 27001** | Many controls are N/A (no backend infrastructure, no data centers, no HR security for backend operators). The relevant controls (access management, cryptography, supplier relationships) are satisfied by the Azure platform. |\n| **GDPR Art. 28** | VariScout is NOT a data processor. It is software deployed to the customer's own tenant — analogous to installing an application on your own server. No Data Processing Agreement (DPA) is legally required, though a DPA template may reduce procurement friction. |\n| **Zero Trust** | Verify explicitly: Entra ID authentication on every request (EasyAuth). Least privilege: delegated permissions only, scoped to signed-in user. Assume breach: no server state to compromise, no stored credentials in the app. |\n\n### 5.3 Supply Chain & Incident Response\n\n**Runtime dependencies** (direct, across all packages):\n\n| Category | Count | Examples |\n| ------------------------- | ------- | ------------------------------------------------ |\n| Microsoft/Visx (charting) | 9 | `@visx/axis`, `@visx/scale`, `@visx/shape`, etc. |\n| D3 ecosystem | 2 | `d3-array`, `d3` |\n| Data handling | 3 | `papaparse`, `exceljs`, `dexie` |\n| React ecosystem | 3 | `react`, `react-dom`, `lucide-react` |\n| Utilities | 3 | `html-to-image`, `jszip`, `tailwindcss-animate` |\n| **Total direct runtime** | **~20** | No backend dependencies |\n\nTeams integration adds 1 dependency: `@microsoft/teams-js` (Microsoft-maintained).\n\n**Gaps:**\n\n| Gap | Impact | Recommendation |\n| --------------------- | ------------------------- | -------------------------------------------------------------- |\n| No SBOM | Supply chain transparency | Generate CycloneDX SBOM in CI, include in release artifacts |\n| No `pnpm audit` in CI | Vulnerability detection | Add `pnpm audit --audit-level=high` step to deploy workflow |\n| No SECURITY.md | Vulnerability disclosure | Create SECURITY.md with disclosure policy and security contact |\n| No security@ contact | Incident communication | Establish security@variscout.com before marketplace submission |\n\n---\n\n## 6. Perspective: Finnish Manufacturer\n\n### 6.1 Who Is This Buyer?\n\nA €5M revenue Finnish manufacturer with ~200 employees. They have M365 E3 or E5 licenses, Entra ID for identity, and 1–3 IT staff who manage network, endpoints, M365, and security. The quality manager found VariScout through the free PWA and wants the team version. €99–299/month is a real budget line item that goes through procurement.\n\n### 6.2 The Admin Consent Conversation\n\nThe quality manager asks IT to approve the app. Here's what happens:\n\n**Standard plan (€99/month)**: No admin consent needed. Only `User.Read` is requested (local-only storage, no OneDrive). IT may still want to review the app registration, but there's no blocker.\n\n**Team plan (€299/month)**: IT admin must grant tenant-wide consent for `Files.ReadWrite.All`. The admin sees a consent screen listing the permission. What they need to understand:\n\n- **\"Access files that user has access to\"** — the app cannot access files the user couldn't already access. It's _delegated_, not _application_.\n- **\"All\" means all locations** — OneDrive + SharePoint, not \"all users' files.\"\n- **No delete in practice** — the app only creates and updates files. The codebase contains no DELETE calls. IT can verify this.\n- **Conditional Access applies** — existing policies (managed devices, MFA, geographic restrictions) are enforced on VariScout like any other Entra ID app.\n\n**Recommendation**: Create a one-page \"IT Admin Guide\" with the consent screen explained in plain language. Include a screenshot of the exact consent dialog. Provide it in Finnish and English.\n\n### 6.3 Data Sensitivity\n\nQuality data can be commercially sensitive:\n\n| Data Type | Sensitivity | Mitigation |\n| --------------------------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |\n| Process parameters (fill weights, tolerances) | Trade secrets | Data stays in company's own tenant. Publisher has zero access. |\n| Specification limits (USL/LSL) | Competitive intelligence | Stored in `.vrs` files in company's own OneDrive/SharePoint |\n| Shop floor photos | May show equipment, products, personnel | EXIF/GPS stripping before upload. Photos stored in channel SharePoint — subject to company's DLP policies. |\n| Base64 photo thumbnails in `.vrs` | Low-res previews visible to channel members | Subject to SharePoint access control + company's DLP policies |\n| Analysis findings and comments | Investigation notes, potentially sensitive | Author + timestamp audit trail. Stored in company's own tenant. |\n\n**Key message**: VariScout does not introduce a new data sovereignty risk. The data was already in the company's M365 tenant (or would be, in spreadsheets and emails). VariScout structures it in a purpose-built format within the same tenant boundary.\n\n### 6.4 Shop Floor Reality\n\n| Concern | How VariScout Addresses It |\n| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Shared/BYOD devices on the shop floor | Entra ID authentication on every session. No persistent local credentials. Conditional Access can restrict to managed devices. |\n| Poor factory WiFi | Offline-first: IndexedDB saves locally, syncs when connected. Sync queue with exponential backoff. |\n| Teams mobile sidebar | One-tap access from Teams app. Teams SDK `media.selectMedia()` for native camera experience; `devicePermissions: [\"media\"]` in manifest gives IT admins audit trail. HTML5 file input fallback outside Teams. |\n| Multiple operators using one terminal | Each operator signs in with their own Entra ID. Author field on findings provides clear attribution. |\n| Language | App UI in English. Quality terminology (Cpk, SPC) is international. Privacy notice should be in Finnish (GDPR good practice). |\n\n### 6.5 Trust Decision\n\n**What makes them say YES:**\n\n- Data stays in their own Azure tenant — verifiable by IT admin\n- Microsoft billing (shows up on existing Azure invoice, procurement-friendly)\n- Standard Entra ID authentication — no new identity system\n- Clear admin consent guide in Finnish\n- Free PWA trial first — they've already used the methodology\n- Publisher has zero access — immutable setting, verifiable in Azure portal\n- Conditional Access and DLP policies apply normally\n\n**What makes them say NO:**\n\n- Unclear permission justification (why does a chart tool need `Files.ReadWrite.All`?)\n- No incident response contact or process\n- No Finnish-language privacy notice\n- No evaluation/trial period for the paid plan\n- Unknown publisher (RDMAIC Oy) with no track record\n- No reference customers in Finnish manufacturing\n\n**Recommendation**: Address the \"NO\" factors before launching the Team plan. A 30-day free trial in Azure Marketplace removes the biggest purchase friction for new customers.\n\n### 6.6 Finnish/EU Regulatory Context\n\n| Regulation | Applicability | Notes |\n| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |\n| **GDPR** | VariScout is NOT a data processor (Art. 28). It is software deployed to the customer's own tenant. The customer is the data controller; VariScout is a software tool, not a service that processes personal data on behalf of the customer. | A DPA template reduces procurement friction even though it's technically unnecessary. |\n| **NIS2** | Likely N/A for a €5M, 200-person manufacturer unless they're in a critical sector (energy, transport, health, water, digital infrastructure, food). | If the customer is in scope, VariScout's architecture (no backend, customer-controlled) minimizes supply chain risk concerns. |\n| **EU AI Act** | N/A — VariScout performs statistical calculations, not AI inference. No machine learning models, no automated decision-making. | Clear differentiation if asked. |\n| **21 CFR Part 11** | If the customer is in pharma/medical devices: author field + timestamp + photo immutability provides a foundation for electronic records compliance. Not a formal Part 11 validation — customer would need to validate in their own quality system. | Consider a compliance alignment statement for regulated industries. |\n\n---\n\n## 7. Consolidated Risk Matrix\n\n| # | Area | Microsoft | Enterprise IT | Finnish Mfr | Severity | Mitigation | Timeline |\n| --- | -------------------------------------- | --------- | ------------- | ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |\n| 1 | Missing CSP header | AMBER | AMBER | LOW | Medium | Add `Content-Security-Policy` to `server.js` responses. Allow `self`, Graph API, and blob: for chart exports. | Before submission |\n| 2 | Missing security headers | AMBER | AMBER | LOW | Medium | Add `Strict-Transport-Security`, `X-Frame-Options: DENY`, `X-Content-Type-Options: nosniff`, `Referrer-Policy: strict-origin-when-cross-origin` to `server.js`. | Before submission |\n| 3 | `Files.ReadWrite.All` scope | GREEN | AMBER | AMBER | Medium | Document justification (channel SharePoint requires `.All`). Create admin consent guide with consent screen screenshot. Explain delegated vs application. | Before Team plan |\n| 4 | IndexedDB unencrypted | GREEN | LOW | LOW | Low | Standard for web apps. Browser manages storage isolation. Document in security FAQ. | Ongoing |\n| 5 | No Key Vault for client secret | LOW | AMBER | LOW | Low | App setting is encrypted at rest by App Service platform. Key Vault is a best practice but not required. Document as optional hardening step for security-conscious customers. | Ongoing |\n| 6 | EXIF/GPS stripping | GREEN | GREEN | GREEN | Medium | Done. Two-layer approach: canvas re-encode + byte-level `stripExifFromBlob` that parses JPEG binary and removes all APP1 markers. 23 unit tests verify GPS, camera model, and orientation are stripped. | Done |\n| 7 | OBO Azure Function | GREEN | AMBER | LOW | Low | ~50 lines, stateless, single-purpose. Standard Microsoft pattern. Include in ARM template. Ensure function has no storage bindings, no persistent state. | Before Team plan |\n| 8 | No incident response process | AMBER | RED | AMBER | High | Create SECURITY.md with disclosure policy. Establish security@variscout.com. Define response timeline (acknowledge \u003C48h, triage \u003C7 days). | Before submission |\n| 9 | No SBOM | LOW | AMBER | LOW | Low | Generate CycloneDX SBOM in CI pipeline. Include in release artifacts. | Before submission |\n| 10 | No `pnpm audit` in CI | AMBER | AMBER | LOW | Medium | Add `pnpm audit --audit-level=high` to deploy workflow. Fail the build on high/critical vulnerabilities. | Before submission |\n| 11 | No admin consent documentation | GREEN | AMBER | RED | High | Create one-page admin guide with consent screen screenshot. Translate to Finnish. Include in onboarding materials. | Before Team plan |\n| 12 | Conflict resolution (concurrent edits) | GREEN | LOW | AMBER | Medium | Optimistic merge for additive operations. Unresolvable conflicts create copies (zero data loss). Document behavior in user guide. | Before Team plan |\n\n---\n\n## 8. Pre-Submission Hardening Checklist\n\n### Tier 1: Before Marketplace Submission (Standard Plan)\n\nThese items should be completed before submitting the Standard plan to Azure Marketplace:\n\n- [ ] **Security headers in `server.js`** — Add CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy\n- [ ] **SECURITY.md** — Vulnerability disclosure policy with security@ contact and response timeline\n- [ ] **`pnpm audit` in CI** — Add to `.github/workflows/deploy-azure-staging.yml`, fail on high/critical\n- [ ] **security@variscout.com** — Establish email address and forwarding\n- [ ] **Dependency review** — Run `pnpm audit`, resolve any high/critical findings\n- [ ] **No console errors in production build** — Verify browser console is clean (submission-checklist.md item)\n- [ ] **CSP headers verified** — Confirm SPA + Graph API calls work with CSP policy (submission-checklist.md item)\n\n### Tier 2: Before Team Plan Launch\n\nThese items are required for the Teams-integrated Team plan:\n\n- [ ] **Admin consent guide** — One-page document explaining each permission scope in plain language. Finnish + English.\n- [ ] **Publisher Verification** — Complete Entra ID verification for RDMAIC Oy via Partner Center (~2 weeks)\n- [ ] **DPA template** — Draft Data Processing Agreement template even though technically unnecessary (reduces procurement friction)\n- [ ] **Finnish privacy notice** — Translate privacy policy to Finnish (GDPR good practice)\n- [x] **EXIF stripping implementation** — Two-layer: canvas re-encode + byte-level `stripExifFromBlob` (APP1 marker removal). 23 unit tests verify GPS, camera model, and orientation stripped.\n- [ ] **Photo immutability enforcement** — Verify no update/delete paths for uploaded photos in storage layer\n- [ ] **OBO function security review** — Verify stateless, no storage bindings, minimal permissions\n- [ ] **Conflict resolution testing** — Test concurrent edit scenarios, verify conflict copy creation\n- [ ] **SBOM generation** — CycloneDX SBOM in CI, included in release artifacts\n- [ ] **Publisher Attestation** — Complete self-reported security practices for Teams App Store\n\n### Tier 3: Ongoing\n\n- [ ] **Monthly dependency audit** — `pnpm audit` on a schedule, triage and patch\n- [ ] **Annual security review** — Re-evaluate this document against current codebase and threat landscape\n- [ ] **Permission scope review** — Verify no scope creep in ARM template or EasyAuth configuration\n- [ ] **Customer feedback loop** — Track security-related questions from buyers, update FAQ and admin guide\n\n---\n\n## Appendices\n\n### A. Permission Scope Reference\n\nComplete Graph API permissions used by VariScout, current and proposed:\n\n| Scope | Type | Consent | Plan | Justification |\n| ----------------------- | -------------- | --------- | ---- | ---------------------------------------------------------------------------------------------------------------------- |\n| `openid` | OpenID Connect | User | Both | Standard OIDC — authentication |\n| `profile` | OpenID Connect | User | Both | Display name for author field |\n| `email` | OpenID Connect | User | Both | User identification |\n| `User.Read` | Delegated | User | Both | Read signed-in user's profile |\n| `Files.ReadWrite` | Delegated | User | Team | Read/write to user's personal OneDrive (`/me/drive/`) |\n| `Files.ReadWrite.All` | Delegated | **Admin** | Team | Read/write to channel SharePoint document libraries. Required because `Files.ReadWrite` only covers personal OneDrive. |\n| `Channel.ReadBasic.All` | Delegated | **Admin** | Team | List channels the user belongs to (for storage location picker). Does NOT read channel messages. |\n\n**Not requested (and why):**\n\n| Scope | Why Not |\n| ----------------------------------- | ------------------------------------------------------------------------------------------------------------ |\n| `Sites.ReadWrite.All` | Broader than needed. `Files.ReadWrite.All` with delegated consent is sufficient for channel file access. |\n| `Files.ReadWrite.All` (Application) | Application permissions bypass user context. VariScout is an interactive tool — always has a signed-in user. |\n| `ChannelMessage.Read.All` | VariScout does not read Teams messages. It only stores files in channel document libraries. |\n| `Mail.Read` / `Mail.Send` | No email functionality. |\n\n### B. Data Flow Diagrams\n\n#### Standard Plan (Browser Mode)\n\n```\n┌─────────────────────────────────────────────────────────┐\n│ Customer's Browser │\n│ ┌────────────────────────────────────────────┐ │\n│ │ VariScout SPA │ │\n│ │ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ │\n│ │ │ Analysis │ │ Charts │ │ Findings│ │ │\n│ │ │ Engine │ │ (Visx) │ │ Log │ │ │\n│ │ └────┬─────┘ └──────────┘ └─────────┘ │ │\n│ │ │ │ │\n│ │ ┌────▼─────────────────────────────────┐ │ │\n│ │ │ IndexedDB (Dexie) │ │ │\n│ │ │ Local .vrs project storage │ │ │\n│ │ └────┬─────────────────────────────────┘ │ │\n│ └───────┼────────────────────────────────────┘ │\n│ │ Graph API (Files.ReadWrite) │\n│ ▼ │\n│ ┌───────────────────────────────────┐ │\n│ │ Customer's OneDrive │ │\n│ │ /VariScout/Projects/*.vrs │ │\n│ └───────────────────────────────────┘ │\n└─────────────────────────────────────────────────────────┘\n ▲ EasyAuth (User.Read)\n │\n┌──────┴──────────┐\n│ Azure AD │\n│ (Customer's │\n│ Entra ID) │\n└─────────────────┘\n```\n\n#### Team Plan (Teams Mode)\n\n```\n┌──────────────────────────────────────────────────────────────┐\n│ Teams WebView / Mobile │\n│ ┌────────────────────────────────────────────────┐ │\n│ │ VariScout SPA + @microsoft/teams-js │ │\n│ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │\n│ │ │ Analysis │ │ Field │ │ Photo │ │ │\n│ │ │ Engine │ │ View │ │ Capture │ │ │\n│ │ └────┬─────┘ └──────────┘ └──────┬───────┘ │ │\n│ │ │ │ │ │\n│ │ │ ┌─────────────────────────┘ │ │\n│ │ │ │ EXIF strip (canvas + byte-level) │ │\n│ │ ┌────▼────▼────────────────────────────────┐ │ │\n│ │ │ IndexedDB (offline queue) │ │ │\n│ │ └────┬─────────────────────────────────────┘ │ │\n│ └───────┼────────────────────────────────────────┘ │\n│ │ Graph API (Files.ReadWrite.All) │\n│ ▼ │\n│ ┌──────────────────────────────────────────┐ │\n│ │ Customer's SharePoint / OneDrive │ │\n│ │ Channel Files/VariScout/Projects/*.vrs │ │\n│ │ Channel Files/VariScout/Photos/**/*.jpg │ │\n│ └──────────────────────────────────────────┘ │\n└──────────────────────────────────────────────────────────────┘\n ▲ Teams SSO → OBO (Azure Function)\n │\n┌──────┴──────────┐ ┌──────────────────────┐\n│ Azure AD │ │ Azure Function │\n│ (Customer's │◄────│ OBO token exchange │\n│ Entra ID) │ │ (~50 lines, │\n└─────────────────┘ │ stateless) │\n └──────────────────────┘\n```\n\n#### Photo Capture Flow\n\n```\nTeams SDK media.selectMedia() ─┐\n ├──► processPhoto()\nHTML5 file input (fallback) ───┘\n │\n ▼\nCanvas re-encode + stripExifFromBlob ──── EXIF/GPS stripped (two layers)\n │\n ├── Base64 thumbnail (~50KB) → embedded in .vrs\n │\n └── Full-res JPEG → PUT to SharePoint\n Channel Files/VariScout/Photos/{analysisId}/{findingId}/photo-001.jpg\n │\n └── Immutable (no update/delete API calls)\n```\n\n### C. GDPR Quick Reference\n\n| GDPR Article | VariScout Response |\n| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Art. 5 (Principles) | Data minimization: only quality data the user explicitly inputs. Purpose limitation: statistical analysis only. |\n| Art. 6 (Lawful basis) | Customer determines lawful basis. VariScout is a tool, not a controller or processor. |\n| Art. 12–14 (Transparency) | Privacy policy at variscout.com/legal/privacy describes the software's data handling. |\n| Art. 17 (Right to erasure) | Customer controls all data in their own tenant. Delete from OneDrive/SharePoint/IndexedDB at any time. Publisher has no access. |\n| Art. 25 (Privacy by design) | No telemetry, no tracking, offline-first, data in customer's tenant, publisher zero access. |\n| Art. 28 (Processor) | NOT applicable. VariScout is deployed to the customer's own infrastructure. No data processing on behalf of the customer. |\n| Art. 32 (Security) | TLS 1.2+, HTTPS-only, EasyAuth (platform-managed), Entra ID authentication. |\n| Art. 33–34 (Breach notification) | Publisher has no access to customer data, so cannot experience a data breach involving customer data. Customer's own Azure tenant security applies. |\n| Art. 44–49 (International transfers) | No transfers. Data stays in the customer's Azure region. Publisher has zero access. |\n\n---\n\n## See Also\n\n- [ADR-016: Teams Integration](adr-016-teams-integration.md) — the technical design being evaluated\n- [ADR-007: Azure Marketplace Distribution](adr-007-azure-marketplace-distribution.md) — two-plan model (Standard + Team)\n- [Certification Guide](../08-products/azure/certification-guide.md) — marketplace certification mechanics\n- [Submission Checklist](../08-products/azure/submission-checklist.md) — submission readiness tracker\n- [Authentication](../08-products/azure/authentication.md) — EasyAuth setup details", + "src/content/docs/07-decisions/adr-016-security-evaluation.md", + "a7703b6263d493ea", + { "html": 2757, "metadata": 2758 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-016-security-evaluation-teams-integration\">ADR-016 Security Evaluation: Teams Integration\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-016-security-evaluation-teams-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-016 Security Evaluation: Teams Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Draft\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2026-02-27\u003C/p>\n\u003Cp>\u003Cstrong>Related\u003C/strong>: \u003Ca href=\"adr-016-teams-integration.md\">ADR-016\u003C/a> (Teams Integration), \u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a> (Marketplace Distribution), \u003Ca href=\"adr-015-investigation-board.md\">ADR-015\u003C/a> (Investigation Board)\u003C/p>\n\u003Cp>\u003Cstrong>Scope\u003C/strong>: Security evaluation of the proposed Teams integration design from three external perspectives: Microsoft certification, enterprise IT procurement, and a Finnish manufacturer buyer.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"1-executive-summary\">1. Executive Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#1-executive-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Executive Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is a client-side statistical process control tool deployed as an Azure Managed Application to the customer’s own tenant. There is no publisher-operated backend — all statistical computation runs in the browser, data is stored in the customer’s OneDrive/IndexedDB, and the publisher has zero access to customer resources. ADR-016 proposes adding Microsoft Teams integration, which escalates Graph API permissions from \u003Ccode dir=\"auto\">User.Read\u003C/code> + \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> to include \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> and \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>, adds a ~50-line Azure Function for OBO token exchange, and introduces photo uploads to channel SharePoint storage.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-security-claims\">Key Security Claims\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-security-claims\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Security Claims”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Claim\u003C/th>\u003Cth>Evidence\u003C/th>\u003Cth>File Reference\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Publisher has zero access to customer resources\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">publisherManagement\u003C/code> disabled in ARM template, immutable after publishing\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json\u003C/code> (no publisher authorization block)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Data never leaves the customer’s Azure tenant\u003C/td>\u003Ctd>Graph API calls go to \u003Ccode dir=\"auto\">graph.microsoft.com/v1.0/me/drive/\u003C/code> — customer’s own OneDrive/SharePoint\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/azure/src/services/storage.ts:104,108\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Authentication is platform-managed, not custom\u003C/td>\u003Ctd>EasyAuth (\u003Ccode dir=\"auto\">authsettingsV2\u003C/code>) handles all auth; app code only reads \u003Ccode dir=\"auto\">/.auth/me\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json:93-127\u003C/code>, \u003Ccode dir=\"auto\">apps/azure/src/auth/easyAuth.ts\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Secrets use ARM \u003Ccode dir=\"auto\">secureString\u003C/code>, CI uses OIDC\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">clientSecret\u003C/code> parameter is \u003Ccode dir=\"auto\">secureString\u003C/code>; GitHub Actions uses federated identity (no stored credentials)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json:31-35\u003C/code>, \u003Ccode dir=\"auto\">.github/workflows/deploy-azure-staging.yml:13,46-49\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Storage model is strictly additive (no DELETE calls)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">storage.ts\u003C/code> contains only \u003Ccode dir=\"auto\">PUT\u003C/code> (save) and \u003Ccode dir=\"auto\">GET\u003C/code> (load/list) Graph API calls; no \u003Ccode dir=\"auto\">DELETE\u003C/code> endpoint\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/azure/src/services/storage.ts:172-264\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"verdict-by-perspective\">Verdict by Perspective\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#verdict-by-perspective\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Verdict by Perspective”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Microsoft\u003C/strong>: Should pass certification. Scope escalation is a standard pattern for Teams apps; requires clear justification during review.\u003C/li>\n\u003Cli>\u003Cstrong>Enterprise IT\u003C/strong>: Strong data sovereignty story. Gaps in security headers and incident response process should be closed before marketplace submission.\u003C/li>\n\u003Cli>\u003Cstrong>Finnish manufacturer\u003C/strong>: Likely to approve with a clear admin consent guide and Finnish-language privacy notice. Data-stays-in-your-tenant is the decisive factor.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"2-security-baseline-pre-teams\">2. Security Baseline (Pre-Teams)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#2-security-baseline-pre-teams\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Security Baseline (Pre-Teams)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>What’s already in place, verified against the codebase:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Area\u003C/th>\u003Cth>Detail\u003C/th>\u003Cth>Reference\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Authentication\u003C/td>\u003Ctd>EasyAuth platform-managed (Azure AD); Standard: \u003Ccode dir=\"auto\">User.Read\u003C/code>; Team: + \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> scopes\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json:96-125\u003C/code>, \u003Ccode dir=\"auto\">apps/azure/src/auth/easyAuth.ts\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Transport\u003C/td>\u003Ctd>HTTPS-only (\u003Ccode dir=\"auto\">httpsOnly: true\u003C/code>), TLS 1.2+ (\u003Ccode dir=\"auto\">minTlsVersion: \"1.2\"\u003C/code>)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json:70,88\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>FTP\u003C/td>\u003Ctd>Disabled (\u003Ccode dir=\"auto\">ftpsState: \"Disabled\"\u003C/code>)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json:89\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Secrets in ARM\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">clientSecret\u003C/code> uses \u003Ccode dir=\"auto\">secureString\u003C/code> parameter type\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json:31-35\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CI/CD credentials\u003C/td>\u003Ctd>OIDC federated identity — no stored secrets for Azure login\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">.github/workflows/deploy-azure-staging.yml:13,46-49\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data sovereignty\u003C/td>\u003Ctd>Deployed to customer’s managed RG; publisher has zero access\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json\u003C/code> (no publisher authorization)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Client storage\u003C/td>\u003Ctd>IndexedDB via Dexie (browser sandbox), offline-first with cloud sync\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/azure/src/services/storage.ts\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Token management\u003C/td>\u003Ctd>Proactive refresh (5-minute window), error classification with retry backoff\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/azure/src/auth/easyAuth.ts:96-134\u003C/code>, \u003Ccode dir=\"auto\">apps/azure/src/services/storage.ts:70-100\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Health endpoint\u003C/td>\u003Ctd>Excluded from auth (\u003Ccode dir=\"auto\">excludedPaths: [\"/health\"]\u003C/code>) — no data exposure\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json:106\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Telemetry\u003C/td>\u003Ctd>None — no analytics, no tracking, no outbound calls except Graph API\u003C/td>\u003Ctd>Entire codebase\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"known-gaps\">Known Gaps\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#known-gaps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Known Gaps”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Gap\u003C/th>\u003Cth>Severity\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No Content Security Policy (CSP)\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">server.js\u003C/code> sets no CSP header; XSS protection relies on React’s built-in escaping only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No security headers\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>No \u003Ccode dir=\"auto\">Strict-Transport-Security\u003C/code>, \u003Ccode dir=\"auto\">X-Frame-Options\u003C/code>, \u003Ccode dir=\"auto\">X-Content-Type-Options\u003C/code>, or \u003Ccode dir=\"auto\">Referrer-Policy\u003C/code> in \u003Ccode dir=\"auto\">server.js\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No Key Vault integration\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">clientSecret\u003C/code> stored as App Service app setting (encrypted at rest by platform, but not in Key Vault)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No managed identity\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>App Service uses client secret for auth, not managed identity\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No SECURITY.md\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>No vulnerability disclosure policy, no security contact\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>IndexedDB unencrypted\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Browser-managed encryption; data at rest not application-encrypted (standard for web apps)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No \u003Ccode dir=\"auto\">pnpm audit\u003C/code> in CI\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Dependency vulnerabilities not automatically caught in pipeline\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No SBOM generation\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>No Software Bill of Materials for supply chain transparency\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"3-teams-integration-security-delta\">3. Teams Integration Security Delta\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#3-teams-integration-security-delta\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Teams Integration Security Delta”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>What ADR-016 adds to the attack surface:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"new-permission-scopes\">New Permission Scopes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#new-permission-scopes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “New Permission Scopes”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Scope\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Consent\u003C/th>\u003Cth>Current\u003C/th>\u003Cth>With Teams\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">User.Read\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>User\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>User\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>\u003Cstrong>Admin\u003C/strong>\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>\u003Cstrong>Yes\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>\u003Cstrong>Admin\u003C/strong>\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>\u003Cstrong>Yes\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> (delegated) does NOT grant access to all files in the organization. It allows the app to access files the signed-in user already has access to. The “All” means “all file locations” (OneDrive + SharePoint), not “all users’ files.” Per-channel scoping is enforced by Teams membership — the natural access control.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"new-runtime-dependency\">New Runtime Dependency\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#new-runtime-dependency\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “New Runtime Dependency”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">@microsoft/teams-js\u003C/code> (~40KB gzipped) — maintained by Microsoft, published on npm. Single purpose: detect Teams context and enable SSO. No server-side component.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"new-infrastructure-phase-6\">New Infrastructure (Phase 6)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#new-infrastructure-phase-6\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “New Infrastructure (Phase 6)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Azure Function for On-Behalf-Of (OBO) token exchange:\u003C/p>\n\u003Cul>\n\u003Cli>~50 lines, stateless, single-purpose\u003C/li>\n\u003Cli>Exchanges Teams SSO token for Graph API access token\u003C/li>\n\u003Cli>Deployed via ARM template alongside App Service\u003C/li>\n\u003Cli>Fallback: EasyAuth redirect if OBO exchange fails\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"new-data-flows\">New Data Flows\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#new-data-flows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “New Data Flows”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Flow\u003C/th>\u003Cth>Direction\u003C/th>\u003Cth>Data\u003C/th>\u003Cth>Storage Location\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Channel project files\u003C/td>\u003Ctd>Read/Write\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">.vrs\u003C/code> JSON files\u003C/td>\u003Ctd>Channel SharePoint document library\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Photo upload\u003C/td>\u003Ctd>Write-only\u003C/td>\u003Ctd>JPEG images\u003C/td>\u003Ctd>Channel SharePoint (\u003Ccode dir=\"auto\">Photos/{analysisId}/\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Photo thumbnails\u003C/td>\u003Ctd>Embedded\u003C/td>\u003Ctd>~50KB base64 per photo\u003C/td>\u003Ctd>Inside \u003Ccode dir=\"auto\">.vrs\u003C/code> file (for cross-user preview)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Channel listing\u003C/td>\u003Ctd>Read-only\u003C/td>\u003Ctd>Channel names + IDs\u003C/td>\u003Ctd>Not stored (runtime only)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"new-client-side-processing\">New Client-Side Processing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#new-client-side-processing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “New Client-Side Processing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Two-layer EXIF/GPS metadata stripping before upload: canvas re-encode + explicit byte-level \u003Ccode dir=\"auto\">stripExifFromBlob\u003C/code> (removes all APP1 markers from JPEG binary)\u003C/li>\n\u003Cli>Base64 thumbnail generation (~50KB per photo)\u003C/li>\n\u003Cli>Optimistic merge for concurrent \u003Ccode dir=\"auto\">.vrs\u003C/code> edits (conflict detection via \u003Ccode dir=\"auto\">eTag\u003C/code>)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"strongest-security-property\">Strongest Security Property\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#strongest-security-property\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strongest Security Property”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Additive-only storage model\u003C/strong>: No \u003Ccode dir=\"auto\">DELETE\u003C/code> calls to Graph API. Conflicts create copies (\u003Ccode dir=\"auto\">\"(conflict copy).vrs\"\u003C/code>). Photos are immutable once uploaded. This is auditable — IT admins can verify the app contains no \u003Ccode dir=\"auto\">DELETE /drive/items/{id}\u003C/code> calls.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-perspective-microsoft\">4. Perspective: Microsoft\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-perspective-microsoft\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Perspective: Microsoft”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"41-marketplace-certification-impact\">4.1 Marketplace Certification Impact\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#41-marketplace-certification-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4.1 Marketplace Certification Impact”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>ADR-016 does not change the Managed Application certification flow documented in \u003Ca href=\"../08-products/azure/certification-guide.md\">\u003Ccode dir=\"auto\">certification-guide.md\u003C/code>\u003C/a>. The Standard plan ships first (no new scopes, no Teams). The Team plan adds:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Certification Layer\u003C/th>\u003Cth>Impact\u003C/th>\u003Cth>Assessment\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Layer 1: Publisher eligibility\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>Same publisher account\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Layer 2: Content validation\u003C/td>\u003Ctd>Minor\u003C/td>\u003Ctd>Updated listing text, new screenshots for Teams features\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Layer 3: Technical validation\u003C/td>\u003Ctd>Moderate\u003C/td>\u003Ctd>New ARM resources (Azure Function), scope escalation review\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The Azure Function adds a new ARM resource (\u003Ccode dir=\"auto\">Microsoft.Web/sites\u003C/code> with Functions runtime) to \u003Ccode dir=\"auto\">mainTemplate.json\u003C/code>. This is a standard pattern and should pass arm-ttk validation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"42-teams-app-store-if-submitted\">4.2 Teams App Store (If Submitted)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#42-teams-app-store-if-submitted\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4.2 Teams App Store (If Submitted)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>If VariScout is submitted to the Teams App Store (separate from Azure Marketplace):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Requirement\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Publisher Verification\u003C/td>\u003Ctd>Required\u003C/td>\u003Ctd>Verify Entra ID (RDMAIC Oy) via Partner Center\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Publisher Attestation\u003C/td>\u003Ctd>Required\u003C/td>\u003Ctd>Self-reported security practices questionnaire\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>M365 App Certification\u003C/td>\u003Ctd>Optional\u003C/td>\u003Ctd>Paid, SOC 2 equivalent — consider for enterprise credibility\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SSO requirement\u003C/td>\u003Ctd>Satisfied\u003C/td>\u003Ctd>OBO flow provides silent SSO in Teams context\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Permissions justification\u003C/td>\u003Ctd>Required\u003C/td>\u003Ctd>Each Graph scope must have documented business justification\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Publisher Verification is a one-time process (~2 weeks) linking the Entra ID tenant to the Partner Center account. This is a prerequisite for any Teams app published to the store.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"43-graph-api-permission-review\">4.3 Graph API Permission Review\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#43-graph-api-permission-review\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4.3 Graph API Permission Review”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Microsoft reviews Graph API permission requests during Teams App Store certification. Key justifications:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Scope\u003C/th>\u003Cth>Justification\u003C/th>\u003Cth>Why Not Narrower?\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>\u003C/td>\u003Ctd>Read/write \u003Ccode dir=\"auto\">.vrs\u003C/code> project files and photos in channel SharePoint document libraries\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> only covers personal OneDrive; channel SharePoint requires \u003Ccode dir=\"auto\">.All\u003C/code>. \u003Ccode dir=\"auto\">Sites.ReadWrite.All\u003C/code> would be broader (includes all SharePoint sites).\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>\u003C/td>\u003Ctd>List channels the user belongs to for storage location selection\u003C/td>\u003Ctd>Minimum scope for channel enumeration. Does not read channel messages.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Why delegated, not application\u003C/strong>: Application permissions would allow access without a signed-in user — inappropriate for an interactive analysis tool. Delegated permissions are scoped to the signed-in user’s own access.\u003C/p>\n\u003Cp>\u003Cstrong>No-delete commitment\u003C/strong>: \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> technically includes delete capability, but VariScout never exercises it. Microsoft cannot enforce this at the scope level (no write-without-delete scope exists), but the app’s codebase is auditable. The storage model is documented as strictly additive in ADR-016.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"44-microsoft-security-baseline-assessment\">4.4 Microsoft Security Baseline Assessment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#44-microsoft-security-baseline-assessment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4.4 Microsoft Security Baseline Assessment”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Area\u003C/th>\u003Cth>Rating\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Identity\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>EasyAuth (platform-managed) + OBO flow (standard Microsoft pattern)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>Customer tenant isolation, publisher zero access, delegated-only permissions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Network\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>No VNet integration, no WAF. Acceptable for SPA — no server-side data processing to protect. App Service has built-in DDoS protection.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Monitoring\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>No App Insights by default. Customer can add it to their managed RG. Recommend documenting how in admin guide.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Secrets\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>ARM \u003Ccode dir=\"auto\">secureString\u003C/code> for client secret; OIDC for CI/CD (no stored credentials)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Transport\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>HTTPS-only, TLS 1.2+, FTP disabled\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"5-perspective-enterprise-it--procurement\">5. Perspective: Enterprise IT & Procurement\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#5-perspective-enterprise-it--procurement\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Perspective: Enterprise IT & Procurement”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"51-security-questionnaire-answers\">5.1 Security Questionnaire Answers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#51-security-questionnaire-answers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5.1 Security Questionnaire Answers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Common security questionnaire sections mapped to VariScout’s architecture:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Question Area\u003C/th>\u003Cth>Answer Pattern\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Where is data stored?\u003C/strong>\u003C/td>\u003Ctd>In your own Azure tenant (OneDrive/SharePoint/IndexedDB). The publisher has zero access to your resources. We are not a sub-processor — your data never transits our systems.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>What data do you collect?\u003C/strong>\u003C/td>\u003Ctd>None. No telemetry, no analytics, no usage tracking. The app makes no outbound calls except to Microsoft Graph API (your own tenant).\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>How is data encrypted?\u003C/strong>\u003C/td>\u003Ctd>In transit: TLS 1.2+ (HTTPS-only). At rest: Azure Storage encryption (platform-managed, your tenant). IndexedDB: browser-managed encryption.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>What is your authentication model?\u003C/strong>\u003C/td>\u003Ctd>Azure AD via EasyAuth (platform-managed by App Service). No custom auth code, no password storage, no session tokens in cookies.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Do you have access to our data?\u003C/strong>\u003C/td>\u003Ctd>No. Publisher management is disabled in the Managed Application. This setting is immutable after marketplace publication.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>What permissions does the app require?\u003C/strong>\u003C/td>\u003Ctd>Standard plan: \u003Ccode dir=\"auto\">User.Read\u003C/code> only (local storage, no OneDrive). Team plan adds: \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> (personal OneDrive), \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> (delegated, admin consent — for channel SharePoint), \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code> (channel listing).\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Do you have a SOC 2 report?\u003C/strong>\u003C/td>\u003Ctd>No formal audit. Architecture makes many SOC 2 controls not applicable (no multi-tenant backend, no data processing, no access to customer data).\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>How do you handle incidents?\u003C/strong>\u003C/td>\u003Ctd>Gap — no formal incident response process. See hardening checklist (Section 8).\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>What is your dependency management process?\u003C/strong>\u003C/td>\u003Ctd>Gap — no automated \u003Ccode dir=\"auto\">pnpm audit\u003C/code> in CI pipeline. See hardening checklist.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"52-compliance-posture\">5.2 Compliance Posture\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#52-compliance-posture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5.2 Compliance Posture”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Framework\u003C/th>\u003Cth>Assessment\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>SOC 2\u003C/strong>\u003C/td>\u003Ctd>Architecture is inherently strong (no multi-tenant infrastructure to audit). No formal SOC 2 report — expensive for a small publisher and less meaningful when the publisher has no access to customer data. Consider Publisher Attestation (Teams App Store) as a lighter-weight alternative.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>ISO 27001\u003C/strong>\u003C/td>\u003Ctd>Many controls are N/A (no backend infrastructure, no data centers, no HR security for backend operators). The relevant controls (access management, cryptography, supplier relationships) are satisfied by the Azure platform.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>GDPR Art. 28\u003C/strong>\u003C/td>\u003Ctd>VariScout is NOT a data processor. It is software deployed to the customer’s own tenant — analogous to installing an application on your own server. No Data Processing Agreement (DPA) is legally required, though a DPA template may reduce procurement friction.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Zero Trust\u003C/strong>\u003C/td>\u003Ctd>Verify explicitly: Entra ID authentication on every request (EasyAuth). Least privilege: delegated permissions only, scoped to signed-in user. Assume breach: no server state to compromise, no stored credentials in the app.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"53-supply-chain--incident-response\">5.3 Supply Chain & Incident Response\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#53-supply-chain--incident-response\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5.3 Supply Chain & Incident Response”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Runtime dependencies\u003C/strong> (direct, across all packages):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Category\u003C/th>\u003Cth>Count\u003C/th>\u003Cth>Examples\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Microsoft/Visx (charting)\u003C/td>\u003Ctd>9\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@visx/axis\u003C/code>, \u003Ccode dir=\"auto\">@visx/scale\u003C/code>, \u003Ccode dir=\"auto\">@visx/shape\u003C/code>, etc.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>D3 ecosystem\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">d3-array\u003C/code>, \u003Ccode dir=\"auto\">d3\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data handling\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">papaparse\u003C/code>, \u003Ccode dir=\"auto\">exceljs\u003C/code>, \u003Ccode dir=\"auto\">dexie\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>React ecosystem\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">react\u003C/code>, \u003Ccode dir=\"auto\">react-dom\u003C/code>, \u003Ccode dir=\"auto\">lucide-react\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Utilities\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">html-to-image\u003C/code>, \u003Ccode dir=\"auto\">jszip\u003C/code>, \u003Ccode dir=\"auto\">tailwindcss-animate\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total direct runtime\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>~20\u003C/strong>\u003C/td>\u003Ctd>No backend dependencies\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Teams integration adds 1 dependency: \u003Ccode dir=\"auto\">@microsoft/teams-js\u003C/code> (Microsoft-maintained).\u003C/p>\n\u003Cp>\u003Cstrong>Gaps:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Gap\u003C/th>\u003Cth>Impact\u003C/th>\u003Cth>Recommendation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No SBOM\u003C/td>\u003Ctd>Supply chain transparency\u003C/td>\u003Ctd>Generate CycloneDX SBOM in CI, include in release artifacts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No \u003Ccode dir=\"auto\">pnpm audit\u003C/code> in CI\u003C/td>\u003Ctd>Vulnerability detection\u003C/td>\u003Ctd>Add \u003Ccode dir=\"auto\">pnpm audit --audit-level=high\u003C/code> step to deploy workflow\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No SECURITY.md\u003C/td>\u003Ctd>Vulnerability disclosure\u003C/td>\u003Ctd>Create SECURITY.md with disclosure policy and security contact\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No security@ contact\u003C/td>\u003Ctd>Incident communication\u003C/td>\u003Ctd>Establish \u003Ca href=\"mailto:security@variscout.com\">security@variscout.com\u003C/a> before marketplace submission\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"6-perspective-finnish-manufacturer\">6. Perspective: Finnish Manufacturer\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#6-perspective-finnish-manufacturer\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Perspective: Finnish Manufacturer”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"61-who-is-this-buyer\">6.1 Who Is This Buyer?\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#61-who-is-this-buyer\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6.1 Who Is This Buyer?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A €5M revenue Finnish manufacturer with ~200 employees. They have M365 E3 or E5 licenses, Entra ID for identity, and 1–3 IT staff who manage network, endpoints, M365, and security. The quality manager found VariScout through the free PWA and wants the team version. €99–299/month is a real budget line item that goes through procurement.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"62-the-admin-consent-conversation\">6.2 The Admin Consent Conversation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#62-the-admin-consent-conversation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6.2 The Admin Consent Conversation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The quality manager asks IT to approve the app. Here’s what happens:\u003C/p>\n\u003Cp>\u003Cstrong>Standard plan (€99/month)\u003C/strong>: No admin consent needed. Only \u003Ccode dir=\"auto\">User.Read\u003C/code> is requested (local-only storage, no OneDrive). IT may still want to review the app registration, but there’s no blocker.\u003C/p>\n\u003Cp>\u003Cstrong>Team plan (€299/month)\u003C/strong>: IT admin must grant tenant-wide consent for \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>. The admin sees a consent screen listing the permission. What they need to understand:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>“Access files that user has access to”\u003C/strong> — the app cannot access files the user couldn’t already access. It’s \u003Cem>delegated\u003C/em>, not \u003Cem>application\u003C/em>.\u003C/li>\n\u003Cli>\u003Cstrong>“All” means all locations\u003C/strong> — OneDrive + SharePoint, not “all users’ files.”\u003C/li>\n\u003Cli>\u003Cstrong>No delete in practice\u003C/strong> — the app only creates and updates files. The codebase contains no DELETE calls. IT can verify this.\u003C/li>\n\u003Cli>\u003Cstrong>Conditional Access applies\u003C/strong> — existing policies (managed devices, MFA, geographic restrictions) are enforced on VariScout like any other Entra ID app.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Recommendation\u003C/strong>: Create a one-page “IT Admin Guide” with the consent screen explained in plain language. Include a screenshot of the exact consent dialog. Provide it in Finnish and English.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"63-data-sensitivity\">6.3 Data Sensitivity\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#63-data-sensitivity\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6.3 Data Sensitivity”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Quality data can be commercially sensitive:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Data Type\u003C/th>\u003Cth>Sensitivity\u003C/th>\u003Cth>Mitigation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Process parameters (fill weights, tolerances)\u003C/td>\u003Ctd>Trade secrets\u003C/td>\u003Ctd>Data stays in company’s own tenant. Publisher has zero access.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Specification limits (USL/LSL)\u003C/td>\u003Ctd>Competitive intelligence\u003C/td>\u003Ctd>Stored in \u003Ccode dir=\"auto\">.vrs\u003C/code> files in company’s own OneDrive/SharePoint\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shop floor photos\u003C/td>\u003Ctd>May show equipment, products, personnel\u003C/td>\u003Ctd>EXIF/GPS stripping before upload. Photos stored in channel SharePoint — subject to company’s DLP policies.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Base64 photo thumbnails in \u003Ccode dir=\"auto\">.vrs\u003C/code>\u003C/td>\u003Ctd>Low-res previews visible to channel members\u003C/td>\u003Ctd>Subject to SharePoint access control + company’s DLP policies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analysis findings and comments\u003C/td>\u003Ctd>Investigation notes, potentially sensitive\u003C/td>\u003Ctd>Author + timestamp audit trail. Stored in company’s own tenant.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key message\u003C/strong>: VariScout does not introduce a new data sovereignty risk. The data was already in the company’s M365 tenant (or would be, in spreadsheets and emails). VariScout structures it in a purpose-built format within the same tenant boundary.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"64-shop-floor-reality\">6.4 Shop Floor Reality\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#64-shop-floor-reality\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6.4 Shop Floor Reality”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Concern\u003C/th>\u003Cth>How VariScout Addresses It\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Shared/BYOD devices on the shop floor\u003C/td>\u003Ctd>Entra ID authentication on every session. No persistent local credentials. Conditional Access can restrict to managed devices.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Poor factory WiFi\u003C/td>\u003Ctd>Offline-first: IndexedDB saves locally, syncs when connected. Sync queue with exponential backoff.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Teams mobile sidebar\u003C/td>\u003Ctd>One-tap access from Teams app. Teams SDK \u003Ccode dir=\"auto\">media.selectMedia()\u003C/code> for native camera experience; \u003Ccode dir=\"auto\">devicePermissions: [\"media\"]\u003C/code> in manifest gives IT admins audit trail. HTML5 file input fallback outside Teams.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multiple operators using one terminal\u003C/td>\u003Ctd>Each operator signs in with their own Entra ID. Author field on findings provides clear attribution.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Language\u003C/td>\u003Ctd>App UI in English. Quality terminology (Cpk, SPC) is international. Privacy notice should be in Finnish (GDPR good practice).\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"65-trust-decision\">6.5 Trust Decision\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#65-trust-decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6.5 Trust Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>What makes them say YES:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Data stays in their own Azure tenant — verifiable by IT admin\u003C/li>\n\u003Cli>Microsoft billing (shows up on existing Azure invoice, procurement-friendly)\u003C/li>\n\u003Cli>Standard Entra ID authentication — no new identity system\u003C/li>\n\u003Cli>Clear admin consent guide in Finnish\u003C/li>\n\u003Cli>Free PWA trial first — they’ve already used the methodology\u003C/li>\n\u003Cli>Publisher has zero access — immutable setting, verifiable in Azure portal\u003C/li>\n\u003Cli>Conditional Access and DLP policies apply normally\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>What makes them say NO:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Unclear permission justification (why does a chart tool need \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>?)\u003C/li>\n\u003Cli>No incident response contact or process\u003C/li>\n\u003Cli>No Finnish-language privacy notice\u003C/li>\n\u003Cli>No evaluation/trial period for the paid plan\u003C/li>\n\u003Cli>Unknown publisher (RDMAIC Oy) with no track record\u003C/li>\n\u003Cli>No reference customers in Finnish manufacturing\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Recommendation\u003C/strong>: Address the “NO” factors before launching the Team plan. A 30-day free trial in Azure Marketplace removes the biggest purchase friction for new customers.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"66-finnisheu-regulatory-context\">6.6 Finnish/EU Regulatory Context\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#66-finnisheu-regulatory-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6.6 Finnish/EU Regulatory Context”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Regulation\u003C/th>\u003Cth>Applicability\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>GDPR\u003C/strong>\u003C/td>\u003Ctd>VariScout is NOT a data processor (Art. 28). It is software deployed to the customer’s own tenant. The customer is the data controller; VariScout is a software tool, not a service that processes personal data on behalf of the customer.\u003C/td>\u003Ctd>A DPA template reduces procurement friction even though it’s technically unnecessary.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>NIS2\u003C/strong>\u003C/td>\u003Ctd>Likely N/A for a €5M, 200-person manufacturer unless they’re in a critical sector (energy, transport, health, water, digital infrastructure, food).\u003C/td>\u003Ctd>If the customer is in scope, VariScout’s architecture (no backend, customer-controlled) minimizes supply chain risk concerns.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>EU AI Act\u003C/strong>\u003C/td>\u003Ctd>N/A — VariScout performs statistical calculations, not AI inference. No machine learning models, no automated decision-making.\u003C/td>\u003Ctd>Clear differentiation if asked.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>21 CFR Part 11\u003C/strong>\u003C/td>\u003Ctd>If the customer is in pharma/medical devices: author field + timestamp + photo immutability provides a foundation for electronic records compliance. Not a formal Part 11 validation — customer would need to validate in their own quality system.\u003C/td>\u003Ctd>Consider a compliance alignment statement for regulated industries.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"7-consolidated-risk-matrix\">7. Consolidated Risk Matrix\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#7-consolidated-risk-matrix\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “7. Consolidated Risk Matrix”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Area\u003C/th>\u003Cth>Microsoft\u003C/th>\u003Cth>Enterprise IT\u003C/th>\u003Cth>Finnish Mfr\u003C/th>\u003Cth>Severity\u003C/th>\u003Cth>Mitigation\u003C/th>\u003Cth>Timeline\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Missing CSP header\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Add \u003Ccode dir=\"auto\">Content-Security-Policy\u003C/code> to \u003Ccode dir=\"auto\">server.js\u003C/code> responses. Allow \u003Ccode dir=\"auto\">self\u003C/code>, Graph API, and blob: for chart exports.\u003C/td>\u003Ctd>Before submission\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Missing security headers\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Add \u003Ccode dir=\"auto\">Strict-Transport-Security\u003C/code>, \u003Ccode dir=\"auto\">X-Frame-Options: DENY\u003C/code>, \u003Ccode dir=\"auto\">X-Content-Type-Options: nosniff\u003C/code>, \u003Ccode dir=\"auto\">Referrer-Policy: strict-origin-when-cross-origin\u003C/code> to \u003Ccode dir=\"auto\">server.js\u003C/code>.\u003C/td>\u003Ctd>Before submission\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> scope\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Document justification (channel SharePoint requires \u003Ccode dir=\"auto\">.All\u003C/code>). Create admin consent guide with consent screen screenshot. Explain delegated vs application.\u003C/td>\u003Ctd>Before Team plan\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>IndexedDB unencrypted\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Standard for web apps. Browser manages storage isolation. Document in security FAQ.\u003C/td>\u003Ctd>Ongoing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>No Key Vault for client secret\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>App setting is encrypted at rest by App Service platform. Key Vault is a best practice but not required. Document as optional hardening step for security-conscious customers.\u003C/td>\u003Ctd>Ongoing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>EXIF/GPS stripping\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Done. Two-layer approach: canvas re-encode + byte-level \u003Ccode dir=\"auto\">stripExifFromBlob\u003C/code> that parses JPEG binary and removes all APP1 markers. 23 unit tests verify GPS, camera model, and orientation are stripped.\u003C/td>\u003Ctd>Done\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>OBO Azure Function\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>~50 lines, stateless, single-purpose. Standard Microsoft pattern. Include in ARM template. Ensure function has no storage bindings, no persistent state.\u003C/td>\u003Ctd>Before Team plan\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>No incident response process\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>RED\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Create SECURITY.md with disclosure policy. Establish \u003Ca href=\"mailto:security@variscout.com\">security@variscout.com\u003C/a>. Define response timeline (acknowledge <48h, triage <7 days).\u003C/td>\u003Ctd>Before submission\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>No SBOM\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Generate CycloneDX SBOM in CI pipeline. Include in release artifacts.\u003C/td>\u003Ctd>Before submission\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>No \u003Ccode dir=\"auto\">pnpm audit\u003C/code> in CI\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Add \u003Ccode dir=\"auto\">pnpm audit --audit-level=high\u003C/code> to deploy workflow. Fail the build on high/critical vulnerabilities.\u003C/td>\u003Ctd>Before submission\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>No admin consent documentation\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>RED\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Create one-page admin guide with consent screen screenshot. Translate to Finnish. Include in onboarding materials.\u003C/td>\u003Ctd>Before Team plan\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>Conflict resolution (concurrent edits)\u003C/td>\u003Ctd>GREEN\u003C/td>\u003Ctd>LOW\u003C/td>\u003Ctd>AMBER\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Optimistic merge for additive operations. Unresolvable conflicts create copies (zero data loss). Document behavior in user guide.\u003C/td>\u003Ctd>Before Team plan\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"8-pre-submission-hardening-checklist\">8. Pre-Submission Hardening Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#8-pre-submission-hardening-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “8. Pre-Submission Hardening Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tier-1-before-marketplace-submission-standard-plan\">Tier 1: Before Marketplace Submission (Standard Plan)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tier-1-before-marketplace-submission-standard-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier 1: Before Marketplace Submission (Standard Plan)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These items should be completed before submitting the Standard plan to Azure Marketplace:\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Security headers in \u003Ccode dir=\"auto\">server.js\u003C/code>\u003C/strong> — Add CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>SECURITY.md\u003C/strong> — Vulnerability disclosure policy with security@ contact and response timeline\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>\u003Ccode dir=\"auto\">pnpm audit\u003C/code> in CI\u003C/strong> — Add to \u003Ccode dir=\"auto\">.github/workflows/deploy-azure-staging.yml\u003C/code>, fail on high/critical\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>\u003Ca href=\"mailto:security@variscout.com\">security@variscout.com\u003C/a>\u003C/strong> — Establish email address and forwarding\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Dependency review\u003C/strong> — Run \u003Ccode dir=\"auto\">pnpm audit\u003C/code>, resolve any high/critical findings\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>No console errors in production build\u003C/strong> — Verify browser console is clean (submission-checklist.md item)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>CSP headers verified\u003C/strong> — Confirm SPA + Graph API calls work with CSP policy (submission-checklist.md item)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tier-2-before-team-plan-launch\">Tier 2: Before Team Plan Launch\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tier-2-before-team-plan-launch\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier 2: Before Team Plan Launch”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These items are required for the Teams-integrated Team plan:\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Admin consent guide\u003C/strong> — One-page document explaining each permission scope in plain language. Finnish + English.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Publisher Verification\u003C/strong> — Complete Entra ID verification for RDMAIC Oy via Partner Center (~2 weeks)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>DPA template\u003C/strong> — Draft Data Processing Agreement template even though technically unnecessary (reduces procurement friction)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Finnish privacy notice\u003C/strong> — Translate privacy policy to Finnish (GDPR good practice)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> \u003Cstrong>EXIF stripping implementation\u003C/strong> — Two-layer: canvas re-encode + byte-level \u003Ccode dir=\"auto\">stripExifFromBlob\u003C/code> (APP1 marker removal). 23 unit tests verify GPS, camera model, and orientation stripped.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Photo immutability enforcement\u003C/strong> — Verify no update/delete paths for uploaded photos in storage layer\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>OBO function security review\u003C/strong> — Verify stateless, no storage bindings, minimal permissions\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Conflict resolution testing\u003C/strong> — Test concurrent edit scenarios, verify conflict copy creation\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>SBOM generation\u003C/strong> — CycloneDX SBOM in CI, included in release artifacts\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Publisher Attestation\u003C/strong> — Complete self-reported security practices for Teams App Store\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tier-3-ongoing\">Tier 3: Ongoing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tier-3-ongoing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier 3: Ongoing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Monthly dependency audit\u003C/strong> — \u003Ccode dir=\"auto\">pnpm audit\u003C/code> on a schedule, triage and patch\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Annual security review\u003C/strong> — Re-evaluate this document against current codebase and threat landscape\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Permission scope review\u003C/strong> — Verify no scope creep in ARM template or EasyAuth configuration\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Customer feedback loop\u003C/strong> — Track security-related questions from buyers, update FAQ and admin guide\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"appendices\">Appendices\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#appendices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Appendices”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"a-permission-scope-reference\">A. Permission Scope Reference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#a-permission-scope-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “A. Permission Scope Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Complete Graph API permissions used by VariScout, current and proposed:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Scope\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Consent\u003C/th>\u003Cth>Plan\u003C/th>\u003Cth>Justification\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">openid\u003C/code>\u003C/td>\u003Ctd>OpenID Connect\u003C/td>\u003Ctd>User\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Standard OIDC — authentication\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">profile\u003C/code>\u003C/td>\u003Ctd>OpenID Connect\u003C/td>\u003Ctd>User\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Display name for author field\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">email\u003C/code>\u003C/td>\u003Ctd>OpenID Connect\u003C/td>\u003Ctd>User\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>User identification\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">User.Read\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>User\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Read signed-in user’s profile\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>User\u003C/td>\u003Ctd>Team\u003C/td>\u003Ctd>Read/write to user’s personal OneDrive (\u003Ccode dir=\"auto\">/me/drive/\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>\u003Cstrong>Admin\u003C/strong>\u003C/td>\u003Ctd>Team\u003C/td>\u003Ctd>Read/write to channel SharePoint document libraries. Required because \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> only covers personal OneDrive.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>\u003Cstrong>Admin\u003C/strong>\u003C/td>\u003Ctd>Team\u003C/td>\u003Ctd>List channels the user belongs to (for storage location picker). Does NOT read channel messages.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Not requested (and why):\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Scope\u003C/th>\u003Cth>Why Not\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Sites.ReadWrite.All\u003C/code>\u003C/td>\u003Ctd>Broader than needed. \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> with delegated consent is sufficient for channel file access.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> (Application)\u003C/td>\u003Ctd>Application permissions bypass user context. VariScout is an interactive tool — always has a signed-in user.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChannelMessage.Read.All\u003C/code>\u003C/td>\u003Ctd>VariScout does not read Teams messages. It only stores files in channel document libraries.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Mail.Read\u003C/code> / \u003Ccode dir=\"auto\">Mail.Send\u003C/code>\u003C/td>\u003Ctd>No email functionality.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"b-data-flow-diagrams\">B. Data Flow Diagrams\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#b-data-flow-diagrams\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “B. Data Flow Diagrams”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"standard-plan-browser-mode\">Standard Plan (Browser Mode)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#standard-plan-browser-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Plan (Browser Mode)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Customer's Browser │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ VariScout SPA │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ Analysis │ │ Charts │ │ Findings│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ Engine │ │ (Visx) │ │ Log │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └────┬─────┘ └──────────┘ └─────────┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ┌────▼─────────────────────────────────┐ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ IndexedDB (Dexie) │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ Local .vrs project storage │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └────┬─────────────────────────────────┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────┼────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Graph API (Files.ReadWrite) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▼ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌───────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Customer's OneDrive │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ /VariScout/Projects/*.vrs │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▲ EasyAuth (User.Read)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌──────┴──────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Azure AD │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (Customer's │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Entra ID) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────┐│ Customer's Browser ││ ┌────────────────────────────────────────────┐ ││ │ VariScout SPA │ ││ │ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ ││ │ │ Analysis │ │ Charts │ │ Findings│ │ ││ │ │ Engine │ │ (Visx) │ │ Log │ │ ││ │ └────┬─────┘ └──────────┘ └─────────┘ │ ││ │ │ │ ││ │ ┌────▼─────────────────────────────────┐ │ ││ │ │ IndexedDB (Dexie) │ │ ││ │ │ Local .vrs project storage │ │ ││ │ └────┬─────────────────────────────────┘ │ ││ └───────┼────────────────────────────────────┘ ││ │ Graph API (Files.ReadWrite) ││ ▼ ││ ┌───────────────────────────────────┐ ││ │ Customer's OneDrive │ ││ │ /VariScout/Projects/*.vrs │ ││ └───────────────────────────────────┘ │└─────────────────────────────────────────────────────────┘ ▲ EasyAuth (User.Read) │┌──────┴──────────┐│ Azure AD ││ (Customer's ││ Entra ID) │└─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"team-plan-teams-mode\">Team Plan (Teams Mode)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#team-plan-teams-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Team Plan (Teams Mode)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌──────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Teams WebView / Mobile │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ VariScout SPA + @microsoft/teams-js │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ Analysis │ │ Field │ │ Photo │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ Engine │ │ View │ │ Capture │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └────┬─────┘ └──────────┘ └──────┬───────┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ ┌─────────────────────────┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ EXIF strip (canvas + byte-level) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ┌────▼────▼────────────────────────────────┐ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ IndexedDB (offline queue) │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └────┬─────────────────────────────────────┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────┼────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Graph API (Files.ReadWrite.All) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▼ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌──────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Customer's SharePoint / OneDrive │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Channel Files/VariScout/Projects/*.vrs │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Channel Files/VariScout/Photos/**/*.jpg │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └──────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▲ Teams SSO → OBO (Azure Function)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌──────┴──────────┐ ┌──────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Azure AD │ │ Azure Function │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (Customer's │◄────│ OBO token exchange │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Entra ID) │ │ (~50 lines, │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────┘ │ stateless) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌──────────────────────────────────────────────────────────────┐│ Teams WebView / Mobile ││ ┌────────────────────────────────────────────────┐ ││ │ VariScout SPA + @microsoft/teams-js │ ││ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ ││ │ │ Analysis │ │ Field │ │ Photo │ │ ││ │ │ Engine │ │ View │ │ Capture │ │ ││ │ └────┬─────┘ └──────────┘ └──────┬───────┘ │ ││ │ │ │ │ ││ │ │ ┌─────────────────────────┘ │ ││ │ │ │ EXIF strip (canvas + byte-level) │ ││ │ ┌────▼────▼────────────────────────────────┐ │ ││ │ │ IndexedDB (offline queue) │ │ ││ │ └────┬─────────────────────────────────────┘ │ ││ └───────┼────────────────────────────────────────┘ ││ │ Graph API (Files.ReadWrite.All) ││ ▼ ││ ┌──────────────────────────────────────────┐ ││ │ Customer's SharePoint / OneDrive │ ││ │ Channel Files/VariScout/Projects/*.vrs │ ││ │ Channel Files/VariScout/Photos/**/*.jpg │ ││ └──────────────────────────────────────────┘ │└──────────────────────────────────────────────────────────────┘ ▲ Teams SSO → OBO (Azure Function) │┌──────┴──────────┐ ┌──────────────────────┐│ Azure AD │ │ Azure Function ││ (Customer's │◄────│ OBO token exchange ││ Entra ID) │ │ (~50 lines, │└─────────────────┘ │ stateless) │ └──────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"photo-capture-flow\">Photo Capture Flow\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#photo-capture-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Photo Capture Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Teams SDK media.selectMedia() ─┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├──► processPhoto()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">HTML5 file input (fallback) ───┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Canvas re-encode + stripExifFromBlob ──── EXIF/GPS stripped (two layers)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Base64 thumbnail (~50KB) → embedded in .vrs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Full-res JPEG → PUT to SharePoint\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Channel Files/VariScout/Photos/{analysisId}/{findingId}/photo-001.jpg\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Immutable (no update/delete API calls)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Teams SDK media.selectMedia() ─┐ ├──► processPhoto()HTML5 file input (fallback) ───┘ │ ▼Canvas re-encode + stripExifFromBlob ──── EXIF/GPS stripped (two layers) │ ├── Base64 thumbnail (~50KB) → embedded in .vrs │ └── Full-res JPEG → PUT to SharePoint Channel Files/VariScout/Photos/{analysisId}/{findingId}/photo-001.jpg │ └── Immutable (no update/delete API calls)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"c-gdpr-quick-reference\">C. GDPR Quick Reference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#c-gdpr-quick-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “C. GDPR Quick Reference”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>GDPR Article\u003C/th>\u003Cth>VariScout Response\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Art. 5 (Principles)\u003C/td>\u003Ctd>Data minimization: only quality data the user explicitly inputs. Purpose limitation: statistical analysis only.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Art. 6 (Lawful basis)\u003C/td>\u003Ctd>Customer determines lawful basis. VariScout is a tool, not a controller or processor.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Art. 12–14 (Transparency)\u003C/td>\u003Ctd>Privacy policy at variscout.com/legal/privacy describes the software’s data handling.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Art. 17 (Right to erasure)\u003C/td>\u003Ctd>Customer controls all data in their own tenant. Delete from OneDrive/SharePoint/IndexedDB at any time. Publisher has no access.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Art. 25 (Privacy by design)\u003C/td>\u003Ctd>No telemetry, no tracking, offline-first, data in customer’s tenant, publisher zero access.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Art. 28 (Processor)\u003C/td>\u003Ctd>NOT applicable. VariScout is deployed to the customer’s own infrastructure. No data processing on behalf of the customer.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Art. 32 (Security)\u003C/td>\u003Ctd>TLS 1.2+, HTTPS-only, EasyAuth (platform-managed), Entra ID authentication.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Art. 33–34 (Breach notification)\u003C/td>\u003Ctd>Publisher has no access to customer data, so cannot experience a data breach involving customer data. Customer’s own Azure tenant security applies.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Art. 44–49 (International transfers)\u003C/td>\u003Ctd>No transfers. Data stays in the customer’s Azure region. Publisher has zero access.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"adr-016-teams-integration.md\">ADR-016: Teams Integration\u003C/a> — the technical design being evaluated\u003C/li>\n\u003Cli>\u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007: Azure Marketplace Distribution\u003C/a> — two-plan model (Standard + Team)\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/azure/certification-guide.md\">Certification Guide\u003C/a> — marketplace certification mechanics\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/azure/submission-checklist.md\">Submission Checklist\u003C/a> — submission readiness tracker\u003C/li>\n\u003Cli>\u003Ca href=\"../08-products/azure/authentication.md\">Authentication\u003C/a> — EasyAuth setup details\u003C/li>\n\u003C/ul>", + { + "headings": 2759, + "localImagePaths": 2883, + "remoteImagePaths": 2884, + "frontmatter": 2885, + "imagePaths": 2886 + }, + [ + 2760, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786, 2789, 2792, 2795, 2798, 2801, 2804, + 2807, 2810, 2813, 2816, 2819, 2822, 2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, + 2855, 2858, 2861, 2864, 2867, 2870, 2873, 2876, 2879, 2882 + ], + { "depth": 30, "slug": 2761, "text": 2749 }, + "adr-016-security-evaluation-teams-integration", + { "depth": 33, "slug": 2763, "text": 2764 }, + "1-executive-summary", + "1. Executive Summary", + { "depth": 79, "slug": 2766, "text": 2767 }, + "key-security-claims", + "Key Security Claims", + { "depth": 79, "slug": 2769, "text": 2770 }, + "verdict-by-perspective", + "Verdict by Perspective", + { "depth": 33, "slug": 2772, "text": 2773 }, + "2-security-baseline-pre-teams", + "2. Security Baseline (Pre-Teams)", + { "depth": 79, "slug": 2775, "text": 2776 }, + "known-gaps", + "Known Gaps", + { "depth": 33, "slug": 2778, "text": 2779 }, + "3-teams-integration-security-delta", + "3. Teams Integration Security Delta", + { "depth": 79, "slug": 2781, "text": 2782 }, + "new-permission-scopes", + "New Permission Scopes", + { "depth": 79, "slug": 2784, "text": 2785 }, + "new-runtime-dependency", + "New Runtime Dependency", + { "depth": 79, "slug": 2787, "text": 2788 }, + "new-infrastructure-phase-6", + "New Infrastructure (Phase 6)", + { "depth": 79, "slug": 2790, "text": 2791 }, + "new-data-flows", + "New Data Flows", + { "depth": 79, "slug": 2793, "text": 2794 }, + "new-client-side-processing", + "New Client-Side Processing", + { "depth": 79, "slug": 2796, "text": 2797 }, + "strongest-security-property", + "Strongest Security Property", + { "depth": 33, "slug": 2799, "text": 2800 }, + "4-perspective-microsoft", + "4. Perspective: Microsoft", + { "depth": 79, "slug": 2802, "text": 2803 }, + "41-marketplace-certification-impact", + "4.1 Marketplace Certification Impact", + { "depth": 79, "slug": 2805, "text": 2806 }, + "42-teams-app-store-if-submitted", + "4.2 Teams App Store (If Submitted)", + { "depth": 79, "slug": 2808, "text": 2809 }, + "43-graph-api-permission-review", + "4.3 Graph API Permission Review", + { "depth": 79, "slug": 2811, "text": 2812 }, + "44-microsoft-security-baseline-assessment", + "4.4 Microsoft Security Baseline Assessment", + { "depth": 33, "slug": 2814, "text": 2815 }, + "5-perspective-enterprise-it--procurement", + "5. Perspective: Enterprise IT & Procurement", + { "depth": 79, "slug": 2817, "text": 2818 }, + "51-security-questionnaire-answers", + "5.1 Security Questionnaire Answers", + { "depth": 79, "slug": 2820, "text": 2821 }, + "52-compliance-posture", + "5.2 Compliance Posture", + { "depth": 79, "slug": 2823, "text": 2824 }, + "53-supply-chain--incident-response", + "5.3 Supply Chain & Incident Response", + { "depth": 33, "slug": 2826, "text": 2827 }, + "6-perspective-finnish-manufacturer", + "6. Perspective: Finnish Manufacturer", + { "depth": 79, "slug": 2829, "text": 2830 }, + "61-who-is-this-buyer", + "6.1 Who Is This Buyer?", + { "depth": 79, "slug": 2832, "text": 2833 }, + "62-the-admin-consent-conversation", + "6.2 The Admin Consent Conversation", + { "depth": 79, "slug": 2835, "text": 2836 }, + "63-data-sensitivity", + "6.3 Data Sensitivity", + { "depth": 79, "slug": 2838, "text": 2839 }, + "64-shop-floor-reality", + "6.4 Shop Floor Reality", + { "depth": 79, "slug": 2841, "text": 2842 }, + "65-trust-decision", + "6.5 Trust Decision", + { "depth": 79, "slug": 2844, "text": 2845 }, + "66-finnisheu-regulatory-context", + "6.6 Finnish/EU Regulatory Context", + { "depth": 33, "slug": 2847, "text": 2848 }, + "7-consolidated-risk-matrix", + "7. Consolidated Risk Matrix", + { "depth": 33, "slug": 2850, "text": 2851 }, + "8-pre-submission-hardening-checklist", + "8. Pre-Submission Hardening Checklist", + { "depth": 79, "slug": 2853, "text": 2854 }, + "tier-1-before-marketplace-submission-standard-plan", + "Tier 1: Before Marketplace Submission (Standard Plan)", + { "depth": 79, "slug": 2856, "text": 2857 }, + "tier-2-before-team-plan-launch", + "Tier 2: Before Team Plan Launch", + { "depth": 79, "slug": 2859, "text": 2860 }, + "tier-3-ongoing", + "Tier 3: Ongoing", + { "depth": 33, "slug": 2862, "text": 2863 }, + "appendices", + "Appendices", + { "depth": 79, "slug": 2865, "text": 2866 }, + "a-permission-scope-reference", + "A. Permission Scope Reference", + { "depth": 79, "slug": 2868, "text": 2869 }, + "b-data-flow-diagrams", + "B. Data Flow Diagrams", + { "depth": 621, "slug": 2871, "text": 2872 }, + "standard-plan-browser-mode", + "Standard Plan (Browser Mode)", + { "depth": 621, "slug": 2874, "text": 2875 }, + "team-plan-teams-mode", + "Team Plan (Teams Mode)", + { "depth": 621, "slug": 2877, "text": 2878 }, + "photo-capture-flow", + "Photo Capture Flow", + { "depth": 79, "slug": 2880, "text": 2881 }, + "c-gdpr-quick-reference", + "C. GDPR Quick Reference", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2749 }, + [], + "07-decisions/adr-016-teams-integration", + { "id": 2887, "data": 2889, "body": 2894, "filePath": 2895, "digest": 2896, "rendered": 2897 }, + { + "title": 2890, + "editUrl": 16, + "head": 2891, + "template": 18, + "sidebar": 2892, + "pagefind": 16, + "draft": 20 + }, + "ADR-016: Microsoft Teams Integration", + [], + { "hidden": 20, "attrs": 2893 }, + {}, + "# ADR-016: Microsoft Teams Integration\n\n**Status**: Accepted\n\n**Date**: 2026-02-27\n\n**Related**: ADR-007 (marketplace distribution), ADR-015 (investigation board)\n\n---\n\n## Context\n\nVariScout is a Managed Application deployed to the customer's Azure tenant. Quality teams need mobile access for gemba investigations — photo evidence, chart sharing, commenting on findings. Microsoft Teams is the natural collaboration layer for M365 organizations.\n\nDesktop-only tools (Minitab, JMP) cannot offer mobile collaboration. Teams is where M365 orgs already collaborate, and VariScout's web app naturally works in Teams WebView. The Managed Application model preserves data sovereignty — all data stays in the customer's tenant.\n\nThe current findings system (ADR-015) is text-only with no photos and no author tracking. Field engineers investigating variation on the shop floor need to capture visual evidence and share it with the team — but switching between a camera app, a file share, and the analysis tool breaks the investigation flow.\n\nWithout Teams integration:\n\n- Engineers use separate apps for photos, notes, and analysis — context is fragmented\n- Sharing a finding requires screenshots + manual copy-paste into Teams chat\n- Mobile access means opening the browser, navigating to the URL, and losing the Teams collaboration context\n- No author tracking on findings or comments — unclear who observed what\n\n---\n\n## Decision\n\n**Adopt Microsoft Teams SDK with a progressive enhancement model.**\n\nThe same codebase detects its runtime context and adapts behavior accordingly:\n\n```\nTeams SDK initialized?\n├── Yes → Channel tab? → shared channel SharePoint storage\n│ → Personal tab? → personal OneDrive\n└── No → Browser mode → local files (File System Access API)\n```\n\n### Two Deployment Profiles\n\n| Capability | Standard (Browser) | Team (Teams-Integrated) |\n| ------------- | ------------------------------------ | --------------------------------------------------------------------- |\n| Auth | EasyAuth redirect | Teams SSO (On-Behalf-Of) |\n| Storage | Local files (File System Access API) | + OneDrive personal + Channel SharePoint |\n| Sharing | Copy URL | URL sharing (Teams native dialog) + deep links |\n| Mobile | Mobile browser | Teams mobile (sidebar icon) |\n| Photos | N/A | Camera capture + channel storage |\n| Permissions | `User.Read` only | + `Files.ReadWrite` + `Files.ReadWrite.All` + `Channel.ReadBasic.All` |\n| Admin consent | None | Required (one-time, tenant-wide) |\n\n### Admin Consent Model\n\n`Files.ReadWrite.All` is a delegated permission requiring one-time, tenant-wide admin approval. It does NOT grant new file access — it allows the app to access files the signed-in user already has access to. Per-channel scoping is enforced by Teams membership (natural access control).\n\n> Note: Microsoft Graph does not offer a \"write without delete\" scope. `Files.ReadWrite.All` includes delete capability, but VariScout never exercises it — the app's storage model is strictly additive (see Security Considerations).\n\nIT admin flow: Azure AD → Enterprise Apps → VariScout → Grant admin consent.\n\nConditional Access recommendations for IT admins:\n\n- Require managed devices for channel file access (BYOD policy)\n- Enforce MFA for VariScout app registration\n- Restrict to specific security groups if needed\n\n### Data Model Extensions\n\n`FindingComment` in `packages/core/src/findings.ts` gains optional fields:\n\n```typescript\n// FindingComment additions\nauthor?: string; // EasyAuth/Teams user display name\nphotos?: PhotoAttachment[]; // Attached evidence\n\n// New type\ninterface PhotoAttachment {\n id: string;\n filename: string;\n driveItemId?: string; // SharePoint/OneDrive item ID\n thumbnailDataUrl?: string; // ~50KB base64 embedded for cross-user visibility\n uploadStatus: 'pending' | 'uploaded' | 'failed';\n capturedAt: number;\n}\n```\n\nThe `author` field enables audit trails. The `thumbnailDataUrl` is embedded in the `.vrs` file so other team members see photo previews without needing to fetch from SharePoint — full-resolution images are fetched on demand.\n\n### Channel File Storage Layout\n\n```\nChannel Files/VariScout/\n ├── Projects/\n │ └── Feb-Fill-Line.vrs ← shared analysis (JSON)\n └── Photos/\n └── {analysisId}/{findingId}/\n ├── photo-001.jpg ← full-res (Engineer A)\n └── photo-002.jpg ← full-res (Engineer B)\n```\n\nProjects are stored as `.vrs` files (JSON) in the channel's SharePoint document library. Photos are stored alongside in a structured folder hierarchy. This keeps all data within the channel's existing access control.\n\n### Concurrent Access Strategy\n\nOptimistic merge for additive operations:\n\n- New finding, new comment, status change, photo upload — all merge cleanly\n- Before saving: fetch latest version, compare with local base, auto-merge non-conflicting changes\n- Conflict detection via `eTag` / `lastModifiedDateTime` (already used in `storage.ts`)\n\nUnresolvable conflicts (both users edited the same finding text simultaneously):\n\n- Save as `\"{name} (conflict copy).vrs\"` alongside the original\n- Zero data loss guarantee — worst case is a duplicate file the team resolves manually\n- Notification toast: \"Another team member modified this project. A conflict copy was saved.\"\n\n### Mobile Layout\n\nThe Azure app uses a responsive phone layout (\u003C 640px) within the existing Editor — not a separate route:\n\n- `MobileChartCarousel` — swipeable carousel (4 views: I-Chart, Boxplot, Pareto, Stats) replacing `DashboardGrid` on phones\n- Findings panel renders as full-screen overlay on phone, inline sidebar on desktop\n- Phone toolbar: Back + project name (truncated) + Save + overflow menu (`EllipsisVertical`)\n- Touch-optimized: 44px minimum touch targets, safe area insets for notched phones\n- Comment thread with photo capture — Teams SDK `media.selectMedia()` inside Teams (native camera experience), HTML5 file input fallback outside Teams\n- Annotations disabled on phone (no right-click context menu on touch devices)\n\nReuses PWA responsive patterns adapted for Teams mobile WebView. Desktop layout is completely unchanged (all gated by `useIsMobile(640)`).\n\n### Sharing (Implemented) and Adaptive Cards (Planned)\n\n**Implemented**: URL sharing via Teams native dialog (`sharing.shareWebContent`) and deep links (`pages.shareDeepLink`). Share payloads built by `shareContent.ts` for findings and charts.\n\n**Planned (Adaptive Cards)**: Rich sharing into Teams conversations:\n\n- Finding summary card: status badge, Cpk value, filter context, photo thumbnail\n- Deep link buttons: \"View Chart\", \"Open Finding\" → navigate directly into the app\n- Compose extension in Teams manifest for sharing from the message compose box\n\n**Channel @mention**: See [ADR-018](adr-018-channel-mention-workflow.md) for the channel\nmention workflow that extends URL sharing with true @mention notifications in channel tabs.\n\n### On-Behalf-Of SSO Flow\n\nAn Azure Function (~50 lines) exchanges the Teams SSO token for a Graph API access token:\n\n- Deployed via ARM template alongside the App Service\n- Scopes: `User.Read` + `Files.ReadWrite.All`\n- Fallback: EasyAuth redirect if OBO exchange fails\n- Minimal attack surface — single-purpose token exchange, no stored state\n\n### Security Considerations\n\n- **EXIF/GPS stripping**: Two-layer metadata removal before upload. First, canvas re-encode strips most EXIF data as a side effect. Second, explicit byte-level `stripExifFromBlob` parses the JPEG binary and removes all EXIF/GPS APP1 markers, guaranteeing no location or device metadata survives. Both layers run client-side. Unit tests (23 cases) verify GPS coordinates, camera model, and orientation are stripped from real-world JPEG samples.\n- **Tighter personal storage**: `Files.ReadWrite.AppFolder` for personal OneDrive (narrower than `Files.ReadWrite`). Channel storage requires `Files.ReadWrite.All`.\n- **Photo immutability**: Photos are immutable once uploaded — no edit or delete of photo files. Prevents evidence tampering in quality investigations.\n- **No-delete principle**: `Files.ReadWrite.All` technically includes delete capability, but VariScout never calls Graph API delete endpoints. The storage model is strictly additive — `.vrs` projects are created/updated (conflicts save as copies), photos are immutable once uploaded. IT admins can audit this: the app contains no `DELETE /drive/items/{id}` calls.\n- **Audit trail**: Author + timestamp on all findings and comments. Combined with photo immutability, creates a reliable investigation record.\n- **`devicePermissions: [\"media\"]`**: Declaring camera access in the Teams manifest makes usage auditable in the Teams Admin Center. IT admins can see which apps request device access during the app permission review. The HTML5 `capture` attribute, by contrast, works silently with no admin visibility.\n- **Font self-hosting**: Recommend self-hosting Google Fonts for strict CSP environments (no external CDN calls).\n\n### IT Compliance Hardening (February 2026)\n\nFour gaps identified during Microsoft best practices audit and fixed:\n\n1. **Reactive Teams theme sync** — `useTeamsContext` hook now re-renders on Teams theme changes via a subscriber pattern. Teams theme (default/dark/contrast) is mapped into `ThemeContext` on initial load and on every change. High-contrast mode maps to `light` (closest safe match).\n\n2. **Dynamic CSP `connect-src`** — `server.js` reads the `FUNCTION_URL` environment variable at startup and includes its origin in the Content Security Policy `connect-src` directive. Without this, OBO token exchange to a separate Azure Function origin was silently blocked by CSP.\n\n3. **`app.notifyFailure()` on crash** — The top-level `ErrorBoundary` in `App.tsx` calls `notifyTeamsFailure()` when a render error is caught. This tells the Teams host that the app has crashed, rather than leaving Teams in a \"healthy\" state while the user sees a fallback error screen.\n\n4. **`registerBeforeUnloadHandler` for data loss prevention** — During Teams SDK initialization, a lifecycle handler is registered. The Editor registers a callback that auto-saves the project (via `saveProject()`) if `hasUnsavedChanges` is true when the user navigates away from the tab.\n\n### Design Principles\n\n1. **Progressive enhancement, not hard dependency** — Teams SDK features enhance the experience but the app must always work without them. Every Teams API call has a non-Teams fallback. `isTeamsMediaAvailable()` / `isInTeams()` gate all SDK calls.\n\n2. **IT admin visibility over silent access** — Prefer Teams SDK APIs that declare permissions in the manifest (`devicePermissions`, Graph scopes) over HTML5 APIs that work silently. This gives tenant admins an audit trail and consent control.\n\n3. **No creative filters on quality evidence** — Photo capture disables Instagram-style filters (`enableFilter: false`), drawing tools (`ink: false`), and text overlays (`textSticker: false`). Quality evidence must be unaltered.\n\n4. **EXIF stripping is non-negotiable** — Every photo path (Teams SDK, HTML5 file input, gallery pick) feeds into the same `processPhoto()` → `stripExifFromBlob()` pipeline. No photo reaches OneDrive with GPS or device metadata.\n\n5. **Additive-only storage** — No delete calls to Graph API. Photos are immutable once uploaded. Conflicts create copies. This is auditable — the app contains no `DELETE /drive/items/{id}` calls.\n\n### Phased Delivery\n\n| Phase | Scope | Dependencies |\n| ----- | ---------------------------------------------------------------------------------- | ------------ |\n| 1 | Teams SDK foundation — detect context, manifest with personal + channel tabs | None |\n| 2 | Mobile layout — responsive phone carousel in Editor, touch navigation | Phase 1 |\n| 3 | Photo comments — data model, Teams SDK media API + HTML5 fallback, OneDrive upload | Phase 1 |\n| 4 | Channel file storage — shared `.vrs` + photos, optimistic merge | Phases 1 + 3 |\n| 5 | Deep links + URL sharing — Teams native dialog, chart/finding links | Phases 1 + 4 |\n| 6 | Azure Function for On-Behalf-Of — true silent SSO | Phase 1 |\n\nPhases 2 and 3 can proceed in parallel after Phase 1. Phase 6 can be done at any point after Phase 1 but is lowest priority (EasyAuth fallback works).\n\n---\n\n## Consequences\n\n### Easier\n\n- **Gemba investigations**: Engineers capture photo evidence directly in the analysis tool — no app switching\n- **Team collaboration**: Shared channel storage means the team works on the same analysis, not emailed copies\n- **Mobile access**: Teams sidebar icon puts VariScout one tap away on any phone\n- **Rich sharing**: Adaptive Cards in Teams chat replace screenshot-and-paste workflows\n- **Author tracking**: Clear audit trail of who observed what, with timestamps\n- **Competitive differentiation**: \"Take VariScout to the gemba\" — unique vs desktop-only tools\n\n### Harder\n\n- **New dependency**: `@microsoft/teams-js` (~40KB gzipped) added to the Azure app bundle\n- **New infrastructure**: Azure Function in ARM template (Phase 6) for OBO token exchange\n- **Storage complexity**: `storage.ts` evolves with channel drive branch + optimistic merge logic\n- **Auth complexity**: `easyAuth.ts` evolves with Teams SSO detection + OBO token exchange\n- **Admin consent**: Team plan requires IT admin approval for `Files.ReadWrite.All` — adds friction to onboarding\n- **Concurrent access**: Optimistic merge logic must handle edge cases gracefully (network failures, partial saves)\n- **More UI surface**: Mobile Field View, photo capture, Adaptive Card templates — additional components to maintain\n- **Testing**: Teams WebView testing requires Teams Developer Portal + sideloading; cannot test locally without Teams context mock\n\n---\n\n## Related Decisions\n\n- [ADR-007: Azure Marketplace Distribution](adr-007-azure-marketplace-distribution.md) — Two-plan model (Standard + Team)\n- [ADR-015: Investigation Board](adr-015-investigation-board.md) — Finding statuses, tags, and comments (extended here with author + photos)\n- [ADR-004: Offline-First](adr-004-offline-first.md) — Offline capability preserved; photo upload queued when offline\n\n---\n\n## See Also\n\n- [Teams SDK Documentation](https://learn.microsoft.com/en-us/microsoftteams/platform/)\n- [On-Behalf-Of Flow](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-on-behalf-of-flow)\n- [Adaptive Cards](https://adaptivecards.io/)\n- [Investigation Workflow](../03-features/workflows/investigation-to-action.md)\n\n---\n\n## Implementation History\n\nAll 6 increments implemented in February 2026:\n\n| Increment | Scope | Status |\n| --------- | --------------------------------------------------- | ----------- |\n| 1 | Teams SDK foundation — context detection, manifest | Implemented |\n| 2 | Mobile layout — responsive phone carousel | Implemented |\n| 3 | Photo comments — camera capture, EXIF strip, upload | Implemented |\n| 4 | Channel SharePoint storage — shared .vrs + photos | Implemented |\n| 5 | Deep links + URL sharing — Teams native dialog | Implemented |\n| 6 | OBO silent SSO — Azure Function token exchange | Implemented |\n\nAdaptive Cards remain planned for a future release.", + "src/content/docs/07-decisions/adr-016-teams-integration.md", + "1660005e01dfbc9b", + { "html": 2898, "metadata": 2899 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-016-microsoft-teams-integration\">ADR-016: Microsoft Teams Integration\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-016-microsoft-teams-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-016: Microsoft Teams Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Accepted\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2026-02-27\u003C/p>\n\u003Cp>\u003Cstrong>Related\u003C/strong>: ADR-007 (marketplace distribution), ADR-015 (investigation board)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is a Managed Application deployed to the customer’s Azure tenant. Quality teams need mobile access for gemba investigations — photo evidence, chart sharing, commenting on findings. Microsoft Teams is the natural collaboration layer for M365 organizations.\u003C/p>\n\u003Cp>Desktop-only tools (Minitab, JMP) cannot offer mobile collaboration. Teams is where M365 orgs already collaborate, and VariScout’s web app naturally works in Teams WebView. The Managed Application model preserves data sovereignty — all data stays in the customer’s tenant.\u003C/p>\n\u003Cp>The current findings system (ADR-015) is text-only with no photos and no author tracking. Field engineers investigating variation on the shop floor need to capture visual evidence and share it with the team — but switching between a camera app, a file share, and the analysis tool breaks the investigation flow.\u003C/p>\n\u003Cp>Without Teams integration:\u003C/p>\n\u003Cul>\n\u003Cli>Engineers use separate apps for photos, notes, and analysis — context is fragmented\u003C/li>\n\u003Cli>Sharing a finding requires screenshots + manual copy-paste into Teams chat\u003C/li>\n\u003Cli>Mobile access means opening the browser, navigating to the URL, and losing the Teams collaboration context\u003C/li>\n\u003Cli>No author tracking on findings or comments — unclear who observed what\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Adopt Microsoft Teams SDK with a progressive enhancement model.\u003C/strong>\u003C/p>\n\u003Cp>The same codebase detects its runtime context and adapts behavior accordingly:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Teams SDK initialized?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Yes → Channel tab? → shared channel SharePoint storage\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ → Personal tab? → personal OneDrive\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── No → Browser mode → local files (File System Access API)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Teams SDK initialized?├── Yes → Channel tab? → shared channel SharePoint storage│ → Personal tab? → personal OneDrive└── No → Browser mode → local files (File System Access API)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"two-deployment-profiles\">Two Deployment Profiles\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#two-deployment-profiles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two Deployment Profiles”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>Standard (Browser)\u003C/th>\u003Cth>Team (Teams-Integrated)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Auth\u003C/td>\u003Ctd>EasyAuth redirect\u003C/td>\u003Ctd>Teams SSO (On-Behalf-Of)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Storage\u003C/td>\u003Ctd>Local files (File System Access API)\u003C/td>\u003Ctd>+ OneDrive personal + Channel SharePoint\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sharing\u003C/td>\u003Ctd>Copy URL\u003C/td>\u003Ctd>URL sharing (Teams native dialog) + deep links\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mobile\u003C/td>\u003Ctd>Mobile browser\u003C/td>\u003Ctd>Teams mobile (sidebar icon)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Photos\u003C/td>\u003Ctd>N/A\u003C/td>\u003Ctd>Camera capture + channel storage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Permissions\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">User.Read\u003C/code> only\u003C/td>\u003Ctd>+ \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> + \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> + \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Admin consent\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>Required (one-time, tenant-wide)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"admin-consent-model\">Admin Consent Model\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#admin-consent-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Admin Consent Model”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> is a delegated permission requiring one-time, tenant-wide admin approval. It does NOT grant new file access — it allows the app to access files the signed-in user already has access to. Per-channel scoping is enforced by Teams membership (natural access control).\u003C/p>\n\u003Cblockquote>\n\u003Cp>Note: Microsoft Graph does not offer a “write without delete” scope. \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> includes delete capability, but VariScout never exercises it — the app’s storage model is strictly additive (see Security Considerations).\u003C/p>\n\u003C/blockquote>\n\u003Cp>IT admin flow: Azure AD → Enterprise Apps → VariScout → Grant admin consent.\u003C/p>\n\u003Cp>Conditional Access recommendations for IT admins:\u003C/p>\n\u003Cul>\n\u003Cli>Require managed devices for channel file access (BYOD policy)\u003C/li>\n\u003Cli>Enforce MFA for VariScout app registration\u003C/li>\n\u003Cli>Restrict to specific security groups if needed\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-model-extensions\">Data Model Extensions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-model-extensions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Model Extensions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">FindingComment\u003C/code> in \u003Ccode dir=\"auto\">packages/core/src/findings.ts\u003C/code> gains optional fields:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// FindingComment additions\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">author\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> string; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// EasyAuth/Teams user display name\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">photos\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PhotoAttachment[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Attached evidence\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// New type\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PhotoAttachment {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filename\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">driveItemId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// SharePoint/OneDrive item ID\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">thumbnailDataUrl\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ~50KB base64 embedded for cross-user visibility\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">uploadStatus\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pending\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">uploaded\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">failed\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">capturedAt\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// FindingComment additionsauthor?: string; // EasyAuth/Teams user display namephotos?: PhotoAttachment[]; // Attached evidence// New typeinterface PhotoAttachment { id: string; filename: string; driveItemId?: string; // SharePoint/OneDrive item ID thumbnailDataUrl?: string; // ~50KB base64 embedded for cross-user visibility uploadStatus: 'pending' | 'uploaded' | 'failed'; capturedAt: number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">author\u003C/code> field enables audit trails. The \u003Ccode dir=\"auto\">thumbnailDataUrl\u003C/code> is embedded in the \u003Ccode dir=\"auto\">.vrs\u003C/code> file so other team members see photo previews without needing to fetch from SharePoint — full-resolution images are fetched on demand.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"channel-file-storage-layout\">Channel File Storage Layout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#channel-file-storage-layout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Channel File Storage Layout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Channel Files/VariScout/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Projects/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Feb-Fill-Line.vrs ← shared analysis (JSON)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Photos/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── {analysisId}/{findingId}/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── photo-001.jpg ← full-res (Engineer A)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── photo-002.jpg ← full-res (Engineer B)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Channel Files/VariScout/ ├── Projects/ │ └── Feb-Fill-Line.vrs ← shared analysis (JSON) └── Photos/ └── {analysisId}/{findingId}/ ├── photo-001.jpg ← full-res (Engineer A) └── photo-002.jpg ← full-res (Engineer B)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Projects are stored as \u003Ccode dir=\"auto\">.vrs\u003C/code> files (JSON) in the channel’s SharePoint document library. Photos are stored alongside in a structured folder hierarchy. This keeps all data within the channel’s existing access control.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"concurrent-access-strategy\">Concurrent Access Strategy\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#concurrent-access-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Concurrent Access Strategy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Optimistic merge for additive operations:\u003C/p>\n\u003Cul>\n\u003Cli>New finding, new comment, status change, photo upload — all merge cleanly\u003C/li>\n\u003Cli>Before saving: fetch latest version, compare with local base, auto-merge non-conflicting changes\u003C/li>\n\u003Cli>Conflict detection via \u003Ccode dir=\"auto\">eTag\u003C/code> / \u003Ccode dir=\"auto\">lastModifiedDateTime\u003C/code> (already used in \u003Ccode dir=\"auto\">storage.ts\u003C/code>)\u003C/li>\n\u003C/ul>\n\u003Cp>Unresolvable conflicts (both users edited the same finding text simultaneously):\u003C/p>\n\u003Cul>\n\u003Cli>Save as \u003Ccode dir=\"auto\">\"{name} (conflict copy).vrs\"\u003C/code> alongside the original\u003C/li>\n\u003Cli>Zero data loss guarantee — worst case is a duplicate file the team resolves manually\u003C/li>\n\u003Cli>Notification toast: “Another team member modified this project. A conflict copy was saved.”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mobile-layout\">Mobile Layout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-layout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Layout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure app uses a responsive phone layout (< 640px) within the existing Editor — not a separate route:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">MobileChartCarousel\u003C/code> — swipeable carousel (4 views: I-Chart, Boxplot, Pareto, Stats) replacing \u003Ccode dir=\"auto\">DashboardGrid\u003C/code> on phones\u003C/li>\n\u003Cli>Findings panel renders as full-screen overlay on phone, inline sidebar on desktop\u003C/li>\n\u003Cli>Phone toolbar: Back + project name (truncated) + Save + overflow menu (\u003Ccode dir=\"auto\">EllipsisVertical\u003C/code>)\u003C/li>\n\u003Cli>Touch-optimized: 44px minimum touch targets, safe area insets for notched phones\u003C/li>\n\u003Cli>Comment thread with photo capture — Teams SDK \u003Ccode dir=\"auto\">media.selectMedia()\u003C/code> inside Teams (native camera experience), HTML5 file input fallback outside Teams\u003C/li>\n\u003Cli>Annotations disabled on phone (no right-click context menu on touch devices)\u003C/li>\n\u003C/ul>\n\u003Cp>Reuses PWA responsive patterns adapted for Teams mobile WebView. Desktop layout is completely unchanged (all gated by \u003Ccode dir=\"auto\">useIsMobile(640)\u003C/code>).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"sharing-implemented-and-adaptive-cards-planned\">Sharing (Implemented) and Adaptive Cards (Planned)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#sharing-implemented-and-adaptive-cards-planned\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sharing (Implemented) and Adaptive Cards (Planned)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Implemented\u003C/strong>: URL sharing via Teams native dialog (\u003Ccode dir=\"auto\">sharing.shareWebContent\u003C/code>) and deep links (\u003Ccode dir=\"auto\">pages.shareDeepLink\u003C/code>). Share payloads built by \u003Ccode dir=\"auto\">shareContent.ts\u003C/code> for findings and charts.\u003C/p>\n\u003Cp>\u003Cstrong>Planned (Adaptive Cards)\u003C/strong>: Rich sharing into Teams conversations:\u003C/p>\n\u003Cul>\n\u003Cli>Finding summary card: status badge, Cpk value, filter context, photo thumbnail\u003C/li>\n\u003Cli>Deep link buttons: “View Chart”, “Open Finding” → navigate directly into the app\u003C/li>\n\u003Cli>Compose extension in Teams manifest for sharing from the message compose box\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Channel @mention\u003C/strong>: See \u003Ca href=\"adr-018-channel-mention-workflow.md\">ADR-018\u003C/a> for the channel\nmention workflow that extends URL sharing with true @mention notifications in channel tabs.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"on-behalf-of-sso-flow\">On-Behalf-Of SSO Flow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#on-behalf-of-sso-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “On-Behalf-Of SSO Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>An Azure Function (~50 lines) exchanges the Teams SSO token for a Graph API access token:\u003C/p>\n\u003Cul>\n\u003Cli>Deployed via ARM template alongside the App Service\u003C/li>\n\u003Cli>Scopes: \u003Ccode dir=\"auto\">User.Read\u003C/code> + \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>\u003C/li>\n\u003Cli>Fallback: EasyAuth redirect if OBO exchange fails\u003C/li>\n\u003Cli>Minimal attack surface — single-purpose token exchange, no stored state\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"security-considerations\">Security Considerations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#security-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>EXIF/GPS stripping\u003C/strong>: Two-layer metadata removal before upload. First, canvas re-encode strips most EXIF data as a side effect. Second, explicit byte-level \u003Ccode dir=\"auto\">stripExifFromBlob\u003C/code> parses the JPEG binary and removes all EXIF/GPS APP1 markers, guaranteeing no location or device metadata survives. Both layers run client-side. Unit tests (23 cases) verify GPS coordinates, camera model, and orientation are stripped from real-world JPEG samples.\u003C/li>\n\u003Cli>\u003Cstrong>Tighter personal storage\u003C/strong>: \u003Ccode dir=\"auto\">Files.ReadWrite.AppFolder\u003C/code> for personal OneDrive (narrower than \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code>). Channel storage requires \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>.\u003C/li>\n\u003Cli>\u003Cstrong>Photo immutability\u003C/strong>: Photos are immutable once uploaded — no edit or delete of photo files. Prevents evidence tampering in quality investigations.\u003C/li>\n\u003Cli>\u003Cstrong>No-delete principle\u003C/strong>: \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> technically includes delete capability, but VariScout never calls Graph API delete endpoints. The storage model is strictly additive — \u003Ccode dir=\"auto\">.vrs\u003C/code> projects are created/updated (conflicts save as copies), photos are immutable once uploaded. IT admins can audit this: the app contains no \u003Ccode dir=\"auto\">DELETE /drive/items/{id}\u003C/code> calls.\u003C/li>\n\u003Cli>\u003Cstrong>Audit trail\u003C/strong>: Author + timestamp on all findings and comments. Combined with photo immutability, creates a reliable investigation record.\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode dir=\"auto\">devicePermissions: [\"media\"]\u003C/code>\u003C/strong>: Declaring camera access in the Teams manifest makes usage auditable in the Teams Admin Center. IT admins can see which apps request device access during the app permission review. The HTML5 \u003Ccode dir=\"auto\">capture\u003C/code> attribute, by contrast, works silently with no admin visibility.\u003C/li>\n\u003Cli>\u003Cstrong>Font self-hosting\u003C/strong>: Recommend self-hosting Google Fonts for strict CSP environments (no external CDN calls).\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"it-compliance-hardening-february-2026\">IT Compliance Hardening (February 2026)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#it-compliance-hardening-february-2026\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “IT Compliance Hardening (February 2026)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Four gaps identified during Microsoft best practices audit and fixed:\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Reactive Teams theme sync\u003C/strong> — \u003Ccode dir=\"auto\">useTeamsContext\u003C/code> hook now re-renders on Teams theme changes via a subscriber pattern. Teams theme (default/dark/contrast) is mapped into \u003Ccode dir=\"auto\">ThemeContext\u003C/code> on initial load and on every change. High-contrast mode maps to \u003Ccode dir=\"auto\">light\u003C/code> (closest safe match).\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Dynamic CSP \u003Ccode dir=\"auto\">connect-src\u003C/code>\u003C/strong> — \u003Ccode dir=\"auto\">server.js\u003C/code> reads the \u003Ccode dir=\"auto\">FUNCTION_URL\u003C/code> environment variable at startup and includes its origin in the Content Security Policy \u003Ccode dir=\"auto\">connect-src\u003C/code> directive. Without this, OBO token exchange to a separate Azure Function origin was silently blocked by CSP.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>\u003Ccode dir=\"auto\">app.notifyFailure()\u003C/code> on crash\u003C/strong> — The top-level \u003Ccode dir=\"auto\">ErrorBoundary\u003C/code> in \u003Ccode dir=\"auto\">App.tsx\u003C/code> calls \u003Ccode dir=\"auto\">notifyTeamsFailure()\u003C/code> when a render error is caught. This tells the Teams host that the app has crashed, rather than leaving Teams in a “healthy” state while the user sees a fallback error screen.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>\u003Ccode dir=\"auto\">registerBeforeUnloadHandler\u003C/code> for data loss prevention\u003C/strong> — During Teams SDK initialization, a lifecycle handler is registered. The Editor registers a callback that auto-saves the project (via \u003Ccode dir=\"auto\">saveProject()\u003C/code>) if \u003Ccode dir=\"auto\">hasUnsavedChanges\u003C/code> is true when the user navigates away from the tab.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"design-principles\">Design Principles\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#design-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Progressive enhancement, not hard dependency\u003C/strong> — Teams SDK features enhance the experience but the app must always work without them. Every Teams API call has a non-Teams fallback. \u003Ccode dir=\"auto\">isTeamsMediaAvailable()\u003C/code> / \u003Ccode dir=\"auto\">isInTeams()\u003C/code> gate all SDK calls.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>IT admin visibility over silent access\u003C/strong> — Prefer Teams SDK APIs that declare permissions in the manifest (\u003Ccode dir=\"auto\">devicePermissions\u003C/code>, Graph scopes) over HTML5 APIs that work silently. This gives tenant admins an audit trail and consent control.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>No creative filters on quality evidence\u003C/strong> — Photo capture disables Instagram-style filters (\u003Ccode dir=\"auto\">enableFilter: false\u003C/code>), drawing tools (\u003Ccode dir=\"auto\">ink: false\u003C/code>), and text overlays (\u003Ccode dir=\"auto\">textSticker: false\u003C/code>). Quality evidence must be unaltered.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>EXIF stripping is non-negotiable\u003C/strong> — Every photo path (Teams SDK, HTML5 file input, gallery pick) feeds into the same \u003Ccode dir=\"auto\">processPhoto()\u003C/code> → \u003Ccode dir=\"auto\">stripExifFromBlob()\u003C/code> pipeline. No photo reaches OneDrive with GPS or device metadata.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Additive-only storage\u003C/strong> — No delete calls to Graph API. Photos are immutable once uploaded. Conflicts create copies. This is auditable — the app contains no \u003Ccode dir=\"auto\">DELETE /drive/items/{id}\u003C/code> calls.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phased-delivery\">Phased Delivery\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phased-delivery\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phased Delivery”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Phase\u003C/th>\u003Cth>Scope\u003C/th>\u003Cth>Dependencies\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Teams SDK foundation — detect context, manifest with personal + channel tabs\u003C/td>\u003Ctd>None\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Mobile layout — responsive phone carousel in Editor, touch navigation\u003C/td>\u003Ctd>Phase 1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Photo comments — data model, Teams SDK media API + HTML5 fallback, OneDrive upload\u003C/td>\u003Ctd>Phase 1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Channel file storage — shared \u003Ccode dir=\"auto\">.vrs\u003C/code> + photos, optimistic merge\u003C/td>\u003Ctd>Phases 1 + 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Deep links + URL sharing — Teams native dialog, chart/finding links\u003C/td>\u003Ctd>Phases 1 + 4\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Azure Function for On-Behalf-Of — true silent SSO\u003C/td>\u003Ctd>Phase 1\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Phases 2 and 3 can proceed in parallel after Phase 1. Phase 6 can be done at any point after Phase 1 but is lowest priority (EasyAuth fallback works).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"easier\">Easier\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#easier\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Easier”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Gemba investigations\u003C/strong>: Engineers capture photo evidence directly in the analysis tool — no app switching\u003C/li>\n\u003Cli>\u003Cstrong>Team collaboration\u003C/strong>: Shared channel storage means the team works on the same analysis, not emailed copies\u003C/li>\n\u003Cli>\u003Cstrong>Mobile access\u003C/strong>: Teams sidebar icon puts VariScout one tap away on any phone\u003C/li>\n\u003Cli>\u003Cstrong>Rich sharing\u003C/strong>: Adaptive Cards in Teams chat replace screenshot-and-paste workflows\u003C/li>\n\u003Cli>\u003Cstrong>Author tracking\u003C/strong>: Clear audit trail of who observed what, with timestamps\u003C/li>\n\u003Cli>\u003Cstrong>Competitive differentiation\u003C/strong>: “Take VariScout to the gemba” — unique vs desktop-only tools\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"harder\">Harder\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#harder\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Harder”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>New dependency\u003C/strong>: \u003Ccode dir=\"auto\">@microsoft/teams-js\u003C/code> (~40KB gzipped) added to the Azure app bundle\u003C/li>\n\u003Cli>\u003Cstrong>New infrastructure\u003C/strong>: Azure Function in ARM template (Phase 6) for OBO token exchange\u003C/li>\n\u003Cli>\u003Cstrong>Storage complexity\u003C/strong>: \u003Ccode dir=\"auto\">storage.ts\u003C/code> evolves with channel drive branch + optimistic merge logic\u003C/li>\n\u003Cli>\u003Cstrong>Auth complexity\u003C/strong>: \u003Ccode dir=\"auto\">easyAuth.ts\u003C/code> evolves with Teams SSO detection + OBO token exchange\u003C/li>\n\u003Cli>\u003Cstrong>Admin consent\u003C/strong>: Team plan requires IT admin approval for \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> — adds friction to onboarding\u003C/li>\n\u003Cli>\u003Cstrong>Concurrent access\u003C/strong>: Optimistic merge logic must handle edge cases gracefully (network failures, partial saves)\u003C/li>\n\u003Cli>\u003Cstrong>More UI surface\u003C/strong>: Mobile Field View, photo capture, Adaptive Card templates — additional components to maintain\u003C/li>\n\u003Cli>\u003Cstrong>Testing\u003C/strong>: Teams WebView testing requires Teams Developer Portal + sideloading; cannot test locally without Teams context mock\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-decisions\">Related Decisions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-decisions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Decisions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007: Azure Marketplace Distribution\u003C/a> — Two-plan model (Standard + Team)\u003C/li>\n\u003Cli>\u003Ca href=\"adr-015-investigation-board.md\">ADR-015: Investigation Board\u003C/a> — Finding statuses, tags, and comments (extended here with author + photos)\u003C/li>\n\u003Cli>\u003Ca href=\"adr-004-offline-first.md\">ADR-004: Offline-First\u003C/a> — Offline capability preserved; photo upload queued when offline\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://learn.microsoft.com/en-us/microsoftteams/platform/\">Teams SDK Documentation\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-on-behalf-of-flow\">On-Behalf-Of Flow\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://adaptivecards.io/\">Adaptive Cards\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../03-features/workflows/investigation-to-action.md\">Investigation Workflow\u003C/a>\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation-history\">Implementation History\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-history\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation History”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All 6 increments implemented in February 2026:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Increment\u003C/th>\u003Cth>Scope\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Teams SDK foundation — context detection, manifest\u003C/td>\u003Ctd>Implemented\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Mobile layout — responsive phone carousel\u003C/td>\u003Ctd>Implemented\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Photo comments — camera capture, EXIF strip, upload\u003C/td>\u003Ctd>Implemented\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Channel SharePoint storage — shared .vrs + photos\u003C/td>\u003Ctd>Implemented\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Deep links + URL sharing — Teams native dialog\u003C/td>\u003Ctd>Implemented\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>OBO silent SSO — Azure Function token exchange\u003C/td>\u003Ctd>Implemented\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Adaptive Cards remain planned for a future release.\u003C/p>", + { + "headings": 2900, + "localImagePaths": 2947, + "remoteImagePaths": 2948, + "frontmatter": 2949, + "imagePaths": 2950 + }, + [ + 2901, 2903, 2904, 2905, 2908, 2911, 2914, 2917, 2920, 2923, 2926, 2929, 2932, 2935, 2936, 2939, + 2940, 2941, 2942, 2943, 2944 + ], + { "depth": 30, "slug": 2902, "text": 2890 }, + "adr-016-microsoft-teams-integration", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2906, "text": 2907 }, + "two-deployment-profiles", + "Two Deployment Profiles", + { "depth": 79, "slug": 2909, "text": 2910 }, + "admin-consent-model", + "Admin Consent Model", + { "depth": 79, "slug": 2912, "text": 2913 }, + "data-model-extensions", + "Data Model Extensions", + { "depth": 79, "slug": 2915, "text": 2916 }, + "channel-file-storage-layout", + "Channel File Storage Layout", + { "depth": 79, "slug": 2918, "text": 2919 }, + "concurrent-access-strategy", + "Concurrent Access Strategy", + { "depth": 79, "slug": 2921, "text": 2922 }, + "mobile-layout", + "Mobile Layout", + { "depth": 79, "slug": 2924, "text": 2925 }, + "sharing-implemented-and-adaptive-cards-planned", + "Sharing (Implemented) and Adaptive Cards (Planned)", + { "depth": 79, "slug": 2927, "text": 2928 }, + "on-behalf-of-sso-flow", + "On-Behalf-Of SSO Flow", + { "depth": 79, "slug": 2930, "text": 2931 }, + "security-considerations", + "Security Considerations", + { "depth": 79, "slug": 2933, "text": 2934 }, + "it-compliance-hardening-february-2026", + "IT Compliance Hardening (February 2026)", + { "depth": 79, "slug": 998, "text": 999 }, + { "depth": 79, "slug": 2937, "text": 2938 }, + "phased-delivery", + "Phased Delivery", + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2609, "text": 2610 }, + { "depth": 79, "slug": 2612, "text": 2613 }, + { "depth": 33, "slug": 2403, "text": 2404 }, + { "depth": 33, "slug": 149, "text": 150 }, + { "depth": 33, "slug": 2945, "text": 2946 }, + "implementation-history", + "Implementation History", + [], + [], + { "title": 2890 }, + [], + "07-decisions/adr-017-fluent-design-alignment", + { "id": 2951, "data": 2953, "body": 2958, "filePath": 2959, "digest": 2960, "rendered": 2961 }, + { + "title": 2954, + "editUrl": 16, + "head": 2955, + "template": 18, + "sidebar": 2956, + "pagefind": 16, + "draft": 20 + }, + "ADR-017: Fluent 2 Design Principle Alignment", + [], + { "hidden": 20, "attrs": 2957 }, + {}, + "# ADR-017: Fluent 2 Design Principle Alignment\n\n**Status**: Accepted\n\n**Date**: 2026-03-02\n\n**Related**: ADR-007 (marketplace distribution), ADR-016 (Teams integration)\n\n---\n\n## Context\n\nVariScout's Azure app is distributed via Azure Marketplace into M365 tenants, integrated with Teams, OneDrive, and Graph API. Users in these environments work daily with Outlook, Teams, SharePoint, and other Microsoft tools that follow Fluent 2 design principles. A tool that _feels_ foreign in this context creates friction — users expect panels, drawers, modals, and dismiss behaviors to work the way they do across the M365 suite.\n\nMicrosoft's Marketplace review process evaluates whether apps provide a coherent experience within the M365 ecosystem. While there is no strict requirement to adopt Fluent UI components, apps that follow Fluent interaction patterns (panel taxonomy, dismiss behaviors, responsive conversion) pass review more smoothly and receive fewer user complaints.\n\nVariScout's current implementation already follows many Fluent 2 patterns organically — inline panels for simultaneous content, overlay panels for focused attention, responsive phone conversion, Escape-to-dismiss. However, this alignment is undocumented. Developers adding new panels or drawers have no decision framework and must reverse-engineer existing implementations.\n\nTwo questions this ADR answers:\n\n1. Should VariScout formally adopt Fluent 2 design principles?\n2. Should VariScout adopt the `@fluentui/react-components` library?\n\n---\n\n## Decision\n\n**Adopt Fluent 2 interaction patterns and panel taxonomy as design principles. Do NOT adopt the Fluent UI component library.**\n\n### What this means\n\nVariScout follows Fluent 2's _interaction model_ — the rules governing when to use inline vs. overlay panels, how dismiss behaviors work, how panels convert on smaller screens, and how z-index layering is structured. Developers consult the [Panels and Drawers](../06-design-system/patterns/panels-and-drawers.md) design system doc when adding new panel types.\n\nFluent 2 panel taxonomy mapped to VariScout:\n\n| Fluent 2 Concept | VariScout Equivalent | When to Use |\n| ---------------- | ------------------------------- | ------------------------------------- |\n| `DrawerInline` | Inline panel (`flex-shrink-0`) | Simultaneous content (data, findings) |\n| `DrawerOverlay` | Overlay panel (`fixed inset-0`) | Focused attention (settings) |\n| `Dialog` | Modal (`z-50`) | Confirmations, quick forms |\n| `Sheet` (mobile) | Phone full-screen (`z-40`) | Phone panel conversion |\n\nDismiss behaviors follow Fluent 2 conventions:\n\n| Behavior | Inline | Overlay | Modal |\n| -------------- | ------ | ------- | ----- |\n| X button | Yes | Yes | Yes |\n| Escape key | Yes | Yes | Yes |\n| Backdrop click | N/A | Yes | Yes |\n\n### What this does NOT mean\n\n- **No Fluent UI library**: We do not add `@fluentui/react-components` as a dependency. VariScout uses Tailwind CSS with semantic tokens. Adding a component library would create a dual styling system, increase bundle size (~200KB), and conflict with our existing design system.\n- **No Fluent color tokens**: VariScout has its own semantic color system (`bg-surface`, `text-content`, `border-edge`) documented in the design system. These already provide theme-aware light/dark support.\n- **No visual redesign**: Existing components are not restyled to look like Fluent controls. The alignment is behavioral (how panels open, close, layer) not visual (how buttons render).\n- **No Fluent typography scale**: VariScout uses its own type scale (Tailwind defaults + chart font scaling).\n\n### Alignment inventory\n\nCurrent implementations that already follow Fluent 2 principles:\n\n| Fluent 2 Principle | VariScout Implementation | File Reference |\n| ------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------- |\n| Inline drawer for parallel work | DataPanel (data table beside charts) | `apps/azure/src/components/data/DataPanel.tsx` |\n| Inline drawer for parallel work | FindingsPanel (findings beside charts) | `packages/ui/src/components/FindingsPanel/FindingsPanelBase.tsx` |\n| Overlay drawer for focus | SettingsPanel (backdrop + slide-in-right) | `packages/ui/src/components/SettingsPanel/SettingsPanelBase.tsx` |\n| Full-screen page for workflows | WhatIfPage (dedicated simulation workspace) | `packages/ui/src/components/WhatIfPage/WhatIfPageBase.tsx` |\n| Dialog for confirmations | Standard modal (centered, backdrop blur) | `docs/06-design-system/components/modals.md` |\n| Sheet for mobile | Phone FindingsPanel (slide-up full-screen) | `apps/azure/src/pages/Editor.tsx:1017` |\n| Escape-to-dismiss | All panels and modals | `FindingsPanelBase.tsx:99`, `SettingsPanelBase.tsx:59` |\n| Backdrop click closes overlay | SettingsPanel backdrop | `SettingsPanelBase.tsx:73` |\n| Resizable inline panels | DataPanel, FindingsPanel (drag divider) | `useResizablePanel` from `@variscout/hooks` |\n| Responsive conversion | FindingsPanel: inline (desktop) → overlay (phone) | `Editor.tsx:1015-1017` |\n| Slide-in-right animation | SettingsPanel (0.25s ease-out) | `packages/ui/src/styles/components.css:94` |\n| Slide-up animation | Phone overlays (0.3s ease-out) | `packages/ui/src/styles/components.css:78` |\n| Z-index layering | Sticky → nav → phone overlays → modals → overlay panels → skip links | See z-index scale in panels-and-drawers.md |\n\n---\n\n## Consequences\n\n### Easier\n\n- **Marketplace review**: Aligned interaction patterns reduce reviewer friction and user complaints about \"non-native\" behavior\n- **Developer guidance**: New panels have a documented decision framework — developers don't guess or copy-paste inconsistently\n- **User familiarity**: M365 users encounter expected panel behaviors (Escape, backdrop click, responsive conversion)\n- **Audit trail**: This ADR records the deliberate choice to align on principles without library dependency\n\n### Harder\n\n- **Decision overhead**: Developers must consult the panel decision framework before adding new panel types (minor — a 30-second table lookup)\n- **Maintenance**: The alignment inventory must be updated when new panel types are added\n- **Not enforced by tooling**: Unlike adopting a component library, principle alignment relies on documentation and code review rather than compile-time checks\n\n---\n\n## See Also\n\n- [Panels and Drawers](../06-design-system/patterns/panels-and-drawers.md) — Practical decision framework and implementation reference\n- [Modals](../06-design-system/components/modals.md) — Existing modal patterns and z-index scale\n- [Fluent 2 Drawer documentation](https://fluent2.microsoft.design/components/web/react/drawer)", + "src/content/docs/07-decisions/adr-017-fluent-design-alignment.md", + "831ce7329ef36ba4", + { "html": 2962, "metadata": 2963 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-017-fluent-2-design-principle-alignment\">ADR-017: Fluent 2 Design Principle Alignment\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-017-fluent-2-design-principle-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-017: Fluent 2 Design Principle Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Accepted\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2026-03-02\u003C/p>\n\u003Cp>\u003Cstrong>Related\u003C/strong>: ADR-007 (marketplace distribution), ADR-016 (Teams integration)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s Azure app is distributed via Azure Marketplace into M365 tenants, integrated with Teams, OneDrive, and Graph API. Users in these environments work daily with Outlook, Teams, SharePoint, and other Microsoft tools that follow Fluent 2 design principles. A tool that \u003Cem>feels\u003C/em> foreign in this context creates friction — users expect panels, drawers, modals, and dismiss behaviors to work the way they do across the M365 suite.\u003C/p>\n\u003Cp>Microsoft’s Marketplace review process evaluates whether apps provide a coherent experience within the M365 ecosystem. While there is no strict requirement to adopt Fluent UI components, apps that follow Fluent interaction patterns (panel taxonomy, dismiss behaviors, responsive conversion) pass review more smoothly and receive fewer user complaints.\u003C/p>\n\u003Cp>VariScout’s current implementation already follows many Fluent 2 patterns organically — inline panels for simultaneous content, overlay panels for focused attention, responsive phone conversion, Escape-to-dismiss. However, this alignment is undocumented. Developers adding new panels or drawers have no decision framework and must reverse-engineer existing implementations.\u003C/p>\n\u003Cp>Two questions this ADR answers:\u003C/p>\n\u003Col>\n\u003Cli>Should VariScout formally adopt Fluent 2 design principles?\u003C/li>\n\u003Cli>Should VariScout adopt the \u003Ccode dir=\"auto\">@fluentui/react-components\u003C/code> library?\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Adopt Fluent 2 interaction patterns and panel taxonomy as design principles. Do NOT adopt the Fluent UI component library.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-this-means\">What this means\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-this-means\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What this means”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout follows Fluent 2’s \u003Cem>interaction model\u003C/em> — the rules governing when to use inline vs. overlay panels, how dismiss behaviors work, how panels convert on smaller screens, and how z-index layering is structured. Developers consult the \u003Ca href=\"../06-design-system/patterns/panels-and-drawers.md\">Panels and Drawers\u003C/a> design system doc when adding new panel types.\u003C/p>\n\u003Cp>Fluent 2 panel taxonomy mapped to VariScout:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Fluent 2 Concept\u003C/th>\u003Cth>VariScout Equivalent\u003C/th>\u003Cth>When to Use\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">DrawerInline\u003C/code>\u003C/td>\u003Ctd>Inline panel (\u003Ccode dir=\"auto\">flex-shrink-0\u003C/code>)\u003C/td>\u003Ctd>Simultaneous content (data, findings)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">DrawerOverlay\u003C/code>\u003C/td>\u003Ctd>Overlay panel (\u003Ccode dir=\"auto\">fixed inset-0\u003C/code>)\u003C/td>\u003Ctd>Focused attention (settings)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Dialog\u003C/code>\u003C/td>\u003Ctd>Modal (\u003Ccode dir=\"auto\">z-50\u003C/code>)\u003C/td>\u003Ctd>Confirmations, quick forms\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Sheet\u003C/code> (mobile)\u003C/td>\u003Ctd>Phone full-screen (\u003Ccode dir=\"auto\">z-40\u003C/code>)\u003C/td>\u003Ctd>Phone panel conversion\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Dismiss behaviors follow Fluent 2 conventions:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Behavior\u003C/th>\u003Cth>Inline\u003C/th>\u003Cth>Overlay\u003C/th>\u003Cth>Modal\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>X button\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Escape key\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Backdrop click\u003C/td>\u003Ctd>N/A\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-this-does-not-mean\">What this does NOT mean\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-this-does-not-mean\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What this does NOT mean”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>No Fluent UI library\u003C/strong>: We do not add \u003Ccode dir=\"auto\">@fluentui/react-components\u003C/code> as a dependency. VariScout uses Tailwind CSS with semantic tokens. Adding a component library would create a dual styling system, increase bundle size (~200KB), and conflict with our existing design system.\u003C/li>\n\u003Cli>\u003Cstrong>No Fluent color tokens\u003C/strong>: VariScout has its own semantic color system (\u003Ccode dir=\"auto\">bg-surface\u003C/code>, \u003Ccode dir=\"auto\">text-content\u003C/code>, \u003Ccode dir=\"auto\">border-edge\u003C/code>) documented in the design system. These already provide theme-aware light/dark support.\u003C/li>\n\u003Cli>\u003Cstrong>No visual redesign\u003C/strong>: Existing components are not restyled to look like Fluent controls. The alignment is behavioral (how panels open, close, layer) not visual (how buttons render).\u003C/li>\n\u003Cli>\u003Cstrong>No Fluent typography scale\u003C/strong>: VariScout uses its own type scale (Tailwind defaults + chart font scaling).\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"alignment-inventory\">Alignment inventory\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#alignment-inventory\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Alignment inventory”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Current implementations that already follow Fluent 2 principles:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Fluent 2 Principle\u003C/th>\u003Cth>VariScout Implementation\u003C/th>\u003Cth>File Reference\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Inline drawer for parallel work\u003C/td>\u003Ctd>DataPanel (data table beside charts)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/azure/src/components/data/DataPanel.tsx\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Inline drawer for parallel work\u003C/td>\u003Ctd>FindingsPanel (findings beside charts)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/FindingsPanel/FindingsPanelBase.tsx\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Overlay drawer for focus\u003C/td>\u003Ctd>SettingsPanel (backdrop + slide-in-right)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/SettingsPanel/SettingsPanelBase.tsx\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Full-screen page for workflows\u003C/td>\u003Ctd>WhatIfPage (dedicated simulation workspace)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/WhatIfPage/WhatIfPageBase.tsx\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Dialog for confirmations\u003C/td>\u003Ctd>Standard modal (centered, backdrop blur)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">docs/06-design-system/components/modals.md\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sheet for mobile\u003C/td>\u003Ctd>Phone FindingsPanel (slide-up full-screen)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/azure/src/pages/Editor.tsx:1017\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Escape-to-dismiss\u003C/td>\u003Ctd>All panels and modals\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FindingsPanelBase.tsx:99\u003C/code>, \u003Ccode dir=\"auto\">SettingsPanelBase.tsx:59\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Backdrop click closes overlay\u003C/td>\u003Ctd>SettingsPanel backdrop\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">SettingsPanelBase.tsx:73\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Resizable inline panels\u003C/td>\u003Ctd>DataPanel, FindingsPanel (drag divider)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useResizablePanel\u003C/code> from \u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Responsive conversion\u003C/td>\u003Ctd>FindingsPanel: inline (desktop) → overlay (phone)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Editor.tsx:1015-1017\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Slide-in-right animation\u003C/td>\u003Ctd>SettingsPanel (0.25s ease-out)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/styles/components.css:94\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Slide-up animation\u003C/td>\u003Ctd>Phone overlays (0.3s ease-out)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/styles/components.css:78\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Z-index layering\u003C/td>\u003Ctd>Sticky → nav → phone overlays → modals → overlay panels → skip links\u003C/td>\u003Ctd>See z-index scale in panels-and-drawers.md\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"easier\">Easier\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#easier\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Easier”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Marketplace review\u003C/strong>: Aligned interaction patterns reduce reviewer friction and user complaints about “non-native” behavior\u003C/li>\n\u003Cli>\u003Cstrong>Developer guidance\u003C/strong>: New panels have a documented decision framework — developers don’t guess or copy-paste inconsistently\u003C/li>\n\u003Cli>\u003Cstrong>User familiarity\u003C/strong>: M365 users encounter expected panel behaviors (Escape, backdrop click, responsive conversion)\u003C/li>\n\u003Cli>\u003Cstrong>Audit trail\u003C/strong>: This ADR records the deliberate choice to align on principles without library dependency\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"harder\">Harder\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#harder\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Harder”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Decision overhead\u003C/strong>: Developers must consult the panel decision framework before adding new panel types (minor — a 30-second table lookup)\u003C/li>\n\u003Cli>\u003Cstrong>Maintenance\u003C/strong>: The alignment inventory must be updated when new panel types are added\u003C/li>\n\u003Cli>\u003Cstrong>Not enforced by tooling\u003C/strong>: Unlike adopting a component library, principle alignment relies on documentation and code review rather than compile-time checks\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../06-design-system/patterns/panels-and-drawers.md\">Panels and Drawers\u003C/a> — Practical decision framework and implementation reference\u003C/li>\n\u003Cli>\u003Ca href=\"../06-design-system/components/modals.md\">Modals\u003C/a> — Existing modal patterns and z-index scale\u003C/li>\n\u003Cli>\u003Ca href=\"https://fluent2.microsoft.design/components/web/react/drawer\">Fluent 2 Drawer documentation\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 2964, + "localImagePaths": 2982, + "remoteImagePaths": 2983, + "frontmatter": 2984, + "imagePaths": 2985 + }, + [2965, 2967, 2968, 2969, 2972, 2975, 2978, 2979, 2980, 2981], + { "depth": 30, "slug": 2966, "text": 2954 }, + "adr-017-fluent-2-design-principle-alignment", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 2970, "text": 2971 }, + "what-this-means", + "What this means", + { "depth": 79, "slug": 2973, "text": 2974 }, + "what-this-does-not-mean", + "What this does NOT mean", + { "depth": 79, "slug": 2976, "text": 2977 }, + "alignment-inventory", + "Alignment inventory", + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2609, "text": 2610 }, + { "depth": 79, "slug": 2612, "text": 2613 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 2954 }, + [], + "07-decisions/adr-018-channel-mention-workflow", + { "id": 2986, "data": 2988, "body": 2993, "filePath": 2994, "digest": 2995, "rendered": 2996 }, + { + "title": 2989, + "editUrl": 16, + "head": 2990, + "template": 18, + "sidebar": 2991, + "pagefind": 16, + "draft": 20 + }, + "ADR-018: Channel @Mention Workflow — Mobile Finding to Team Action", + [], + { "hidden": 20, "attrs": 2992 }, + {}, + "# ADR-018: Channel @Mention Workflow — Mobile Finding to Team Action\n\n**Status**: Proposed\n\n**Date**: 2026-03-02\n\n**Related**: ADR-016 (Teams integration), ADR-015 (investigation board), ADR-007 (marketplace distribution)\n\n---\n\n## Context\n\nADR-015 established findings as a lightweight investigation tool: \"NOT project management — no\nassignees, no due dates, no priority levels.\" ADR-016 added Teams integration with URL sharing\n(`shareWebContent`) and deep links, with Adaptive Cards noted as planned.\n\nField supervisors on their phones now have a gap: they can observe a pattern in a chart and pin\nit as a finding, but there's no way to assign it to a specific person and notify them to\ninvestigate. The current workflow requires:\n\n1. Pin finding → 2. Open findings panel → 3. Tap share → 4. Pick conversation in Teams share\n dialog → 5. Separately tell the person in chat to look at it\n\nThis is 5 steps with context-switching. The desired workflow:\n\n1. Tap chart bar → 2. Type observation + pick person → 3. Pin & Share → done (colleague gets\n @mention notification in the channel with a deep link)\n\nAdditionally, a bug exists: the note text typed in MobileCategorySheet is silently discarded\nwhen creating chart observations. All mobile chart findings are created with empty text.\n\n### Why now\n\n- The mobile carousel (ADR-016 Phase 2) and MobileCategorySheet are implemented and stable\n- Teams context already provides `teamId` and `channelId` in channel tabs\n- The OBO token exchange infrastructure (ADR-016 Phase 6) supports scope extension\n- The `ChannelMessage.Send` permission fits naturally into the existing admin consent flow\n (IT admins already approve `Files.ReadWrite.All` and `Channel.ReadBasic.All`)\n\n---\n\n## Decision\n\n**Extend the Finding data model with an optional assignee and enable true @mention posting\nto the current Teams channel from the mobile chart interaction sheet.**\n\nThis consciously relaxes ADR-015's \"no assignees\" constraint for the Team plan only. The\nassignee is lightweight — a display name and UPN, not a full project management system.\nThere are no due dates, priorities, or assignment notifications outside of Teams channels.\n\n### Finding Assignee (Data Model Extension)\n\n```typescript\ninterface FindingAssignee {\n /** Azure AD user principal name (e.g. jane@contoso.com) */\n upn: string;\n /** Display name for UI rendering */\n displayName: string;\n /** Azure AD object ID — used for Graph @mention entity */\n userId?: string;\n}\n\n// Finding interface gains:\nassignee?: FindingAssignee;\n```\n\nThe field is optional. Existing `.vrs` files load without modification. The PWA ignores it.\nStandard plan does not render the assignee UI.\n\n### Mobile Interaction Flow\n\n```\nTap boxplot box / Pareto bar\n → MobileCategorySheet opens (existing)\n → Type observation note (bug fix: text now preserved)\n → \"Pin as Finding\" button\n → Finding created with note + chart source\n → Sheet transitions to confirmation phase:\n ┌──────────────────────────────────┐\n │ Finding created │\n │ \"Machine B runs hot\" │\n │ │\n │ [Assign & Share to Teams] │\n │ [Done] │\n └──────────────────────────────────┘\n → \"Assign & Share\" tapped:\n ┌──────────────────────────────────┐\n │ Assign to: [Search people ] │\n │ ┌─────────────────────────┐ │\n │ │ Jane Smith │ │\n │ │ Karl Virtanen │ │\n │ └─────────────────────────┘ │\n │ │\n │ [Share to Channel] │\n └──────────────────────────────────┘\n → Posts @mention message to current channel\n```\n\n### Channel @Mention (Graph API)\n\nWhen in a Teams channel tab (`isChannelTab() && isTeamPlan()`), the app posts directly to\nthe current channel via Graph API:\n\n```\nPOST /teams/{teamId}/channels/{channelId}/messages\n\n{\n \"body\": {\n \"contentType\": \"html\",\n \"content\": \"\u003Cat id=\\\"0\\\">Jane Smith\u003C/at> Machine B showing 38% contribution.\n Cpk 0.7 — \u003Ca href=\\\"{deepLink}\\\">Open in VariScout\u003C/a>\"\n },\n \"mentions\": [{\n \"id\": 0,\n \"mentionText\": \"Jane Smith\",\n \"mentioned\": {\n \"user\": {\n \"id\": \"{azure-ad-user-id}\",\n \"displayName\": \"Jane Smith\",\n \"userIdentityType\": \"aadUser\"\n }\n }\n }]\n}\n```\n\nThe `teamId` and `channelId` come from `getTeamsContext()` (already available). The\n`userId` comes from the People Picker search result.\n\n### Fallback Chain\n\n```\nisChannelTab() && isTeamPlan()?\n├── Yes → POST /channels/{id}/messages → real @mention with notification bell\n└── No → isInTeams()?\n ├── Yes → sharing.shareWebContent() → URL card (user picks conversation)\n └── No → navigator.clipboard.writeText(url) → copy deep link\n```\n\nThe channel @mention is the fast path for the target persona (supervisor in a channel tab).\nAll other contexts gracefully fall back to existing sharing mechanisms.\n\n### People Search\n\nColleagues are searched via `GET /me/people?$search=\"{query}\"` (Graph People API). This\nreturns people relevant to the signed-in user — org chart adjacency, recent collaborators,\nTeams channel members. Debounced at 300ms, max 5 results displayed.\n\n### Permission Extension\n\n| Permission | Type | Consent | Purpose | Status |\n| --------------------- | --------- | ------- | ------------------------- | ------------------- |\n| `People.Read` | Delegated | User | People picker search | **New** (Team plan) |\n| `ChannelMessage.Send` | Delegated | Admin | Channel @mention messages | **New** (Team plan) |\n\nBoth are additive to the existing Team plan scope string. `ChannelMessage.Send` requires\nadmin consent but fits naturally into the existing consent flow — IT admins already approve\n`Files.ReadWrite.All` and `Channel.ReadBasic.All` during Managed App deployment.\n\nThe OBO token exchange function gains scope flexibility: the client sends requested scopes,\nthe function validates against a server-side allowlist before exchanging.\n\nStandard plan scope string is unchanged. PWA is unaffected.\n\n### Security Considerations\n\n- **Scope allowlist**: The OBO Azure Function validates requested scopes against a hardcoded\n allowlist. The client cannot request arbitrary Graph permissions.\n- **Channel-scoped posting**: Messages are posted to the channel the app is installed in —\n the user cannot target arbitrary channels. `channelId` comes from Teams context, not user\n input.\n- **Assignee is advisory**: The `FindingAssignee` field is a display hint, not an access\n control mechanism. Any channel member can view and update any finding.\n- **No escalation path**: The app posts messages as the signed-in user (delegated permission),\n not as a service principal. Messages appear with the user's name and avatar — fully\n attributable.\n\n---\n\n## Consequences\n\n### Easier\n\n- **3-tap investigation dispatch**: Tap chart → type observation → Pin & Share. Colleague\n gets a Teams notification bell with a deep link directly to the finding.\n- **Natural supervisor workflow**: Observation, assignment, and notification happen in a\n single interaction on the factory floor — no app switching or manual forwarding.\n- **Audit trail**: The channel message provides a timestamped record of who flagged what\n and who was assigned, visible to the entire team.\n\n### Harder\n\n- **Admin consent expansion**: `ChannelMessage.Send` requires admin approval. This is one\n more scope in the existing consent flow but may raise questions from cautious IT admins.\n Mitigation: document that messages are always user-attributed (delegated, not app-only).\n- **OBO scope flexibility**: The token exchange function becomes slightly more complex with\n scope allowlisting, but this is a one-time infrastructure change.\n- **ADR-015 evolution**: The \"no assignees\" constraint is relaxed for Team plan. This is\n a conscious design choice — assignment here is lightweight (name + UPN), not a PM system.\n\n---\n\n## Related Decisions\n\n- [ADR-015: Investigation Board](adr-015-investigation-board.md) — Findings system (extended\n here with assignee)\n- [ADR-016: Teams Integration](adr-016-teams-integration.md) — Teams SDK foundation, mobile\n layout, sharing (extended here with channel @mention)\n- [ADR-007: Azure Marketplace Distribution](adr-007-azure-marketplace-distribution.md) —\n Standard vs Team plan gating\n\n---\n\n## Implementation Phases\n\n| Phase | Scope | Size |\n| ----- | ----------------------------------------------------------------- | ------ |\n| 1 | Bug fix: note text flows through MobileChartCarousel | Small |\n| 2 | FindingAssignee data model + useFindings update | Small |\n| 3 | People Picker + graphPeople service (People.Read) | Medium |\n| 4 | Post-pin \"Assign & Share\" flow in MobileCategorySheet | Medium |\n| 5 | Channel @mention via Graph (ChannelMessage.Send) + OBO scope flex | Medium |", + "src/content/docs/07-decisions/adr-018-channel-mention-workflow.md", + "14b9901e0631f583", + { "html": 2997, "metadata": 2998 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"adr-018-channel-mention-workflow--mobile-finding-to-team-action\">ADR-018: Channel @Mention Workflow — Mobile Finding to Team Action\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#adr-018-channel-mention-workflow--mobile-finding-to-team-action\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR-018: Channel @Mention Workflow — Mobile Finding to Team Action”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Proposed\u003C/p>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2026-03-02\u003C/p>\n\u003Cp>\u003Cstrong>Related\u003C/strong>: ADR-016 (Teams integration), ADR-015 (investigation board), ADR-007 (marketplace distribution)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>ADR-015 established findings as a lightweight investigation tool: “NOT project management — no\nassignees, no due dates, no priority levels.” ADR-016 added Teams integration with URL sharing\n(\u003Ccode dir=\"auto\">shareWebContent\u003C/code>) and deep links, with Adaptive Cards noted as planned.\u003C/p>\n\u003Cp>Field supervisors on their phones now have a gap: they can observe a pattern in a chart and pin\nit as a finding, but there’s no way to assign it to a specific person and notify them to\ninvestigate. The current workflow requires:\u003C/p>\n\u003Col>\n\u003Cli>Pin finding → 2. Open findings panel → 3. Tap share → 4. Pick conversation in Teams share\ndialog → 5. Separately tell the person in chat to look at it\u003C/li>\n\u003C/ol>\n\u003Cp>This is 5 steps with context-switching. The desired workflow:\u003C/p>\n\u003Col>\n\u003Cli>Tap chart bar → 2. Type observation + pick person → 3. Pin & Share → done (colleague gets\n@mention notification in the channel with a deep link)\u003C/li>\n\u003C/ol>\n\u003Cp>Additionally, a bug exists: the note text typed in MobileCategorySheet is silently discarded\nwhen creating chart observations. All mobile chart findings are created with empty text.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-now\">Why now\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-now\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why now”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>The mobile carousel (ADR-016 Phase 2) and MobileCategorySheet are implemented and stable\u003C/li>\n\u003Cli>Teams context already provides \u003Ccode dir=\"auto\">teamId\u003C/code> and \u003Ccode dir=\"auto\">channelId\u003C/code> in channel tabs\u003C/li>\n\u003Cli>The OBO token exchange infrastructure (ADR-016 Phase 6) supports scope extension\u003C/li>\n\u003Cli>The \u003Ccode dir=\"auto\">ChannelMessage.Send\u003C/code> permission fits naturally into the existing admin consent flow\n(IT admins already approve \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> and \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision\">Decision\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Extend the Finding data model with an optional assignee and enable true @mention posting\nto the current Teams channel from the mobile chart interaction sheet.\u003C/strong>\u003C/p>\n\u003Cp>This consciously relaxes ADR-015’s “no assignees” constraint for the Team plan only. The\nassignee is lightweight — a display name and UPN, not a full project management system.\nThere are no due dates, priorities, or assignment notifications outside of Teams channels.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"finding-assignee-data-model-extension\">Finding Assignee (Data Model Extension)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#finding-assignee-data-model-extension\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Finding Assignee (Data Model Extension)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FindingAssignee {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Azure AD user principal name (e.g. jane@contoso.com) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">upn\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Display name for UI rendering */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">displayName\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Azure AD object ID — used for Graph \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">@mention\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"> entity */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">userId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Finding interface gains:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">assignee\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FindingAssignee;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface FindingAssignee { /** Azure AD user principal name (e.g. jane@contoso.com) */ upn: string; /** Display name for UI rendering */ displayName: string; /** Azure AD object ID — used for Graph @mention entity */ userId?: string;}// Finding interface gains:assignee?: FindingAssignee;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The field is optional. Existing \u003Ccode dir=\"auto\">.vrs\u003C/code> files load without modification. The PWA ignores it.\nStandard plan does not render the assignee UI.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mobile-interaction-flow\">Mobile Interaction Flow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-interaction-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Interaction Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Tap boxplot box / Pareto bar\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">→ MobileCategorySheet opens (existing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">→ Type observation note (bug fix: text now preserved)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">→ \"Pin as Finding\" button\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">→ Finding created with note + chart source\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">→ Sheet transitions to confirmation phase:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌──────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Finding created │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Machine B runs hot\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Assign & Share to Teams] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Done] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">→ \"Assign & Share\" tapped:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌──────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Assign to: [Search people ] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌─────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Jane Smith │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Karl Virtanen │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └─────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Share to Channel] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">→ Posts @mention message to current channel\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Tap boxplot box / Pareto bar → MobileCategorySheet opens (existing) → Type observation note (bug fix: text now preserved) → "Pin as Finding" button → Finding created with note + chart source → Sheet transitions to confirmation phase: ┌──────────────────────────────────┐ │ Finding created │ │ "Machine B runs hot" │ │ │ │ [Assign & Share to Teams] │ │ [Done] │ └──────────────────────────────────┘ → "Assign & Share" tapped: ┌──────────────────────────────────┐ │ Assign to: [Search people ] │ │ ┌─────────────────────────┐ │ │ │ Jane Smith │ │ │ │ Karl Virtanen │ │ │ └─────────────────────────┘ │ │ │ │ [Share to Channel] │ └──────────────────────────────────┘ → Posts @mention message to current channel\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"channel-mention-graph-api\">Channel @Mention (Graph API)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#channel-mention-graph-api\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Channel @Mention (Graph API)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When in a Teams channel tab (\u003Ccode dir=\"auto\">isChannelTab() && isTeamPlan()\u003C/code>), the app posts directly to\nthe current channel via Graph API:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">POST /teams/{teamId}/channels/{channelId}/messages\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"body\": {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"contentType\": \"html\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"content\": \"<at id=\\\"0\\\">Jane Smith</at> Machine B showing 38% contribution.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cpk 0.7 — <a href=\\\"{deepLink}\\\">Open in VariScout</a>\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"mentions\": [{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"id\": 0,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"mentionText\": \"Jane Smith\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"mentioned\": {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"user\": {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"id\": \"{azure-ad-user-id}\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"displayName\": \"Jane Smith\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"userIdentityType\": \"aadUser\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">}]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"POST /teams/{teamId}/channels/{channelId}/messages{ "body": { "contentType": "html", "content": "\u003Cat id=\\"0\\">Jane Smith\u003C/at> Machine B showing 38% contribution. Cpk 0.7 — \u003Ca href=\\"{deepLink}\\">Open in VariScout\u003C/a>" }, "mentions": [{ "id": 0, "mentionText": "Jane Smith", "mentioned": { "user": { "id": "{azure-ad-user-id}", "displayName": "Jane Smith", "userIdentityType": "aadUser" } } }]}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">teamId\u003C/code> and \u003Ccode dir=\"auto\">channelId\u003C/code> come from \u003Ccode dir=\"auto\">getTeamsContext()\u003C/code> (already available). The\n\u003Ccode dir=\"auto\">userId\u003C/code> comes from the People Picker search result.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"fallback-chain\">Fallback Chain\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#fallback-chain\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Fallback Chain”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">isChannelTab() && isTeamPlan()?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Yes → POST /channels/{id}/messages → real @mention with notification bell\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── No → isInTeams()?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Yes → sharing.shareWebContent() → URL card (user picks conversation)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── No → navigator.clipboard.writeText(url) → copy deep link\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"isChannelTab() && isTeamPlan()?├── Yes → POST /channels/{id}/messages → real @mention with notification bell└── No → isInTeams()? ├── Yes → sharing.shareWebContent() → URL card (user picks conversation) └── No → navigator.clipboard.writeText(url) → copy deep link\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The channel @mention is the fast path for the target persona (supervisor in a channel tab).\nAll other contexts gracefully fall back to existing sharing mechanisms.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"people-search\">People Search\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#people-search\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “People Search”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Colleagues are searched via \u003Ccode dir=\"auto\">GET /me/people?$search=\"{query}\"\u003C/code> (Graph People API). This\nreturns people relevant to the signed-in user — org chart adjacency, recent collaborators,\nTeams channel members. Debounced at 300ms, max 5 results displayed.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"permission-extension\">Permission Extension\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#permission-extension\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Permission Extension”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Permission\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Consent\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">People.Read\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>User\u003C/td>\u003Ctd>People picker search\u003C/td>\u003Ctd>\u003Cstrong>New\u003C/strong> (Team plan)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChannelMessage.Send\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Admin\u003C/td>\u003Ctd>Channel @mention messages\u003C/td>\u003Ctd>\u003Cstrong>New\u003C/strong> (Team plan)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Both are additive to the existing Team plan scope string. \u003Ccode dir=\"auto\">ChannelMessage.Send\u003C/code> requires\nadmin consent but fits naturally into the existing consent flow — IT admins already approve\n\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> and \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code> during Managed App deployment.\u003C/p>\n\u003Cp>The OBO token exchange function gains scope flexibility: the client sends requested scopes,\nthe function validates against a server-side allowlist before exchanging.\u003C/p>\n\u003Cp>Standard plan scope string is unchanged. PWA is unaffected.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"security-considerations\">Security Considerations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#security-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Scope allowlist\u003C/strong>: The OBO Azure Function validates requested scopes against a hardcoded\nallowlist. The client cannot request arbitrary Graph permissions.\u003C/li>\n\u003Cli>\u003Cstrong>Channel-scoped posting\u003C/strong>: Messages are posted to the channel the app is installed in —\nthe user cannot target arbitrary channels. \u003Ccode dir=\"auto\">channelId\u003C/code> comes from Teams context, not user\ninput.\u003C/li>\n\u003Cli>\u003Cstrong>Assignee is advisory\u003C/strong>: The \u003Ccode dir=\"auto\">FindingAssignee\u003C/code> field is a display hint, not an access\ncontrol mechanism. Any channel member can view and update any finding.\u003C/li>\n\u003Cli>\u003Cstrong>No escalation path\u003C/strong>: The app posts messages as the signed-in user (delegated permission),\nnot as a service principal. Messages appear with the user’s name and avatar — fully\nattributable.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"consequences\">Consequences\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"easier\">Easier\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#easier\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Easier”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>3-tap investigation dispatch\u003C/strong>: Tap chart → type observation → Pin & Share. Colleague\ngets a Teams notification bell with a deep link directly to the finding.\u003C/li>\n\u003Cli>\u003Cstrong>Natural supervisor workflow\u003C/strong>: Observation, assignment, and notification happen in a\nsingle interaction on the factory floor — no app switching or manual forwarding.\u003C/li>\n\u003Cli>\u003Cstrong>Audit trail\u003C/strong>: The channel message provides a timestamped record of who flagged what\nand who was assigned, visible to the entire team.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"harder\">Harder\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#harder\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Harder”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Admin consent expansion\u003C/strong>: \u003Ccode dir=\"auto\">ChannelMessage.Send\u003C/code> requires admin approval. This is one\nmore scope in the existing consent flow but may raise questions from cautious IT admins.\nMitigation: document that messages are always user-attributed (delegated, not app-only).\u003C/li>\n\u003Cli>\u003Cstrong>OBO scope flexibility\u003C/strong>: The token exchange function becomes slightly more complex with\nscope allowlisting, but this is a one-time infrastructure change.\u003C/li>\n\u003Cli>\u003Cstrong>ADR-015 evolution\u003C/strong>: The “no assignees” constraint is relaxed for Team plan. This is\na conscious design choice — assignment here is lightweight (name + UPN), not a PM system.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-decisions\">Related Decisions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-decisions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Decisions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"adr-015-investigation-board.md\">ADR-015: Investigation Board\u003C/a> — Findings system (extended\nhere with assignee)\u003C/li>\n\u003Cli>\u003Ca href=\"adr-016-teams-integration.md\">ADR-016: Teams Integration\u003C/a> — Teams SDK foundation, mobile\nlayout, sharing (extended here with channel @mention)\u003C/li>\n\u003Cli>\u003Ca href=\"adr-007-azure-marketplace-distribution.md\">ADR-007: Azure Marketplace Distribution\u003C/a> —\nStandard vs Team plan gating\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation-phases\">Implementation Phases\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-phases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation Phases”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Phase\u003C/th>\u003Cth>Scope\u003C/th>\u003Cth>Size\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Bug fix: note text flows through MobileChartCarousel\u003C/td>\u003Ctd>Small\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>FindingAssignee data model + useFindings update\u003C/td>\u003Ctd>Small\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>People Picker + graphPeople service (People.Read)\u003C/td>\u003Ctd>Medium\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Post-pin “Assign & Share” flow in MobileCategorySheet\u003C/td>\u003Ctd>Medium\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Channel @mention via Graph (ChannelMessage.Send) + OBO scope flex\u003C/td>\u003Ctd>Medium\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 2999, + "localImagePaths": 3031, + "remoteImagePaths": 3032, + "frontmatter": 3033, + "imagePaths": 3034 + }, + [3000, 3002, 3003, 3006, 3007, 3010, 3013, 3016, 3019, 3022, 3025, 3026, 3027, 3028, 3029, 3030], + { "depth": 30, "slug": 3001, "text": 2989 }, + "adr-018-channel-mention-workflow--mobile-finding-to-team-action", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 79, "slug": 3004, "text": 3005 }, + "why-now", + "Why now", + { "depth": 33, "slug": 2150, "text": 2151 }, + { "depth": 79, "slug": 3008, "text": 3009 }, + "finding-assignee-data-model-extension", + "Finding Assignee (Data Model Extension)", + { "depth": 79, "slug": 3011, "text": 3012 }, + "mobile-interaction-flow", + "Mobile Interaction Flow", + { "depth": 79, "slug": 3014, "text": 3015 }, + "channel-mention-graph-api", + "Channel @Mention (Graph API)", + { "depth": 79, "slug": 3017, "text": 3018 }, + "fallback-chain", + "Fallback Chain", + { "depth": 79, "slug": 3020, "text": 3021 }, + "people-search", + "People Search", + { "depth": 79, "slug": 3023, "text": 3024 }, + "permission-extension", + "Permission Extension", + { "depth": 79, "slug": 2930, "text": 2931 }, + { "depth": 33, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 2609, "text": 2610 }, + { "depth": 79, "slug": 2612, "text": 2613 }, + { "depth": 33, "slug": 2403, "text": 2404 }, + { "depth": 33, "slug": 2385, "text": 2386 }, + [], + [], + { "title": 2989 }, + [], + "07-decisions/audit-2026-02-state-of-product", + { "id": 3035, "data": 3037, "body": 3042, "filePath": 3043, "digest": 3044, "rendered": 3045 }, + { + "title": 3038, + "editUrl": 16, + "head": 3039, + "template": 18, + "sidebar": 3040, + "pagefind": 16, + "draft": 20 + }, + "State-of-the-Product Audit — February 2026", + [], + { "hidden": 20, "attrs": 3041 }, + {}, + "# State-of-the-Product Audit — February 2026\n\n**Date**: 2026-02-13\n**Scope**: Full codebase, all docs, all packages and apps\n**Method**: Automated exhaustive exploration (not sampling)\n\n---\n\n## Context\n\nAfter the pricing/licensing overhaul (Azure Managed Application), dead-code cleanup (-983 lines), and website UX pass, this audit examines the entire product from three leadership perspectives to identify gaps, risks, and priorities before the next development cycle.\n\n---\n\n## 1. Product Owner Perspective\n\n### Pricing & Positioning — CLEAN\n\n| Signal | Status |\n| ------------------------------------------------------------ | ---------------------------- |\n| Website pricing page (€0 / €0 / €150) | Correct |\n| Schema.org structured data | Correct |\n| Product comparison page | Correct |\n| Feature parity matrix (`docs/08-products/feature-parity.md`) | Correct |\n| README.md | Correct |\n| ADR-007 (distribution strategy) | Current (revised 2026-02-13) |\n| PWA install prompt copy | Current |\n\nNo stale €99/yr or license-key references remain in user-facing surfaces.\n\n### Documentation — STRONG\n\nAll 8 doc sections exist with indexes: vision (13 files), journeys (13), features (31), cases (8 dirs), technical (13), design system (28), decisions (8), products (16). Total: ~130 docs.\n\n### Case Studies — 5 of 7 READY\n\n| Case | Status | Data Files | Week |\n| ------------------- | ------ | ------------------------------------------------------ | ---- |\n| Bottleneck | Ready | `data.csv` | 1 |\n| Hospital Ward | Ready | `data.csv` | 5 |\n| Coffee | Ready | `washing-station.csv`, `moisture-grr.csv` | 9 |\n| Packaging | Ready | `defects.csv`, `fillweights.csv`, `fillweight-grr.csv` | 9 |\n| Avocado | Ready | `coating-regression.csv`, `coating-grr.csv` | 12 |\n| Machine Utilization | Stub | — | — |\n| Oven Zones | Stub | — | — |\n\n### Product Gaps\n\n| # | Gap | Severity |\n| --- | -------------------------------------------------------------------------------- | ----------- |\n| P1 | Azure Marketplace listing not live (upgrade URL is placeholder in `tier.ts:168`) | **BLOCKER** |\n| P2 | AppSource submission status unclear | HIGH |\n| P3 | 2 case studies are stubs (machine-utilization, oven-zones) | LOW |\n| P4 | Power BI product spec marked \"Planned — Not yet in development\" | LOW |\n| P5 | No analytics/telemetry for PWA usage or conversion | MEDIUM |\n\n---\n\n## 2. CTO Perspective\n\n### Architecture — SOLID\n\n- Clean monorepo layering: `core` → `charts`/`hooks`/`ui` → apps\n- No circular dependencies\n- Shared hooks (`useDataState`) eliminate ~460 lines of duplication\n- Props-based chart architecture (no context coupling)\n- TypeScript strict mode everywhere\n\n### Dependency Health — FIXED 2026-02-13\n\n| # | Issue | Resolution |\n| --- | -------------------------------------------------------------- | --------------------------------------------------------------- |\n| D1 | @visx version mismatch (Azure 3.3–3.5, others 3.12) | Aligned to ^3.12.0 |\n| D2 | lucide-react version spread (ui=0.330, azure=0.344, pwa=0.400) | Aligned to ^0.400.0, moved to peerDependencies in @variscout/ui |\n| D3 | Vitest version (Excel add-in 1.6 vs others 4.0) | Aligned to ^4.0.16 |\n| D4 | React version (Website 19.0, others 18.3) | Accepted — Astro islands handle this correctly |\n| D5 | d3 minor version (Azure 7.8.5 vs others 7.9.0) | Aligned to ^7.9.0 |\n\n### Test Coverage\n\n| Area | Test Files | Assessment |\n| ------------------- | -------------------------- | --------------- |\n| `@variscout/core` | 26 files (739 tests) | **Very Strong** |\n| `@variscout/charts` | 4 files (59 tests) | Moderate |\n| `@variscout/hooks` | 25 files (270 tests) | **Very Strong** |\n| `@variscout/ui` | 10 files (136 tests) | **Strong** |\n| PWA app | 10 files (100 tests) | **Strong** |\n| Azure app | 15 files (171 tests) | **Strong** |\n| Website | 0 | None |\n| **Total** | **90 files (1,475 tests)** | |\n\n### Technical Debt\n\n| # | Item | Severity |\n| --- | ------------------------------------------------------------------- | ------------------------------- |\n| T1 | ~~`edition.ts` deprecated but still used for branding logic~~ | RESOLVED |\n| T2 | ~~Excel add-in has stub `licenseDetection.ts` and `useLicense.ts`~~ | RESOLVED (Excel add-in deleted) |\n| T3 | TODO: Integrate funnel filters with FilterNavigation breadcrumbs | LOW |\n| T4 | TODO: Replace upgrade URL placeholder (`tier.ts:168`) | **HIGH** |\n| T5 | No CI/CD pipeline (`.github/workflows/` missing) | MEDIUM |\n\n### Security\n\n- pnpm overrides for known CVEs (qs, esbuild, lodash, tmp) (removed Feb 2026 — dependencies no longer in tree)\n- fast-xml-parser CVE fixed (pnpm override >=5.3.6 — 3 CVEs: 1 critical, 2 high)\n- No `.env` files or secrets in codebase\n- Offline-first architecture reduces attack surface\n\n---\n\n## 3. Head of Design Perspective\n\n### Design System Documentation — COMPREHENSIVE\n\n28 files covering foundations, components, charts, and patterns.\n\n### Color System — 4 SOURCES (coordinated but not unified)\n\n| Location | What | Used By |\n| ------------------------------------ | -------------------------- | ------------- |\n| `packages/charts/src/colors.ts` | Chart data + chrome colors | Charts |\n| `packages/ui/src/colors.ts` | Status + grade colors | UI components |\n| `apps/pwa/src/index.css` | CSS custom properties | PWA |\n| `apps/website/src/styles/global.css` | Tailwind v4 theme tokens | Website |\n\nValues are coordinated (status colors match) but no single source of truth.\n\n### Accessibility — IMPROVING\n\n| Area | Status |\n| ------------- | ------------------------------------------------------------------------------------ |\n| Documentation | Excellent (WCAG 2.1 AA targets) |\n| Website | Good (aria-labels, focus traps) |\n| Charts | Good (`role=\"img\"` + `aria-label` on IChart, Boxplot, Pareto) |\n| UI components | Good (`aria-live` on FilterBreadcrumb, DataQualityBanner, SyncToast, StatsPanelBase) |\n| PWA app | Moderate (skip link, semantic header/nav/footer, aria-labels) |\n| Landmarks | Present in PWA (header, nav, main, footer) and Azure (header, nav, main) |\n| Live regions | Present (FilterBreadcrumb, SyncToast, StatsPanelBase, InvestigationPrompt) |\n\n### Branding\n\n| Signal | Finding |\n| ----------- | -------------------------------------------------------------------------------------- |\n| Name casing | Website uses \"VaRiScout\" (71 instances, intentional stylization); PWA uses \"VariScout\" |\n| Taglines | Consistent across all surfaces |\n| Brand color | Consistent: `#2563eb` (blue-600) |\n\n### Design Gaps\n\n| # | Gap | Severity |\n| --- | --------------------------------------------------------------------------------- | -------- |\n| UX1 | Accessibility implementation far behind documentation | **HIGH** |\n| UX2 | Color system split across 4 files | MEDIUM |\n| UX3 | Brand name casing: \"VaRiScout\" (website) vs \"VariScout\" (PWA/docs) — intentional? | MEDIUM |\n| UX4 | PWA underuses responsive utilities | LOW |\n\n---\n\n## Combined Priority Matrix\n\n### Blockers\n\n| Issue | Owner |\n| --------------------------------------------- | ------------ |\n| P1: Azure Marketplace listing not live | PO |\n| D1+D2: Dependency mismatches → build failures | CTO ✅ Fixed |\n\n### High Priority\n\n| Issue | Owner |\n| ------------------------------------------------------------------ | ------ |\n| UX1: Accessibility — remaining gaps (keyboard nav, contrast audit) | Design |\n| P2: AppSource submission status | PO |\n| T4: Upgrade URL placeholder in `tier.ts` | CTO |\n\n### Medium Priority\n\n| Issue | Owner |\n| ---------------------------------------- | ------ |\n| UX2: Color system consolidation | Design |\n| UX3: Brand name standardization decision | Design |\n| P5: Usage analytics/telemetry | PO |\n| Test coverage expansion | CTO |\n\n### Low Priority\n\n| Issue | Owner |\n| ----------------------------- | ------ |\n| ~~T1: `edition.ts` cleanup~~ | DONE |\n| ~~T2: Excel stub files~~ | DONE |\n| T3: Funnel/breadcrumb TODO | CTO |\n| P3: 2 stub case studies | PO |\n| P4: Power BI spec visibility | PO |\n| D4: React version consistency | CTO |\n| UX4: PWA responsive usage | Design |\n\n---\n\n## What's Working Well\n\n- **Documentation**: 130+ docs, all current, no stale pricing\n- **Architecture**: Clean monorepo layering, shared hooks, props-based charts\n- **Core package**: 739 tests, strict TypeScript, solid statistics engine\n- **Pricing alignment**: Consistent across all surfaces\n- **Case studies**: 5 ready with data, mapped to content calendar\n- **Design system docs**: Comprehensive 28-file system\n- **Offline-first**: No backend dependency, data stays local\n- **Recent cleanup**: 983 lines of dead code removed", + "src/content/docs/07-decisions/audit-2026-02-state-of-product.md", + "d753b9d880e4c712", + { "html": 3046, "metadata": 3047 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"state-of-the-product-audit--february-2026\">State-of-the-Product Audit — February 2026\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#state-of-the-product-audit--february-2026\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “State-of-the-Product Audit — February 2026”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2026-02-13\n\u003Cstrong>Scope\u003C/strong>: Full codebase, all docs, all packages and apps\n\u003Cstrong>Method\u003C/strong>: Automated exhaustive exploration (not sampling)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"context\">Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After the pricing/licensing overhaul (Azure Managed Application), dead-code cleanup (-983 lines), and website UX pass, this audit examines the entire product from three leadership perspectives to identify gaps, risks, and priorities before the next development cycle.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"1-product-owner-perspective\">1. Product Owner Perspective\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#1-product-owner-perspective\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Product Owner Perspective”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pricing--positioning--clean\">Pricing & Positioning — CLEAN\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pricing--positioning--clean\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pricing & Positioning — CLEAN”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Signal\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Website pricing page (€0 / €0 / €150)\u003C/td>\u003Ctd>Correct\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Schema.org structured data\u003C/td>\u003Ctd>Correct\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Product comparison page\u003C/td>\u003Ctd>Correct\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Feature parity matrix (\u003Ccode dir=\"auto\">docs/08-products/feature-parity.md\u003C/code>)\u003C/td>\u003Ctd>Correct\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>README.md\u003C/td>\u003Ctd>Correct\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ADR-007 (distribution strategy)\u003C/td>\u003Ctd>Current (revised 2026-02-13)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PWA install prompt copy\u003C/td>\u003Ctd>Current\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>No stale €99/yr or license-key references remain in user-facing surfaces.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"documentation--strong\">Documentation — STRONG\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#documentation--strong\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Documentation — STRONG”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All 8 doc sections exist with indexes: vision (13 files), journeys (13), features (31), cases (8 dirs), technical (13), design system (28), decisions (8), products (16). Total: ~130 docs.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"case-studies--5-of-7-ready\">Case Studies — 5 of 7 READY\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#case-studies--5-of-7-ready\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Case Studies — 5 of 7 READY”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Case\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Data Files\u003C/th>\u003Cth>Week\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>Ready\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">data.csv\u003C/code>\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hospital Ward\u003C/td>\u003Ctd>Ready\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">data.csv\u003C/code>\u003C/td>\u003Ctd>5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Coffee\u003C/td>\u003Ctd>Ready\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">washing-station.csv\u003C/code>, \u003Ccode dir=\"auto\">moisture-grr.csv\u003C/code>\u003C/td>\u003Ctd>9\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Packaging\u003C/td>\u003Ctd>Ready\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">defects.csv\u003C/code>, \u003Ccode dir=\"auto\">fillweights.csv\u003C/code>, \u003Ccode dir=\"auto\">fillweight-grr.csv\u003C/code>\u003C/td>\u003Ctd>9\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Avocado\u003C/td>\u003Ctd>Ready\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">coating-regression.csv\u003C/code>, \u003Ccode dir=\"auto\">coating-grr.csv\u003C/code>\u003C/td>\u003Ctd>12\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Machine Utilization\u003C/td>\u003Ctd>Stub\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Oven Zones\u003C/td>\u003Ctd>Stub\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"product-gaps\">Product Gaps\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#product-gaps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Gaps”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Gap\u003C/th>\u003Cth>Severity\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>P1\u003C/td>\u003Ctd>Azure Marketplace listing not live (upgrade URL is placeholder in \u003Ccode dir=\"auto\">tier.ts:168\u003C/code>)\u003C/td>\u003Ctd>\u003Cstrong>BLOCKER\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>P2\u003C/td>\u003Ctd>AppSource submission status unclear\u003C/td>\u003Ctd>HIGH\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>P3\u003C/td>\u003Ctd>2 case studies are stubs (machine-utilization, oven-zones)\u003C/td>\u003Ctd>LOW\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>P4\u003C/td>\u003Ctd>Power BI product spec marked “Planned — Not yet in development”\u003C/td>\u003Ctd>LOW\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>P5\u003C/td>\u003Ctd>No analytics/telemetry for PWA usage or conversion\u003C/td>\u003Ctd>MEDIUM\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"2-cto-perspective\">2. CTO Perspective\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#2-cto-perspective\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. CTO Perspective”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"architecture--solid\">Architecture — SOLID\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#architecture--solid\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture — SOLID”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Clean monorepo layering: \u003Ccode dir=\"auto\">core\u003C/code> → \u003Ccode dir=\"auto\">charts\u003C/code>/\u003Ccode dir=\"auto\">hooks\u003C/code>/\u003Ccode dir=\"auto\">ui\u003C/code> → apps\u003C/li>\n\u003Cli>No circular dependencies\u003C/li>\n\u003Cli>Shared hooks (\u003Ccode dir=\"auto\">useDataState\u003C/code>) eliminate ~460 lines of duplication\u003C/li>\n\u003Cli>Props-based chart architecture (no context coupling)\u003C/li>\n\u003Cli>TypeScript strict mode everywhere\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"dependency-health--fixed-2026-02-13\">Dependency Health — FIXED 2026-02-13\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#dependency-health--fixed-2026-02-13\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dependency Health — FIXED 2026-02-13”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Issue\u003C/th>\u003Cth>Resolution\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>D1\u003C/td>\u003Ctd>@visx version mismatch (Azure 3.3–3.5, others 3.12)\u003C/td>\u003Ctd>Aligned to ^3.12.0\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>D2\u003C/td>\u003Ctd>lucide-react version spread (ui=0.330, azure=0.344, pwa=0.400)\u003C/td>\u003Ctd>Aligned to ^0.400.0, moved to peerDependencies in @variscout/ui\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>D3\u003C/td>\u003Ctd>Vitest version (Excel add-in 1.6 vs others 4.0)\u003C/td>\u003Ctd>Aligned to ^4.0.16\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>D4\u003C/td>\u003Ctd>React version (Website 19.0, others 18.3)\u003C/td>\u003Ctd>Accepted — Astro islands handle this correctly\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>D5\u003C/td>\u003Ctd>d3 minor version (Azure 7.8.5 vs others 7.9.0)\u003C/td>\u003Ctd>Aligned to ^7.9.0\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"test-coverage\">Test Coverage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#test-coverage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Test Coverage”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Area\u003C/th>\u003Cth>Test Files\u003C/th>\u003Cth>Assessment\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/td>\u003Ctd>26 files (739 tests)\u003C/td>\u003Ctd>\u003Cstrong>Very Strong\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/td>\u003Ctd>4 files (59 tests)\u003C/td>\u003Ctd>Moderate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003Ctd>25 files (270 tests)\u003C/td>\u003Ctd>\u003Cstrong>Very Strong\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>10 files (136 tests)\u003C/td>\u003Ctd>\u003Cstrong>Strong\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PWA app\u003C/td>\u003Ctd>10 files (100 tests)\u003C/td>\u003Ctd>\u003Cstrong>Strong\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure app\u003C/td>\u003Ctd>15 files (171 tests)\u003C/td>\u003Ctd>\u003Cstrong>Strong\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Website\u003C/td>\u003Ctd>0\u003C/td>\u003Ctd>None\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>90 files (1,475 tests)\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"technical-debt\">Technical Debt\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#technical-debt\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Debt”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Item\u003C/th>\u003Cth>Severity\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>T1\u003C/td>\u003Ctd>\u003Cdel>\u003Ccode dir=\"auto\">edition.ts\u003C/code> deprecated but still used for branding logic\u003C/del>\u003C/td>\u003Ctd>RESOLVED\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>T2\u003C/td>\u003Ctd>\u003Cdel>Excel add-in has stub \u003Ccode dir=\"auto\">licenseDetection.ts\u003C/code> and \u003Ccode dir=\"auto\">useLicense.ts\u003C/code>\u003C/del>\u003C/td>\u003Ctd>RESOLVED (Excel add-in deleted)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>T3\u003C/td>\u003Ctd>TODO: Integrate funnel filters with FilterNavigation breadcrumbs\u003C/td>\u003Ctd>LOW\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>T4\u003C/td>\u003Ctd>TODO: Replace upgrade URL placeholder (\u003Ccode dir=\"auto\">tier.ts:168\u003C/code>)\u003C/td>\u003Ctd>\u003Cstrong>HIGH\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>T5\u003C/td>\u003Ctd>No CI/CD pipeline (\u003Ccode dir=\"auto\">.github/workflows/\u003C/code> missing)\u003C/td>\u003Ctd>MEDIUM\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"security\">Security\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#security\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>pnpm overrides for known CVEs (qs, esbuild, lodash, tmp) (removed Feb 2026 — dependencies no longer in tree)\u003C/li>\n\u003Cli>fast-xml-parser CVE fixed (pnpm override >=5.3.6 — 3 CVEs: 1 critical, 2 high)\u003C/li>\n\u003Cli>No \u003Ccode dir=\"auto\">.env\u003C/code> files or secrets in codebase\u003C/li>\n\u003Cli>Offline-first architecture reduces attack surface\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"3-head-of-design-perspective\">3. Head of Design Perspective\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#3-head-of-design-perspective\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Head of Design Perspective”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"design-system-documentation--comprehensive\">Design System Documentation — COMPREHENSIVE\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#design-system-documentation--comprehensive\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design System Documentation — COMPREHENSIVE”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>28 files covering foundations, components, charts, and patterns.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"color-system--4-sources-coordinated-but-not-unified\">Color System — 4 SOURCES (coordinated but not unified)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#color-system--4-sources-coordinated-but-not-unified\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color System — 4 SOURCES (coordinated but not unified)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Location\u003C/th>\u003Cth>What\u003C/th>\u003Cth>Used By\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/charts/src/colors.ts\u003C/code>\u003C/td>\u003Ctd>Chart data + chrome colors\u003C/td>\u003Ctd>Charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/colors.ts\u003C/code>\u003C/td>\u003Ctd>Status + grade colors\u003C/td>\u003Ctd>UI components\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/index.css\u003C/code>\u003C/td>\u003Ctd>CSS custom properties\u003C/td>\u003Ctd>PWA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">apps/website/src/styles/global.css\u003C/code>\u003C/td>\u003Ctd>Tailwind v4 theme tokens\u003C/td>\u003Ctd>Website\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Values are coordinated (status colors match) but no single source of truth.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"accessibility--improving\">Accessibility — IMPROVING\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#accessibility--improving\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Accessibility — IMPROVING”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Area\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Documentation\u003C/td>\u003Ctd>Excellent (WCAG 2.1 AA targets)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Website\u003C/td>\u003Ctd>Good (aria-labels, focus traps)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Charts\u003C/td>\u003Ctd>Good (\u003Ccode dir=\"auto\">role=\"img\"\u003C/code> + \u003Ccode dir=\"auto\">aria-label\u003C/code> on IChart, Boxplot, Pareto)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UI components\u003C/td>\u003Ctd>Good (\u003Ccode dir=\"auto\">aria-live\u003C/code> on FilterBreadcrumb, DataQualityBanner, SyncToast, StatsPanelBase)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PWA app\u003C/td>\u003Ctd>Moderate (skip link, semantic header/nav/footer, aria-labels)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Landmarks\u003C/td>\u003Ctd>Present in PWA (header, nav, main, footer) and Azure (header, nav, main)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Live regions\u003C/td>\u003Ctd>Present (FilterBreadcrumb, SyncToast, StatsPanelBase, InvestigationPrompt)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"branding\">Branding\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#branding\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Branding”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Signal\u003C/th>\u003Cth>Finding\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Name casing\u003C/td>\u003Ctd>Website uses “VaRiScout” (71 instances, intentional stylization); PWA uses “VariScout”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Taglines\u003C/td>\u003Ctd>Consistent across all surfaces\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Brand color\u003C/td>\u003Ctd>Consistent: \u003Ccode dir=\"auto\">#2563eb\u003C/code> (blue-600)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"design-gaps\">Design Gaps\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#design-gaps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Gaps”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Gap\u003C/th>\u003Cth>Severity\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>UX1\u003C/td>\u003Ctd>Accessibility implementation far behind documentation\u003C/td>\u003Ctd>\u003Cstrong>HIGH\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UX2\u003C/td>\u003Ctd>Color system split across 4 files\u003C/td>\u003Ctd>MEDIUM\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UX3\u003C/td>\u003Ctd>Brand name casing: “VaRiScout” (website) vs “VariScout” (PWA/docs) — intentional?\u003C/td>\u003Ctd>MEDIUM\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UX4\u003C/td>\u003Ctd>PWA underuses responsive utilities\u003C/td>\u003Ctd>LOW\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"combined-priority-matrix\">Combined Priority Matrix\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#combined-priority-matrix\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Combined Priority Matrix”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"blockers\">Blockers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#blockers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Blockers”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Issue\u003C/th>\u003Cth>Owner\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>P1: Azure Marketplace listing not live\u003C/td>\u003Ctd>PO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>D1+D2: Dependency mismatches → build failures\u003C/td>\u003Ctd>CTO ✅ Fixed\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"high-priority\">High Priority\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#high-priority\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “High Priority”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Issue\u003C/th>\u003Cth>Owner\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>UX1: Accessibility — remaining gaps (keyboard nav, contrast audit)\u003C/td>\u003Ctd>Design\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>P2: AppSource submission status\u003C/td>\u003Ctd>PO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>T4: Upgrade URL placeholder in \u003Ccode dir=\"auto\">tier.ts\u003C/code>\u003C/td>\u003Ctd>CTO\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"medium-priority\">Medium Priority\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#medium-priority\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Medium Priority”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Issue\u003C/th>\u003Cth>Owner\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>UX2: Color system consolidation\u003C/td>\u003Ctd>Design\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UX3: Brand name standardization decision\u003C/td>\u003Ctd>Design\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>P5: Usage analytics/telemetry\u003C/td>\u003Ctd>PO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Test coverage expansion\u003C/td>\u003Ctd>CTO\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"low-priority\">Low Priority\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#low-priority\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Low Priority”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Issue\u003C/th>\u003Cth>Owner\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cdel>T1: \u003Ccode dir=\"auto\">edition.ts\u003C/code> cleanup\u003C/del>\u003C/td>\u003Ctd>DONE\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cdel>T2: Excel stub files\u003C/del>\u003C/td>\u003Ctd>DONE\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>T3: Funnel/breadcrumb TODO\u003C/td>\u003Ctd>CTO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>P3: 2 stub case studies\u003C/td>\u003Ctd>PO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>P4: Power BI spec visibility\u003C/td>\u003Ctd>PO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>D4: React version consistency\u003C/td>\u003Ctd>CTO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UX4: PWA responsive usage\u003C/td>\u003Ctd>Design\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whats-working-well\">What’s Working Well\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whats-working-well\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What’s Working Well”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Documentation\u003C/strong>: 130+ docs, all current, no stale pricing\u003C/li>\n\u003Cli>\u003Cstrong>Architecture\u003C/strong>: Clean monorepo layering, shared hooks, props-based charts\u003C/li>\n\u003Cli>\u003Cstrong>Core package\u003C/strong>: 739 tests, strict TypeScript, solid statistics engine\u003C/li>\n\u003Cli>\u003Cstrong>Pricing alignment\u003C/strong>: Consistent across all surfaces\u003C/li>\n\u003Cli>\u003Cstrong>Case studies\u003C/strong>: 5 ready with data, mapped to content calendar\u003C/li>\n\u003Cli>\u003Cstrong>Design system docs\u003C/strong>: Comprehensive 28-file system\u003C/li>\n\u003Cli>\u003Cstrong>Offline-first\u003C/strong>: No backend dependency, data stays local\u003C/li>\n\u003Cli>\u003Cstrong>Recent cleanup\u003C/strong>: 983 lines of dead code removed\u003C/li>\n\u003C/ul>", + { + "headings": 3048, + "localImagePaths": 3121, + "remoteImagePaths": 3122, + "frontmatter": 3123, + "imagePaths": 3124 + }, + [ + 3049, 3051, 3052, 3055, 3058, 3061, 3064, 3067, 3070, 3073, 3076, 3079, 3082, 3085, 3088, 3091, + 3094, 3097, 3100, 3103, 3106, 3109, 3112, 3115, 3118 + ], + { "depth": 30, "slug": 3050, "text": 3038 }, + "state-of-the-product-audit--february-2026", + { "depth": 33, "slug": 628, "text": 629 }, + { "depth": 33, "slug": 3053, "text": 3054 }, + "1-product-owner-perspective", + "1. Product Owner Perspective", + { "depth": 79, "slug": 3056, "text": 3057 }, + "pricing--positioning--clean", + "Pricing & Positioning — CLEAN", + { "depth": 79, "slug": 3059, "text": 3060 }, + "documentation--strong", + "Documentation — STRONG", + { "depth": 79, "slug": 3062, "text": 3063 }, + "case-studies--5-of-7-ready", + "Case Studies — 5 of 7 READY", + { "depth": 79, "slug": 3065, "text": 3066 }, + "product-gaps", + "Product Gaps", + { "depth": 33, "slug": 3068, "text": 3069 }, + "2-cto-perspective", + "2. CTO Perspective", + { "depth": 79, "slug": 3071, "text": 3072 }, + "architecture--solid", + "Architecture — SOLID", + { "depth": 79, "slug": 3074, "text": 3075 }, + "dependency-health--fixed-2026-02-13", + "Dependency Health — FIXED 2026-02-13", + { "depth": 79, "slug": 3077, "text": 3078 }, + "test-coverage", + "Test Coverage", + { "depth": 79, "slug": 3080, "text": 3081 }, + "technical-debt", + "Technical Debt", + { "depth": 79, "slug": 3083, "text": 3084 }, + "security", + "Security", + { "depth": 33, "slug": 3086, "text": 3087 }, + "3-head-of-design-perspective", + "3. Head of Design Perspective", + { "depth": 79, "slug": 3089, "text": 3090 }, + "design-system-documentation--comprehensive", + "Design System Documentation — COMPREHENSIVE", + { "depth": 79, "slug": 3092, "text": 3093 }, + "color-system--4-sources-coordinated-but-not-unified", + "Color System — 4 SOURCES (coordinated but not unified)", + { "depth": 79, "slug": 3095, "text": 3096 }, + "accessibility--improving", + "Accessibility — IMPROVING", + { "depth": 79, "slug": 3098, "text": 3099 }, + "branding", + "Branding", + { "depth": 79, "slug": 3101, "text": 3102 }, + "design-gaps", + "Design Gaps", + { "depth": 33, "slug": 3104, "text": 3105 }, + "combined-priority-matrix", + "Combined Priority Matrix", + { "depth": 79, "slug": 3107, "text": 3108 }, + "blockers", + "Blockers", + { "depth": 79, "slug": 3110, "text": 3111 }, + "high-priority", + "High Priority", + { "depth": 79, "slug": 3113, "text": 3114 }, + "medium-priority", + "Medium Priority", + { "depth": 79, "slug": 3116, "text": 3117 }, + "low-priority", + "Low Priority", + { "depth": 33, "slug": 3119, "text": 3120 }, + "whats-working-well", + "What’s Working Well", + [], + [], + { "title": 3038 }, + [], + "07-decisions", + { "id": 3125, "data": 3127, "body": 3132, "filePath": 3133, "digest": 3134, "rendered": 3135 }, + { + "title": 3128, + "editUrl": 16, + "head": 3129, + "template": 18, + "sidebar": 3130, + "pagefind": 16, + "draft": 20 + }, + "Architecture Decision Records", + [], + { "hidden": 20, "attrs": 3131 }, + {}, + "# Architecture Decision Records\n\nThis section captures key architectural decisions made during VariScout development. Each decision includes context, the decision made, and consequences.\n\n---\n\n## Decision Log\n\n| ID | Title | Status | Date |\n| ---------------------------------------------------- | ------------------------------------ | ---------- | ---------- |\n| [001](adr-001-monorepo.md) | Monorepo with pnpm | Accepted | 2024-01-15 |\n| [002](adr-002-visx-charts.md) | Visx for Charts | Accepted | 2024-01-20 |\n| [003](adr-003-indexeddb.md) | IndexedDB for Storage | Accepted | 2024-02-01 |\n| [004](adr-004-offline-first.md) | Offline-First | Accepted | 2024-02-05 |\n| [005](adr-005-props-based-charts.md) | Props-Based Charts | Accepted | 2024-02-15 |\n| [006](adr-006-edition-system.md) | Edition System | Superseded | 2024-03-01 |\n| [007](adr-007-azure-marketplace-distribution.md) | Azure Marketplace Distribution | Accepted | 2026-02-05 |\n| [008](adr-008-website-content-architecture.md) | Website Content Architecture | Accepted | 2026-02-13 |\n| [009](adr-009-boxplot-violin-mode.md) | Boxplot Violin Mode | Accepted | 2026-02-16 |\n| [010](adr-010-gagerr-deferral.md) | Gage R&R Deferral | Superseded | 2026-02-16 |\n| [011](adr-011-ai-development-tooling.md) | AI Development Tooling | Accepted | 2026-02-18 |\n| [012](adr-012-pwa-browser-only.md) | PWA Browser-Only, Zero Data | Accepted | 2026-02-18 |\n| [013](adr-013-architecture-evaluation-ddd-swarms.md) | Architecture Evaluation (DDD/Swarms) | Accepted | 2026-02-18 |\n| [014](adr-014-regression-deferral.md) | Defer Regression to Phase 2 | Accepted | 2026-02-25 |\n| [015](adr-015-investigation-board.md) | Investigation Board | Accepted | 2026-02-26 |\n| [016](adr-016-teams-integration.md) | Teams Integration | Proposed | 2026-02-27 |\n| [017](adr-017-fluent-design-alignment.md) | Fluent 2 Design Principle Alignment | Accepted | 2026-03-02 |\n| [018](adr-018-channel-mention-workflow.md) | Channel @Mention Workflow | Proposed | 2026-03-02 |\n\n---\n\n## ADR Dependency Map\n\n```mermaid\nflowchart TB\n subgraph Architecture[\"Architecture\"]\n ADR001[\"001 Monorepo\"]\n ADR004[\"004 Offline-First\"]\n ADR011[\"011 AI Tooling\"]\n ADR013[\"013 DDD/Swarms\"]\n ADR001 --> ADR013\n end\n\n subgraph Charts[\"Charts & UI\"]\n ADR002[\"002 Visx Charts\"]\n ADR005[\"005 Props-Based\"]\n ADR009[\"009 Violin Mode\"]\n ADR017[\"017 Fluent 2\"]\n ADR002 --> ADR005\n ADR005 --> ADR009\n end\n\n subgraph Storage[\"Storage\"]\n ADR003[\"003 IndexedDB\"]\n ADR012[\"012 PWA Browser-Only\"]\n ADR003 --> ADR004\n ADR004 --> ADR012\n end\n\n subgraph Distribution[\"Distribution\"]\n ADR006[\"006 Edition System\"]\n ADR007[\"007 Azure Marketplace\"]\n ADR008[\"008 Website Architecture\"]\n ADR006 -.->|superseded| ADR007\n end\n\n subgraph Features[\"Features\"]\n ADR010[\"010 Gage R&R\"]\n ADR014[\"014 Regression Deferral\"]\n ADR015[\"015 Investigation Board\"]\n end\n\n subgraph Teams[\"Teams Platform\"]\n ADR016[\"016 Teams Integration\"]\n ADR018[\"018 Channel @Mention\"]\n ADR007 --> ADR016\n ADR015 --> ADR016\n ADR016 --> ADR018\n ADR015 --> ADR018\n end\n\n style ADR006 fill:#94a3b8,color:#fff\n style ADR010 fill:#94a3b8,color:#fff\n```\n\nSee also: [Documentation Methodology — ADR Dependency Map](../05-technical/documentation-methodology.md#adr-dependency-map) for the full methodology context.\n\n---\n\n## ADR Template\n\nWhen adding new decisions, use this template:\n\n```markdown\n# ADR-XXX: Title\n\n**Status**: Proposed | Accepted | Deprecated | Superseded by ADR-XXX\n\n**Date**: YYYY-MM-DD\n\n## Context\n\nWhat is the issue we're addressing?\n\n## Decision\n\nWhat is the change we're proposing?\n\n## Consequences\n\nWhat becomes easier or harder as a result?\n```\n\n---\n\n## Other Documents\n\n| Document | Description |\n| ---------------------------------------------------------------------- | ------------------------------------ |\n| [State of Product Audit (Feb 2026)](audit-2026-02-state-of-product.md) | Comprehensive product audit snapshot |", + "src/content/docs/07-decisions/index.md", + "ca099c5d4d96186f", + { "html": 3136, "metadata": 3137 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"architecture-decision-records\">Architecture Decision Records\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#architecture-decision-records\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture Decision Records”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This section captures key architectural decisions made during VariScout development. Each decision includes context, the decision made, and consequences.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision-log\">Decision Log\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision-log\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision Log”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>ID\u003C/th>\u003Cth>Title\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Date\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-001-monorepo.md\">001\u003C/a>\u003C/td>\u003Ctd>Monorepo with pnpm\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2024-01-15\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-002-visx-charts.md\">002\u003C/a>\u003C/td>\u003Ctd>Visx for Charts\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2024-01-20\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-003-indexeddb.md\">003\u003C/a>\u003C/td>\u003Ctd>IndexedDB for Storage\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2024-02-01\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-004-offline-first.md\">004\u003C/a>\u003C/td>\u003Ctd>Offline-First\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2024-02-05\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-005-props-based-charts.md\">005\u003C/a>\u003C/td>\u003Ctd>Props-Based Charts\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2024-02-15\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-006-edition-system.md\">006\u003C/a>\u003C/td>\u003Ctd>Edition System\u003C/td>\u003Ctd>Superseded\u003C/td>\u003Ctd>2024-03-01\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-007-azure-marketplace-distribution.md\">007\u003C/a>\u003C/td>\u003Ctd>Azure Marketplace Distribution\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2026-02-05\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-008-website-content-architecture.md\">008\u003C/a>\u003C/td>\u003Ctd>Website Content Architecture\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2026-02-13\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-009-boxplot-violin-mode.md\">009\u003C/a>\u003C/td>\u003Ctd>Boxplot Violin Mode\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2026-02-16\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-010-gagerr-deferral.md\">010\u003C/a>\u003C/td>\u003Ctd>Gage R&R Deferral\u003C/td>\u003Ctd>Superseded\u003C/td>\u003Ctd>2026-02-16\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-011-ai-development-tooling.md\">011\u003C/a>\u003C/td>\u003Ctd>AI Development Tooling\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2026-02-18\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-012-pwa-browser-only.md\">012\u003C/a>\u003C/td>\u003Ctd>PWA Browser-Only, Zero Data\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2026-02-18\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-013-architecture-evaluation-ddd-swarms.md\">013\u003C/a>\u003C/td>\u003Ctd>Architecture Evaluation (DDD/Swarms)\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2026-02-18\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-014-regression-deferral.md\">014\u003C/a>\u003C/td>\u003Ctd>Defer Regression to Phase 2\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2026-02-25\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-015-investigation-board.md\">015\u003C/a>\u003C/td>\u003Ctd>Investigation Board\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2026-02-26\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-016-teams-integration.md\">016\u003C/a>\u003C/td>\u003Ctd>Teams Integration\u003C/td>\u003Ctd>Proposed\u003C/td>\u003Ctd>2026-02-27\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-017-fluent-design-alignment.md\">017\u003C/a>\u003C/td>\u003Ctd>Fluent 2 Design Principle Alignment\u003C/td>\u003Ctd>Accepted\u003C/td>\u003Ctd>2026-03-02\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"adr-018-channel-mention-workflow.md\">018\u003C/a>\u003C/td>\u003Ctd>Channel @Mention Workflow\u003C/td>\u003Ctd>Proposed\u003C/td>\u003Ctd>2026-03-02\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"adr-dependency-map\">ADR Dependency Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#adr-dependency-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR Dependency Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph Architecture[\"Architecture\"]\n ADR001[\"001 Monorepo\"]\n ADR004[\"004 Offline-First\"]\n ADR011[\"011 AI Tooling\"]\n ADR013[\"013 DDD/Swarms\"]\n ADR001 --> ADR013\n end\n\n subgraph Charts[\"Charts & UI\"]\n ADR002[\"002 Visx Charts\"]\n ADR005[\"005 Props-Based\"]\n ADR009[\"009 Violin Mode\"]\n ADR017[\"017 Fluent 2\"]\n ADR002 --> ADR005\n ADR005 --> ADR009\n end\n\n subgraph Storage[\"Storage\"]\n ADR003[\"003 IndexedDB\"]\n ADR012[\"012 PWA Browser-Only\"]\n ADR003 --> ADR004\n ADR004 --> ADR012\n end\n\n subgraph Distribution[\"Distribution\"]\n ADR006[\"006 Edition System\"]\n ADR007[\"007 Azure Marketplace\"]\n ADR008[\"008 Website Architecture\"]\n ADR006 -.->|superseded| ADR007\n end\n\n subgraph Features[\"Features\"]\n ADR010[\"010 Gage R&R\"]\n ADR014[\"014 Regression Deferral\"]\n ADR015[\"015 Investigation Board\"]\n end\n\n subgraph Teams[\"Teams Platform\"]\n ADR016[\"016 Teams Integration\"]\n ADR018[\"018 Channel @Mention\"]\n ADR007 --> ADR016\n ADR015 --> ADR016\n ADR016 --> ADR018\n ADR015 --> ADR018\n end\n\n style ADR006 fill:#94a3b8,color:#fff\n style ADR010 fill:#94a3b8,color:#fff\n\u003C/pre>\n\u003Cp>See also: \u003Ca href=\"../05-technical/documentation-methodology.md#adr-dependency-map\">Documentation Methodology — ADR Dependency Map\u003C/a> for the full methodology context.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"adr-template\">ADR Template\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#adr-template\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ADR Template”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When adding new decisions, use this template:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"markdown\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82B1FF;--1:#3B61B0\"># ADR-XXX: Title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#C5E478;--0fw:bold;--1:#3B61B0;--1fw:bold\">Status\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: Proposed | Accepted | Deprecated | Superseded by ADR-XXX\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#C5E478;--0fw:bold;--1:#3B61B0;--1fw:bold\">Date\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: YYYY-MM-DD\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82B1FF;--1:#3B61B0\">## Context\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">What is the issue we're addressing?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82B1FF;--1:#3B61B0\">## Decision\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">What is the change we're proposing?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82B1FF;--1:#3B61B0\">## Consequences\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">What becomes easier or harder as a result?\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"# ADR-XXX: Title**Status**: Proposed | Accepted | Deprecated | Superseded by ADR-XXX**Date**: YYYY-MM-DD## ContextWhat is the issue we're addressing?## DecisionWhat is the change we're proposing?## ConsequencesWhat becomes easier or harder as a result?\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"other-documents\">Other Documents\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#other-documents\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Other Documents”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Document\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"audit-2026-02-state-of-product.md\">State of Product Audit (Feb 2026)\u003C/a>\u003C/td>\u003Ctd>Comprehensive product audit snapshot\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 3138, + "localImagePaths": 3151, + "remoteImagePaths": 3152, + "frontmatter": 3153, + "imagePaths": 3154 + }, + [3139, 3141, 3144, 3145, 3148], + { "depth": 30, "slug": 3140, "text": 3128 }, + "architecture-decision-records", + { "depth": 33, "slug": 3142, "text": 3143 }, + "decision-log", + "Decision Log", + { "depth": 33, "slug": 143, "text": 144 }, + { "depth": 33, "slug": 3146, "text": 3147 }, + "adr-template", + "ADR Template", + { "depth": 33, "slug": 3149, "text": 3150 }, + "other-documents", + "Other Documents", + [], + [], + { "title": 3128 }, + [], + "archive/brushing-usage-example", + { "id": 3155, "data": 3157, "body": 3162, "filePath": 3163, "digest": 3164, "rendered": 3165 }, + { + "title": 3158, + "editUrl": 16, + "head": 3159, + "template": 18, + "sidebar": 3160, + "pagefind": 16, + "draft": 20 + }, + "Minitab-Style Brushing - Usage Example", + [], + { "hidden": 20, "attrs": 3161 }, + {}, + "> **ARCHIVED**: This document describes historical implementation details. Do not reference for current work.\n\n# Minitab-Style Brushing - Usage Example\n\n## Quick Start\n\n### 1. Enable Brushing in Dashboard\n\n```tsx\n// apps/pwa/src/components/Dashboard.tsx\nimport { useData } from '../context/DataContext';\nimport { IChart } from '@variscout/charts';\n\nconst Dashboard = () => {\n const { filteredData, outcome, stats, specs, selectedPoints, setSelectedPoints, clearSelection } =\n useData();\n\n // Transform data for IChart\n const chartData = filteredData.map((row, i) => ({\n x: i,\n y: row[outcome] as number,\n originalIndex: i,\n }));\n\n return (\n \u003Cdiv>\n {/* Selection count badge */}\n {selectedPoints.size > 0 && (\n \u003Cdiv className=\"mb-4 flex items-center gap-2\">\n \u003Cspan className=\"rounded bg-blue-500 px-3 py-1 text-sm text-white\">\n {selectedPoints.size} point{selectedPoints.size > 1 ? 's' : ''} selected\n \u003C/span>\n \u003Cbutton onClick={clearSelection} className=\"text-sm text-slate-400 hover:text-slate-200\">\n Clear\n \u003C/button>\n \u003C/div>\n )}\n\n {/* I-Chart with brushing enabled */}\n \u003CIChart\n data={chartData}\n stats={stats}\n specs={specs}\n enableBrushSelection={true}\n selectedPoints={selectedPoints}\n onSelectionChange={indices => setSelectedPoints(indices)}\n parentWidth={800}\n parentHeight={400}\n yAxisLabel={outcome || 'Value'}\n />\n \u003C/div>\n );\n};\n```\n\n### 2. Interaction Patterns\n\n#### Rectangular Brush Selection\n\n```\n1. Click and drag on chart to draw selection rectangle\n2. Release mouse to select all points within rectangle\n3. Selected points: larger (6px), white stroke, full opacity\n4. Unselected points: dimmed (0.3 opacity)\n```\n\n#### Modifier Key Interactions\n\n```\nCtrl+Click: Toggle individual point\n - Point selected? → Remove from selection\n - Point not selected? → Add to selection\n\nShift+Click: Add point to selection\n - Always adds point without removing others\n\nRegular Click: Replace selection\n - Clears existing selection\n - Selects only the clicked point\n```\n\n### 3. Visual Feedback\n\n#### Default State (No Selection)\n\n```\nAll points:\n - Radius: 4px\n - Opacity: 1.0\n - Stroke: Default (1px)\n - Color: Semantic (red/green/amber/blue)\n```\n\n#### Active Selection\n\n```\nSelected points:\n - Radius: 6px (+2px)\n - Opacity: 1.0\n - Stroke: 2px white\n - Color: Maintains semantic meaning\n\nUnselected points:\n - Radius: 4px\n - Opacity: 0.3 (dimmed)\n - Stroke: Default (1px)\n - Color: Dimmed semantic color\n```\n\n#### Brush Rectangle (During Selection)\n\n```\nFill: rgba(59, 130, 246, 0.1) // Blue, 10% opacity\nStroke: rgba(59, 130, 246, 0.5) // Blue, 50% opacity\nWidth: 1.5px\nCursor: crosshair\n```\n\n### 4. Advanced Usage - Custom Selection Actions\n\n```tsx\nconst Dashboard = () => {\n const { filteredData, selectedPoints, setSelectedPoints, clearSelection, setFilters, filters } =\n useData();\n\n // Filter to show only selected points\n const filterToSelection = () => {\n if (selectedPoints.size === 0) return;\n\n // Get selected row IDs (if you have a unique ID column)\n const selectedIds = Array.from(selectedPoints).map(i => filteredData[i].id);\n\n setFilters({\n ...filters,\n id: selectedIds, // Assuming 'id' is a column\n });\n\n clearSelection();\n };\n\n // Export selected points to CSV\n const exportSelection = () => {\n if (selectedPoints.size === 0) return;\n\n const selectedRows = Array.from(selectedPoints).map(i => filteredData[i]);\n\n const csv = [\n Object.keys(selectedRows[0]).join(','),\n ...selectedRows.map(row => Object.values(row).join(',')),\n ].join('\\n');\n\n const blob = new Blob([csv], { type: 'text/csv' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'selected_points.csv';\n a.click();\n };\n\n // Highlight outliers automatically\n const selectOutliers = () => {\n const indices = new Set\u003Cnumber>();\n\n filteredData.forEach((row, i) => {\n const value = row[outcome] as number;\n if (\n (specs.usl !== undefined && value > specs.usl) ||\n (specs.lsl !== undefined && value \u003C specs.lsl)\n ) {\n indices.add(i);\n }\n });\n\n setSelectedPoints(indices);\n };\n\n return (\n \u003Cdiv>\n {/* Action buttons */}\n \u003Cdiv className=\"mb-4 flex gap-2\">\n \u003Cbutton onClick={selectOutliers}>Select Outliers\u003C/button>\n {selectedPoints.size > 0 && (\n \u003C>\n \u003Cbutton onClick={filterToSelection}>Filter to Selection ({selectedPoints.size})\u003C/button>\n \u003Cbutton onClick={exportSelection}>Export Selection\u003C/button>\n \u003C/>\n )}\n \u003C/div>\n\n \u003CIChart\n enableBrushSelection={true}\n selectedPoints={selectedPoints}\n onSelectionChange={setSelectedPoints}\n {...chartProps}\n />\n \u003C/div>\n );\n};\n```\n\n### 5. Cross-Chart Synchronization (Phase 2 - Pending)\n\n```tsx\n// Future: Selection syncs across all charts automatically\nconst Dashboard = () => {\n const { selectedPoints, setSelectedPoints } = useData();\n\n return (\n \u003Cdiv>\n {/* Selection persists across all charts */}\n \u003CIChart\n enableBrushSelection={true}\n selectedPoints={selectedPoints}\n onSelectionChange={setSelectedPoints}\n {...chartProps}\n />\n\n \u003CScatterPlot\n enableBrushSelection={true}\n selectedPoints={selectedPoints}\n onSelectionChange={setSelectedPoints}\n {...scatterProps}\n />\n\n \u003CBoxplot\n selectedGroups={getSelectedGroups(selectedPoints)}\n onBoxClick={handleBoxClick}\n {...boxplotProps}\n />\n \u003C/div>\n );\n};\n```\n\n### 6. Data Table Bi-Directional Sync (Phase 2 - Pending)\n\n```tsx\n// Future: Table row click updates chart selection\nconst DataTable = () => {\n const { filteredData, selectedPoints, addToSelection, togglePointSelection } = useData();\n\n return (\n \u003Ctable>\n {filteredData.map((row, i) => (\n \u003Ctr\n key={i}\n className={selectedPoints.has(i) ? 'bg-blue-100' : ''}\n onClick={e => {\n if (e.ctrlKey || e.metaKey) {\n togglePointSelection(i);\n } else {\n addToSelection([i]);\n }\n }}\n >\n \u003Ctd>{row.value}\u003C/td>\n \u003C/tr>\n ))}\n \u003C/table>\n );\n};\n```\n\n## Keyboard Shortcuts (Phase 6 - Pending)\n\n| Key | Action |\n| -------- | ----------------- |\n| `Escape` | Clear selection |\n| `Ctrl+A` | Select all points |\n| `Ctrl+I` | Invert selection |\n\n## Mobile/Touch Support (Phase 6 - Pending)\n\n```tsx\n// Touch gestures for mobile devices\nconst IChartMobile = () => {\n return (\n \u003CIChart\n enableBrushSelection={true}\n // Touch: Long press to start brush\n // Touch: Drag to select region\n // Touch: Double-tap to toggle point\n {...props}\n />\n );\n};\n```\n\n## Performance Tips\n\n### Large Datasets (1000+ points)\n\n```tsx\n// Use virtualization for data table\nimport { VirtualizedTable } from '@variscout/ui';\n\nconst DataTable = () => {\n return (\n \u003CVirtualizedTable\n data={filteredData}\n selectedRows={Array.from(selectedPoints)}\n onRowClick={index => togglePointSelection(index)}\n rowHeight={40}\n height={600}\n />\n );\n};\n\n// Use sampling for preview\nconst previewSelection = Array.from(selectedPoints).slice(0, 5);\n```\n\n### Debounce Selection Updates\n\n```tsx\nimport { useDebouncedCallback } from 'use-debounce';\n\nconst Dashboard = () => {\n const debouncedSelectionChange = useDebouncedCallback(\n (indices: Set\u003Cnumber>) => {\n setSelectedPoints(indices);\n },\n 100 // 100ms debounce\n );\n\n return \u003CIChart onSelectionChange={debouncedSelectionChange} {...props} />;\n};\n```\n\n## Troubleshooting\n\n### Selection Cleared After Filter Change\n\nThis is intentional to prevent confusion. When filters change, the visible data changes, so selection is auto-cleared. A warning banner will be added in Phase 3.\n\n### Selection Not Syncing Across Charts\n\nPhase 2 pending. Currently only IChart supports brushing. ScatterPlot and Boxplot integration coming soon.\n\n### Brush Not Working\n\nVerify `enableBrushSelection={true}` prop is set and `onSelectionChange` callback is provided.\n\n### Mobile Touch Issues\n\nMobile/touch support pending in Phase 6. Use desktop browser for now.", + "src/content/docs/archive/brushing-usage-example.md", + "7a54eae10da4228d", + { "html": 3166, "metadata": 3167 }, + "\u003Cblockquote>\n\u003Cp>\u003Cstrong>ARCHIVED\u003C/strong>: This document describes historical implementation details. Do not reference for current work.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"minitab-style-brushing---usage-example\">Minitab-Style Brushing - Usage Example\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#minitab-style-brushing---usage-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Minitab-Style Brushing - Usage Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"quick-start\">Quick Start\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#quick-start\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Start”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-enable-brushing-in-dashboard\">1. Enable Brushing in Dashboard\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-enable-brushing-in-dashboard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Enable Brushing in Dashboard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">apps/pwa/src/components/Dashboard.tsx\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useData } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">../context/DataContext\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { IChart } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Dashboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filteredData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">outcome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">clearSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } =\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Transform data for IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chartData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">row\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">i\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">x: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">i\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">y: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">row[outcome]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> as \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">originalIndex: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">i\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6;--1:#8844AE\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Selection count badge */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">size\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">mb-4 flex items-center gap-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">rounded bg-blue-500 px-3 py-1 text-sm text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">size\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> point\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">size\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">s\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">clearSelection\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm text-slate-400 hover:text-slate-200\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Clear\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* I-Chart with brushing enabled */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">enableBrushSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onSelectionChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">indices\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(indices)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">800\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">400\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">yAxisLabel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">||\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Value\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useData } from '../context/DataContext';import { IChart } from '@variscout/charts';const Dashboard = () => { const { filteredData, outcome, stats, specs, selectedPoints, setSelectedPoints, clearSelection } = useData(); // Transform data for IChart const chartData = filteredData.map((row, i) => ({ x: i, y: row[outcome] as number, originalIndex: i, })); return ( \u003Cdiv> {/* Selection count badge */} {selectedPoints.size > 0 && ( \u003Cdiv className="mb-4 flex items-center gap-2"> \u003Cspan className="rounded bg-blue-500 px-3 py-1 text-sm text-white"> {selectedPoints.size} point{selectedPoints.size > 1 ? 's' : ''} selected \u003C/span> \u003Cbutton onClick={clearSelection} className="text-sm text-slate-400 hover:text-slate-200"> Clear \u003C/button> \u003C/div> )} {/* I-Chart with brushing enabled */} \u003CIChart data={chartData} stats={stats} specs={specs} enableBrushSelection={true} selectedPoints={selectedPoints} onSelectionChange={indices => setSelectedPoints(indices)} parentWidth={800} parentHeight={400} yAxisLabel={outcome || 'Value'} /> \u003C/div> );};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-interaction-patterns\">2. Interaction Patterns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-interaction-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Interaction Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"rectangular-brush-selection\">Rectangular Brush Selection\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#rectangular-brush-selection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Rectangular Brush Selection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">1. Click and drag on chart to draw selection rectangle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">2. Release mouse to select all points within rectangle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">3. Selected points: larger (6px), white stroke, full opacity\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">4. Unselected points: dimmed (0.3 opacity)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"1. Click and drag on chart to draw selection rectangle2. Release mouse to select all points within rectangle3. Selected points: larger (6px), white stroke, full opacity4. Unselected points: dimmed (0.3 opacity)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"modifier-key-interactions\">Modifier Key Interactions\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#modifier-key-interactions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Modifier Key Interactions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Ctrl+Click: Toggle individual point\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Point selected? → Remove from selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Point not selected? → Add to selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Shift+Click: Add point to selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Always adds point without removing others\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Regular Click: Replace selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Clears existing selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Selects only the clicked point\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Ctrl+Click: Toggle individual point - Point selected? → Remove from selection - Point not selected? → Add to selectionShift+Click: Add point to selection - Always adds point without removing othersRegular Click: Replace selection - Clears existing selection - Selects only the clicked point\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-visual-feedback\">3. Visual Feedback\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-visual-feedback\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Visual Feedback”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"default-state-no-selection\">Default State (No Selection)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#default-state-no-selection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Default State (No Selection)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">All points:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Radius: 4px\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Opacity: 1.0\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Stroke: Default (1px)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Color: Semantic (red/green/amber/blue)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"All points: - Radius: 4px - Opacity: 1.0 - Stroke: Default (1px) - Color: Semantic (red/green/amber/blue)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"active-selection\">Active Selection\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#active-selection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Active Selection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Selected points:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Radius: 6px (+2px)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Opacity: 1.0\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Stroke: 2px white\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Color: Maintains semantic meaning\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Unselected points:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Radius: 4px\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Opacity: 0.3 (dimmed)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Stroke: Default (1px)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Color: Dimmed semantic color\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Selected points: - Radius: 6px (+2px) - Opacity: 1.0 - Stroke: 2px white - Color: Maintains semantic meaningUnselected points: - Radius: 4px - Opacity: 0.3 (dimmed) - Stroke: Default (1px) - Color: Dimmed semantic color\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"brush-rectangle-during-selection\">Brush Rectangle (During Selection)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#brush-rectangle-during-selection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Brush Rectangle (During Selection)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Fill: rgba(59, 130, 246, 0.1) // Blue, 10% opacity\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Stroke: rgba(59, 130, 246, 0.5) // Blue, 50% opacity\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Width: 1.5px\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cursor: crosshair\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Fill: rgba(59, 130, 246, 0.1) // Blue, 10% opacityStroke: rgba(59, 130, 246, 0.5) // Blue, 50% opacityWidth: 1.5pxCursor: crosshair\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-advanced-usage---custom-selection-actions\">4. Advanced Usage - Custom Selection Actions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-advanced-usage---custom-selection-actions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Advanced Usage - Custom Selection Actions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Dashboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filteredData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">clearSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setFilters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } =\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Filter to show only selected points\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterToSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> === \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> return;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Get selected row IDs (if you have a unique ID column)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectedIds\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Array\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(selectedPoints)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">i\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredData[i]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setFilters\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">id: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedIds\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Assuming 'id' is a column\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">clearSelection\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Export selected points to CSV\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">exportSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> === \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> return;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectedRows\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Array\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(selectedPoints)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">i\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredData[i])\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">csv\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> =\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Object\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">keys\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(selectedRows[\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">])\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">join\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">,\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">),\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedRows\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">row\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Object\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">values\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(row)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">join\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">,\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)),\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">join\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\n\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">blob\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Blob\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">([csv]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, { type: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text/csv\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">url\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">URL\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createObjectURL\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(blob)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">a\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">document\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createElement\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">a\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">a\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">href\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">url\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">a\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">download\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">selected_points.csv\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">a\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">click\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Highlight outliers automatically\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectOutliers\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">indices\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Set\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">forEach\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">row\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">i\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">row[outcome]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> as \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">usl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> !== \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> && \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> > \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">usl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> ||\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">lsl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> !== \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> && \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> < \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">lsl\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">indices\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(i)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(indices)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6;--1:#8844AE\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Action buttons */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">mb-4 flex gap-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectOutliers\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Select Outliers\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">size\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterToSelection\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Filter to Selection (\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">size\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">exportSelection\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Export Selection\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">enableBrushSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onSelectionChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartProps\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const Dashboard = () => { const { filteredData, selectedPoints, setSelectedPoints, clearSelection, setFilters, filters } = useData(); // Filter to show only selected points const filterToSelection = () => { if (selectedPoints.size === 0) return; // Get selected row IDs (if you have a unique ID column) const selectedIds = Array.from(selectedPoints).map(i => filteredData[i].id); setFilters({ ...filters, id: selectedIds, // Assuming 'id' is a column }); clearSelection(); }; // Export selected points to CSV const exportSelection = () => { if (selectedPoints.size === 0) return; const selectedRows = Array.from(selectedPoints).map(i => filteredData[i]); const csv = [ Object.keys(selectedRows[0]).join(','), ...selectedRows.map(row => Object.values(row).join(',')), ].join('\\n'); const blob = new Blob([csv], { type: 'text/csv' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'selected_points.csv'; a.click(); }; // Highlight outliers automatically const selectOutliers = () => { const indices = new Set\u003Cnumber>(); filteredData.forEach((row, i) => { const value = row[outcome] as number; if ( (specs.usl !== undefined && value > specs.usl) || (specs.lsl !== undefined && value \u003C specs.lsl) ) { indices.add(i); } }); setSelectedPoints(indices); }; return ( \u003Cdiv> {/* Action buttons */} \u003Cdiv className="mb-4 flex gap-2"> \u003Cbutton onClick={selectOutliers}>Select Outliers\u003C/button> {selectedPoints.size > 0 && ( \u003C> \u003Cbutton onClick={filterToSelection}>Filter to Selection ({selectedPoints.size})\u003C/button> \u003Cbutton onClick={exportSelection}>Export Selection\u003C/button> \u003C/> )} \u003C/div> \u003CIChart enableBrushSelection={true} selectedPoints={selectedPoints} onSelectionChange={setSelectedPoints} {...chartProps} /> \u003C/div> );};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"5-cross-chart-synchronization-phase-2---pending\">5. Cross-Chart Synchronization (Phase 2 - Pending)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#5-cross-chart-synchronization-phase-2---pending\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Cross-Chart Synchronization (Phase 2 - Pending)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Future: Selection syncs across all charts automatically\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Dashboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6;--1:#8844AE\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Selection persists across all charts */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">enableBrushSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onSelectionChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartProps\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ScatterPlot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">enableBrushSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onSelectionChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">scatterProps\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Boxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedGroups\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getSelectedGroups\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(selectedPoints)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onBoxClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleBoxClick\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">boxplotProps\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Future: Selection syncs across all charts automaticallyconst Dashboard = () => { const { selectedPoints, setSelectedPoints } = useData(); return ( \u003Cdiv> {/* Selection persists across all charts */} \u003CIChart enableBrushSelection={true} selectedPoints={selectedPoints} onSelectionChange={setSelectedPoints} {...chartProps} /> \u003CScatterPlot enableBrushSelection={true} selectedPoints={selectedPoints} onSelectionChange={setSelectedPoints} {...scatterProps} /> \u003CBoxplot selectedGroups={getSelectedGroups(selectedPoints)} onBoxClick={handleBoxClick} {...boxplotProps} /> \u003C/div> );};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"6-data-table-bi-directional-sync-phase-2---pending\">6. Data Table Bi-Directional Sync (Phase 2 - Pending)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#6-data-table-bi-directional-sync-phase-2---pending\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Data Table Bi-Directional Sync (Phase 2 - Pending)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Future: Table row click updates chart selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">DataTable\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filteredData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addToSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">togglePointSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6;--1:#8844AE\">table\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">row\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">i\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">tr\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">i\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">has\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(i)\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-blue-100\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(e\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">ctrlKey\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">||\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">metaKey\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">togglePointSelection\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(i)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">else\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addToSelection\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">([i])\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">td\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">row\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">value\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">td\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">tr\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">table\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Future: Table row click updates chart selectionconst DataTable = () => { const { filteredData, selectedPoints, addToSelection, togglePointSelection } = useData(); return ( \u003Ctable> {filteredData.map((row, i) => ( \u003Ctr key={i} className={selectedPoints.has(i) ? 'bg-blue-100' : ''} onClick={e => { if (e.ctrlKey || e.metaKey) { togglePointSelection(i); } else { addToSelection([i]); } }} > \u003Ctd>{row.value}\u003C/td> \u003C/tr> ))} \u003C/table> );};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyboard-shortcuts-phase-6---pending\">Keyboard Shortcuts (Phase 6 - Pending)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyboard-shortcuts-phase-6---pending\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyboard Shortcuts (Phase 6 - Pending)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Key\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Escape\u003C/code>\u003C/td>\u003Ctd>Clear selection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Ctrl+A\u003C/code>\u003C/td>\u003Ctd>Select all points\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Ctrl+I\u003C/code>\u003C/td>\u003Ctd>Invert selection\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"mobiletouch-support-phase-6---pending\">Mobile/Touch Support (Phase 6 - Pending)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#mobiletouch-support-phase-6---pending\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile/Touch Support (Phase 6 - Pending)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Touch gestures for mobile devices\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">IChartMobile\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">enableBrushSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Touch: Long press to start brush\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Touch: Drag to select region\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Touch: Double-tap to toggle point\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">props\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Touch gestures for mobile devicesconst IChartMobile = () => { return ( \u003CIChart enableBrushSelection={true} // Touch: Long press to start brush // Touch: Drag to select region // Touch: Double-tap to toggle point {...props} /> );};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performance-tips\">Performance Tips\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performance-tips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Tips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"large-datasets-1000-points\">Large Datasets (1000+ points)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#large-datasets-1000-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Large Datasets (1000+ points)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Use virtualization for data table\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { VirtualizedTable } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">DataTable\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">VirtualizedTable\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedRows\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Array\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(selectedPoints)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onRowClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">togglePointSelection\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(index)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">rowHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">40\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">600\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Use sampling for preview\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">previewSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Array\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(selectedPoints)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">slice\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Use virtualization for data tableimport { VirtualizedTable } from '@variscout/ui';const DataTable = () => { return ( \u003CVirtualizedTable data={filteredData} selectedRows={Array.from(selectedPoints)} onRowClick={index => togglePointSelection(index)} rowHeight={40} height={600} /> );};// Use sampling for previewconst previewSelection = Array.from(selectedPoints).slice(0, 5);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"debounce-selection-updates\">Debounce Selection Updates\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#debounce-selection-updates\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Debounce Selection Updates”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useDebouncedCallback } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">use-debounce\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Dashboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">debouncedSelectionChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useDebouncedCallback\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">indices\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Set\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(indices)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 100ms debounce\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onSelectionChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">debouncedSelectionChange\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">props\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> />\u003C/span>\u003Cspan style=\"--0:#C792EA\">;\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useDebouncedCallback } from 'use-debounce';const Dashboard = () => { const debouncedSelectionChange = useDebouncedCallback( (indices: Set\u003Cnumber>) => { setSelectedPoints(indices); }, 100 // 100ms debounce ); return \u003CIChart onSelectionChange={debouncedSelectionChange} {...props} />;};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"troubleshooting\">Troubleshooting\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#troubleshooting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Troubleshooting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"selection-cleared-after-filter-change\">Selection Cleared After Filter Change\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#selection-cleared-after-filter-change\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Selection Cleared After Filter Change”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This is intentional to prevent confusion. When filters change, the visible data changes, so selection is auto-cleared. A warning banner will be added in Phase 3.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"selection-not-syncing-across-charts\">Selection Not Syncing Across Charts\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#selection-not-syncing-across-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Selection Not Syncing Across Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Phase 2 pending. Currently only IChart supports brushing. ScatterPlot and Boxplot integration coming soon.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"brush-not-working\">Brush Not Working\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#brush-not-working\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Brush Not Working”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Verify \u003Ccode dir=\"auto\">enableBrushSelection={true}\u003C/code> prop is set and \u003Ccode dir=\"auto\">onSelectionChange\u003C/code> callback is provided.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mobile-touch-issues\">Mobile Touch Issues\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-touch-issues\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Touch Issues”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Mobile/touch support pending in Phase 6. Use desktop browser for now.\u003C/p>", + { + "headings": 3168, + "localImagePaths": 3235, + "remoteImagePaths": 3236, + "frontmatter": 3237, + "imagePaths": 3238 + }, + [ + 3169, 3171, 3172, 3175, 3178, 3181, 3184, 3187, 3190, 3193, 3196, 3199, 3202, 3205, 3208, 3211, + 3214, 3217, 3220, 3223, 3226, 3229, 3232 + ], + { "depth": 30, "slug": 3170, "text": 3158 }, + "minitab-style-brushing---usage-example", + { "depth": 33, "slug": 34, "text": 35 }, + { "depth": 79, "slug": 3173, "text": 3174 }, + "1-enable-brushing-in-dashboard", + "1. Enable Brushing in Dashboard", + { "depth": 79, "slug": 3176, "text": 3177 }, + "2-interaction-patterns", + "2. Interaction Patterns", + { "depth": 621, "slug": 3179, "text": 3180 }, + "rectangular-brush-selection", + "Rectangular Brush Selection", + { "depth": 621, "slug": 3182, "text": 3183 }, + "modifier-key-interactions", + "Modifier Key Interactions", + { "depth": 79, "slug": 3185, "text": 3186 }, + "3-visual-feedback", + "3. Visual Feedback", + { "depth": 621, "slug": 3188, "text": 3189 }, + "default-state-no-selection", + "Default State (No Selection)", + { "depth": 621, "slug": 3191, "text": 3192 }, + "active-selection", + "Active Selection", + { "depth": 621, "slug": 3194, "text": 3195 }, + "brush-rectangle-during-selection", + "Brush Rectangle (During Selection)", + { "depth": 79, "slug": 3197, "text": 3198 }, + "4-advanced-usage---custom-selection-actions", + "4. Advanced Usage - Custom Selection Actions", + { "depth": 79, "slug": 3200, "text": 3201 }, + "5-cross-chart-synchronization-phase-2---pending", + "5. Cross-Chart Synchronization (Phase 2 - Pending)", + { "depth": 79, "slug": 3203, "text": 3204 }, + "6-data-table-bi-directional-sync-phase-2---pending", + "6. Data Table Bi-Directional Sync (Phase 2 - Pending)", + { "depth": 33, "slug": 3206, "text": 3207 }, + "keyboard-shortcuts-phase-6---pending", + "Keyboard Shortcuts (Phase 6 - Pending)", + { "depth": 33, "slug": 3209, "text": 3210 }, + "mobiletouch-support-phase-6---pending", + "Mobile/Touch Support (Phase 6 - Pending)", + { "depth": 33, "slug": 3212, "text": 3213 }, + "performance-tips", + "Performance Tips", + { "depth": 79, "slug": 3215, "text": 3216 }, + "large-datasets-1000-points", + "Large Datasets (1000+ points)", + { "depth": 79, "slug": 3218, "text": 3219 }, + "debounce-selection-updates", + "Debounce Selection Updates", + { "depth": 33, "slug": 3221, "text": 3222 }, + "troubleshooting", + "Troubleshooting", + { "depth": 79, "slug": 3224, "text": 3225 }, + "selection-cleared-after-filter-change", + "Selection Cleared After Filter Change", + { "depth": 79, "slug": 3227, "text": 3228 }, + "selection-not-syncing-across-charts", + "Selection Not Syncing Across Charts", + { "depth": 79, "slug": 3230, "text": 3231 }, + "brush-not-working", + "Brush Not Working", + { "depth": 79, "slug": 3233, "text": 3234 }, + "mobile-touch-issues", + "Mobile Touch Issues", + [], + [], + { "title": 3158 }, + [], + "archive/create-factor-guide", + { "id": 3239, "data": 3241, "body": 3246, "filePath": 3247, "digest": 3248, "rendered": 3249 }, + { + "title": 3242, + "editUrl": 16, + "head": 3243, + "template": 18, + "sidebar": 3244, + "pagefind": 16, + "draft": 20 + }, + "Create Factor from Selection - User Guide", + [], + { "hidden": 20, "attrs": 3245 }, + {}, + "> **ARCHIVED**: This document describes historical implementation details. Do not reference for current work.\n\n# Create Factor from Selection - User Guide\n\n**Feature**: Create custom factors from brushed point selections in IChart\n**Status**: Phase 2 Complete ✅\n**Version**: 1.0.0\n\n---\n\n## Overview\n\nThe **Create Factor from Selection** feature allows users to turn a brushed point selection into a permanent, named factor column. This enables:\n\n- Identifying and naming specific events or patterns\n- Filtering to analyze only the selected points\n- Comparing selected vs unselected points in drill-down\n- Exporting data with custom factor labels\n\n**Common Use Cases**:\n\n- Outlier investigation (\"High Temperature Outliers\")\n- Time window analysis (\"Morning Shift\", \"Weekend Production\")\n- Pattern identification (\"Cyclic Events\", \"Tool Wear Period\")\n- Special cause isolation (\"Machine Malfunction\", \"Operator Training\")\n\n---\n\n## User Workflow\n\n### Step 1: Brush Points in IChart\n\nSelect points using one of these methods:\n\n**Drag to Select Region** (Primary Method):\n\n- Click and drag to draw a blue selection rectangle\n- All points within the rectangle are selected\n- Visual feedback: Selected points grow larger with white stroke\n\n**Modify Selection**:\n\n- **Ctrl+click** → Toggle individual point in/out of selection\n- **Shift+click** → Add point to existing selection\n- **Drag new region** → Replace entire selection with new region\n- **Click empty area** → Clear selection\n\n**Visual Feedback**:\n\n- Selected points: 6px radius, 2px white stroke, full opacity\n- Unselected points: Normal size, 0.3 opacity (dimmed for context)\n- Brush rectangle: Blue fill (10% opacity), blue stroke (50% opacity)\n\n---\n\n### Step 2: Review Selection in SelectionPanel\n\nThe **SelectionPanel** appears below the FilterBreadcrumb when points are selected.\n\n**What You See**:\n\n```\n┌─────────────────────────────────────────────────┐\n│ 12 points selected [Clear] [Create Factor] │\n├─────────────────────────────────────────────────┤\n│ #23: Value=45.2, Operator=A, Time=09:15 │\n│ #47: Value=43.8, Operator=B, Time=09:30 │\n│ #52: Value=44.1, Operator=A, Time=09:35 │\n│ #61: Value=46.8, Operator=C, Time=09:44 │\n│ #73: Value=44.5, Operator=A, Time=09:56 │\n│ ... and 7 more points │\n└─────────────────────────────────────────────────┘\n```\n\n**Information Shown**:\n\n- Total point count\n- First 5 points with row numbers (1-based)\n- Outcome value for each point\n- Factor values (e.g., Operator, Shift)\n- Time column value (if present)\n- Overflow indicator (\"and N more points\")\n\n**Actions Available**:\n\n- **[Clear]** → Remove selection, hide panel\n- **[Create Factor]** → Open naming modal\n\n---\n\n### Step 3: Name Your Factor\n\nClick **[Create Factor]** to open the modal.\n\n**Modal Interface**:\n\n```\n┌─────────────────────────────────────────────────┐\n│ Create Factor from Selection [×] │\n├─────────────────────────────────────────────────┤\n│ Factor Name: [________________________] │\n│ │\n│ 12 points will be marked as: │\n│ • \"Your Factor Name\" (selected) │\n│ • \"Other\" (unselected) │\n│ │\n│ The view will automatically filter to show │\n│ only the selected points. │\n│ │\n│ [Cancel] [Create & Filter] │\n└─────────────────────────────────────────────────┘\n```\n\n**Naming Guidelines**:\n\n- Be descriptive: \"High Temperature Outliers\" better than \"Group1\"\n- Use context: \"Morning Shift\" better than \"Shift A\"\n- Avoid duplicates: System validates against existing columns\n- Keep it concise: Factor name appears in charts and filters\n\n**Validation Rules**:\n\n- ❌ Empty name → \"Factor name cannot be empty\"\n- ❌ Duplicate name → \"A factor with this name already exists\"\n- ✅ Unique name → \"Create & Filter\" button enabled\n\n**Keyboard Shortcuts**:\n\n- **Enter** → Create factor (if name valid)\n- **Escape** → Cancel and close modal\n\n---\n\n### Step 4: Auto-Filter Applied\n\nAfter clicking **[Create & Filter]**, the system:\n\n1. **Creates new column** in your dataset\n - Column name: Your factor name (e.g., \"High Temperature Events\")\n - Selected points: Get factor name as value\n - Unselected points: Get \"Other\" as value\n\n2. **Applies filter automatically**\n - Filter: `High Temperature Events: High Temperature Events`\n - Chart view zooms to show only selected points\n - FilterBreadcrumb shows new filter chip\n\n3. **Clears selection**\n - SelectionPanel disappears\n - Now using filter instead of selection\n\n**Example Data After Factor Creation**:\n\n```\n| Row | Value | Operator | High Temperature Events |\n|-----|-------|----------|-------------------------|\n| 23 | 45.2 | A | High Temperature Events | ← Selected\n| 24 | 39.1 | B | Other | ← Not selected\n| 47 | 43.8 | B | High Temperature Events | ← Selected\n| 48 | 38.5 | A | Other | ← Not selected\n```\n\n---\n\n### Step 5: Analyze & Export\n\n**What You Can Do Now**:\n\n**View Filtered Data**:\n\n- IChart shows only selected points (zoomed view)\n- Stats panel updates to show stats for selected points only\n- All charts reflect the filtered dataset\n\n**Remove Filter to See Full Dataset**:\n\n- Click **×** on filter chip in FilterBreadcrumb\n- Full dataset reappears\n- New factor column still exists\n\n**Drill Down by Factor**:\n\n- Select factor in Boxplot: Compare \"High Temperature Events\" vs \"Other\"\n- Select factor in Pareto: See Cpk ranking by factor value\n- Use factor like any other categorical variable\n\n**Export with Factor**:\n\n- Export to CSV includes new factor column\n- Share data with team, factor labels preserved\n- Reproducible analysis with named categories\n\n---\n\n## Real-World Examples\n\n### Example 1: Investigating Outliers\n\n**Scenario**: Coffee roasting temperatures have 5 points above USL.\n\n**Steps**:\n\n1. Brush the 5 high points in IChart\n2. SelectionPanel shows: \"#12, #18, #23, #29, #34\"\n3. Click \"Create Factor\" → Name: \"Temperature Outliers\"\n4. System filters to show only these 5 points\n5. Boxplot shows: \"Temperature Outliers\" vs \"Other\"\n6. Drill by Operator: See if outliers concentrated in one operator\n7. Export CSV with \"Temperature Outliers\" column for report\n\n**Result**: Identified that 4/5 outliers occurred with Operator C during morning shift.\n\n---\n\n### Example 2: Time Window Analysis\n\n**Scenario**: Suspecting morning shift produces better results.\n\n**Steps**:\n\n1. Brush points from 6am-12pm in IChart\n2. SelectionPanel shows: \"24 points selected\"\n3. Create Factor → Name: \"Morning Shift\"\n4. Remove filter to see full dataset\n5. Boxplot: Compare \"Morning Shift\" vs \"Other\"\n6. Stats show: Morning Cpk = 1.8, Other Cpk = 1.2\n7. Present finding: Morning shift has 50% better capability\n\n**Result**: Identified process difference between shifts, recommend standardizing setup procedures.\n\n---\n\n### Example 3: Pattern Group Identification\n\n**Scenario**: Cyclic pattern appears in sachet fill weights.\n\n**Steps**:\n\n1. Brush the 8 points in cyclic peaks\n2. Create Factor → Name: \"Cyclic Events\"\n3. Filter to show only cyclic points\n4. Drill by Machine: See which machine shows pattern\n5. Drill by Time: Confirm pattern occurs every 2 hours\n6. Export with \"Cyclic Events\" label for maintenance\n\n**Result**: Found pattern linked to heat exchanger cycling, added to PM schedule.\n\n---\n\n## Tips & Best Practices\n\n### Naming Conventions\n\n**Good Names**:\n\n- ✅ \"High Temperature Outliers\" (descriptive, actionable)\n- ✅ \"Morning Shift Production\" (context + category)\n- ✅ \"Machine 3 Warm-Up Period\" (specific event)\n- ✅ \"Operator Training Week\" (time-based event)\n\n**Avoid**:\n\n- ❌ \"Group1\" (not descriptive)\n- ❌ \"Data\" (too generic)\n- ❌ \"Selected\" (doesn't convey meaning)\n- ❌ \"X\" (cryptic)\n\n### When to Create Factors\n\n**Good Use Cases**:\n\n- Outlier investigation (isolate special causes)\n- Time window analysis (shift comparisons)\n- Pattern identification (cyclic events)\n- Event labeling (maintenance periods)\n- Hypothesis testing (before/after changes)\n\n**Better Done with Filters**:\n\n- Temporary exploration (use filter chips instead)\n- Already have categorical column (use existing factor)\n- Single-use analysis (no need for persistence)\n\n### Workflow Efficiency\n\n**Before Brushing**:\n\n- Decide what you're looking for (outliers, patterns, time windows)\n- Check if existing factors already capture this (Shift, Operator, etc.)\n- Consider if multiple factors needed (create separately)\n\n**After Creating Factor**:\n\n- Remove filter chip to verify factor column exists\n- Try drill-down with new factor in Boxplot/Pareto\n- Export early to save work (factor persists in CSV)\n\n**Multiple Factors**:\n\n- Can create multiple factors from different selections\n- Each creates independent column\n- Can drill by multiple factors sequentially\n\n---\n\n## Troubleshooting\n\n### Issue: \"A factor with this name already exists\"\n\n**Cause**: Column name already in dataset (original column or previously created factor)\n\n**Solution**:\n\n- Use a different name: \"High Temp Events v2\"\n- Or delete the old column first (if no longer needed)\n- Check existing columns in factor dropdown\n\n---\n\n### Issue: Selection cleared after creating factor\n\n**Cause**: This is intentional behavior. After creating factor, you're now using a filter instead of a selection.\n\n**Solution**:\n\n- This is expected! The filter chip shows your factor filter.\n- Points are still \"selected\" via the filter, not brush selection.\n- To modify, remove filter chip and brush new selection.\n\n---\n\n### Issue: Factor not appearing in Boxplot dropdown\n\n**Cause**: Factor was created but filter is still active, hiding other values.\n\n**Solution**:\n\n- Remove the auto-applied filter chip\n- Full dataset returns, including \"Other\" category\n- Factor now appears in dropdown with both values\n\n---\n\n### Issue: Created factor by mistake\n\n**Cause**: Clicked \"Create & Filter\" with wrong name or selection.\n\n**Solution**:\n\n- No built-in undo (intentional design)\n- Can manually remove from data:\n 1. Export to CSV\n 2. Delete factor column in Excel\n 3. Re-import cleaned CSV\n- Or create new selection with correct name\n\n---\n\n## Technical Notes\n\n### Data Structure\n\n**Before Factor Creation**:\n\n```json\n[\n { \"Value\": 45.2, \"Operator\": \"A\", \"Time\": \"09:15\" },\n { \"Value\": 39.1, \"Operator\": \"B\", \"Time\": \"09:16\" }\n]\n```\n\n**After Creating \"High Temp\" Factor (row 1 selected)**:\n\n```json\n[\n { \"Value\": 45.2, \"Operator\": \"A\", \"Time\": \"09:15\", \"High Temp\": \"High Temp\" },\n { \"Value\": 39.1, \"Operator\": \"B\", \"Time\": \"09:16\", \"High Temp\": \"Other\" }\n]\n```\n\n### Filter Application\n\n**Auto-filter** applies: `{ \"High Temp\": [\"High Temp\"] }`\n\nThis means: Show only rows where `\"High Temp\"` column equals `\"High Temp\"` value.\n\nTo see all data: Remove filter chip → Shows both \"High Temp\" and \"Other\" rows.\n\n---\n\n## API Reference (For Developers)\n\n### SelectionPanel Props\n\n```typescript\ninterface SelectionPanelProps {\n selectedIndices: Set\u003Cnumber>; // Selected row indices (0-based)\n data: DataRow[]; // Filtered dataset\n outcome: string | null; // Outcome column name\n columnAliases?: Record\u003Cstring, string>; // Display name overrides\n factors?: string[]; // Factor columns to show\n timeColumn?: string | null; // Time column name\n onClearSelection: () => void; // Clear callback\n onCreateFactor: () => void; // Open modal callback\n}\n```\n\n### CreateFactorModal Props\n\n```typescript\ninterface CreateFactorModalProps {\n isOpen: boolean; // Modal open state\n onClose: () => void; // Close callback\n selectedCount: number; // Number of selected points\n existingFactors: string[]; // Existing column names (for validation)\n onCreateFactor: (factorName: string) => void; // Create callback\n}\n```\n\n### Core Utilities\n\n```typescript\n// Create factor column from selection\nfunction createFactorFromSelection(\n data: DataRow[],\n selectedIndices: Set\u003Cnumber>,\n factorName: string\n): DataRow[];\n\n// Validate factor name uniqueness\nfunction isValidFactorName(factorName: string, existingColumns: string[]): boolean;\n\n// Extract all column names from dataset\nfunction getColumnNames(data: DataRow[]): string[];\n```\n\n---\n\n## Future Enhancements (Not in Phase 2)\n\n- [ ] Undo factor creation\n- [ ] Rename factor after creation\n- [ ] Multi-value factor (not just \"Factor Name\" / \"Other\")\n- [ ] Factor templates (save common selections)\n- [ ] Merge multiple selections into one factor\n- [ ] Color coding in SelectionPanel by health status\n\n---\n\n## Feedback & Support\n\n**Found a bug?** Report at: [GitHub Issues](https://github.com/ruvnet/variscout/issues)\n\n**Have a feature request?** Create an issue with label: `enhancement`\n\n**Need help?** Check the [main documentation](../index.md) or [Minitab Brushing](./minitab-brushing.md)\n\n---\n\n**Last Updated**: 2026-02-04\n**Phase**: 2 Complete ✅\n**Next**: Phase 3 - Data Table Sync", + "src/content/docs/archive/create-factor-guide.md", + "54a51805b33b4397", + { "html": 3250, "metadata": 3251 }, + "\u003Cblockquote>\n\u003Cp>\u003Cstrong>ARCHIVED\u003C/strong>: This document describes historical implementation details. Do not reference for current work.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"create-factor-from-selection---user-guide\">Create Factor from Selection - User Guide\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#create-factor-from-selection---user-guide\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Create Factor from Selection - User Guide”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Feature\u003C/strong>: Create custom factors from brushed point selections in IChart\n\u003Cstrong>Status\u003C/strong>: Phase 2 Complete ✅\n\u003Cstrong>Version\u003C/strong>: 1.0.0\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Cstrong>Create Factor from Selection\u003C/strong> feature allows users to turn a brushed point selection into a permanent, named factor column. This enables:\u003C/p>\n\u003Cul>\n\u003Cli>Identifying and naming specific events or patterns\u003C/li>\n\u003Cli>Filtering to analyze only the selected points\u003C/li>\n\u003Cli>Comparing selected vs unselected points in drill-down\u003C/li>\n\u003Cli>Exporting data with custom factor labels\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Common Use Cases\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Outlier investigation (“High Temperature Outliers”)\u003C/li>\n\u003Cli>Time window analysis (“Morning Shift”, “Weekend Production”)\u003C/li>\n\u003Cli>Pattern identification (“Cyclic Events”, “Tool Wear Period”)\u003C/li>\n\u003Cli>Special cause isolation (“Machine Malfunction”, “Operator Training”)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"user-workflow\">User Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#user-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-1-brush-points-in-ichart\">Step 1: Brush Points in IChart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-brush-points-in-ichart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Brush Points in IChart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Select points using one of these methods:\u003C/p>\n\u003Cp>\u003Cstrong>Drag to Select Region\u003C/strong> (Primary Method):\u003C/p>\n\u003Cul>\n\u003Cli>Click and drag to draw a blue selection rectangle\u003C/li>\n\u003Cli>All points within the rectangle are selected\u003C/li>\n\u003Cli>Visual feedback: Selected points grow larger with white stroke\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Modify Selection\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Ctrl+click\u003C/strong> → Toggle individual point in/out of selection\u003C/li>\n\u003Cli>\u003Cstrong>Shift+click\u003C/strong> → Add point to existing selection\u003C/li>\n\u003Cli>\u003Cstrong>Drag new region\u003C/strong> → Replace entire selection with new region\u003C/li>\n\u003Cli>\u003Cstrong>Click empty area\u003C/strong> → Clear selection\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Visual Feedback\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Selected points: 6px radius, 2px white stroke, full opacity\u003C/li>\n\u003Cli>Unselected points: Normal size, 0.3 opacity (dimmed for context)\u003C/li>\n\u003Cli>Brush rectangle: Blue fill (10% opacity), blue stroke (50% opacity)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-2-review-selection-in-selectionpanel\">Step 2: Review Selection in SelectionPanel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-review-selection-in-selectionpanel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Review Selection in SelectionPanel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Cstrong>SelectionPanel\u003C/strong> appears below the FilterBreadcrumb when points are selected.\u003C/p>\n\u003Cp>\u003Cstrong>What You See\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 12 points selected [Clear] [Create Factor] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ #23: Value=45.2, Operator=A, Time=09:15 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ #47: Value=43.8, Operator=B, Time=09:30 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ #52: Value=44.1, Operator=A, Time=09:35 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ #61: Value=46.8, Operator=C, Time=09:44 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ #73: Value=44.5, Operator=A, Time=09:56 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ... and 7 more points │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────┐│ 12 points selected [Clear] [Create Factor] │├─────────────────────────────────────────────────┤│ #23: Value=45.2, Operator=A, Time=09:15 ││ #47: Value=43.8, Operator=B, Time=09:30 ││ #52: Value=44.1, Operator=A, Time=09:35 ││ #61: Value=46.8, Operator=C, Time=09:44 ││ #73: Value=44.5, Operator=A, Time=09:56 ││ ... and 7 more points │└─────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Information Shown\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Total point count\u003C/li>\n\u003Cli>First 5 points with row numbers (1-based)\u003C/li>\n\u003Cli>Outcome value for each point\u003C/li>\n\u003Cli>Factor values (e.g., Operator, Shift)\u003C/li>\n\u003Cli>Time column value (if present)\u003C/li>\n\u003Cli>Overflow indicator (“and N more points”)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Actions Available\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>[Clear]\u003C/strong> → Remove selection, hide panel\u003C/li>\n\u003Cli>\u003Cstrong>[Create Factor]\u003C/strong> → Open naming modal\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-3-name-your-factor\">Step 3: Name Your Factor\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-name-your-factor\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Name Your Factor”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click \u003Cstrong>[Create Factor]\u003C/strong> to open the modal.\u003C/p>\n\u003Cp>\u003Cstrong>Modal Interface\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Create Factor from Selection [×] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Factor Name: [________________________] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 12 points will be marked as: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • \"Your Factor Name\" (selected) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • \"Other\" (unselected) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ The view will automatically filter to show │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ only the selected points. │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Cancel] [Create & Filter] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────┐│ Create Factor from Selection [×] │├─────────────────────────────────────────────────┤│ Factor Name: [________________________] ││ ││ 12 points will be marked as: ││ • "Your Factor Name" (selected) ││ • "Other" (unselected) ││ ││ The view will automatically filter to show ││ only the selected points. ││ ││ [Cancel] [Create & Filter] │└─────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Naming Guidelines\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Be descriptive: “High Temperature Outliers” better than “Group1”\u003C/li>\n\u003Cli>Use context: “Morning Shift” better than “Shift A”\u003C/li>\n\u003Cli>Avoid duplicates: System validates against existing columns\u003C/li>\n\u003Cli>Keep it concise: Factor name appears in charts and filters\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Validation Rules\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>❌ Empty name → “Factor name cannot be empty”\u003C/li>\n\u003Cli>❌ Duplicate name → “A factor with this name already exists”\u003C/li>\n\u003Cli>✅ Unique name → “Create & Filter” button enabled\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Keyboard Shortcuts\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Enter\u003C/strong> → Create factor (if name valid)\u003C/li>\n\u003Cli>\u003Cstrong>Escape\u003C/strong> → Cancel and close modal\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-4-auto-filter-applied\">Step 4: Auto-Filter Applied\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-auto-filter-applied\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Auto-Filter Applied”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After clicking \u003Cstrong>[Create & Filter]\u003C/strong>, the system:\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Creates new column\u003C/strong> in your dataset\u003C/p>\n\u003Cul>\n\u003Cli>Column name: Your factor name (e.g., “High Temperature Events”)\u003C/li>\n\u003Cli>Selected points: Get factor name as value\u003C/li>\n\u003Cli>Unselected points: Get “Other” as value\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Applies filter automatically\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Filter: \u003Ccode dir=\"auto\">High Temperature Events: High Temperature Events\u003C/code>\u003C/li>\n\u003Cli>Chart view zooms to show only selected points\u003C/li>\n\u003Cli>FilterBreadcrumb shows new filter chip\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Clears selection\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>SelectionPanel disappears\u003C/li>\n\u003Cli>Now using filter instead of selection\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Example Data After Factor Creation\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| Row | Value | Operator | High Temperature Events |\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|-----|-------|----------|-------------------------|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| 23 | 45.2 | A | High Temperature Events | ← Selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| 24 | 39.1 | B | Other | ← Not selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| 47 | 43.8 | B | High Temperature Events | ← Selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| 48 | 38.5 | A | Other | ← Not selected\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"| Row | Value | Operator | High Temperature Events ||-----|-------|----------|-------------------------|| 23 | 45.2 | A | High Temperature Events | ← Selected| 24 | 39.1 | B | Other | ← Not selected| 47 | 43.8 | B | High Temperature Events | ← Selected| 48 | 38.5 | A | Other | ← Not selected\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-5-analyze--export\">Step 5: Analyze & Export\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-analyze--export\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Analyze & Export”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>What You Can Do Now\u003C/strong>:\u003C/p>\n\u003Cp>\u003Cstrong>View Filtered Data\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>IChart shows only selected points (zoomed view)\u003C/li>\n\u003Cli>Stats panel updates to show stats for selected points only\u003C/li>\n\u003Cli>All charts reflect the filtered dataset\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Remove Filter to See Full Dataset\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Click \u003Cstrong>×\u003C/strong> on filter chip in FilterBreadcrumb\u003C/li>\n\u003Cli>Full dataset reappears\u003C/li>\n\u003Cli>New factor column still exists\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Drill Down by Factor\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Select factor in Boxplot: Compare “High Temperature Events” vs “Other”\u003C/li>\n\u003Cli>Select factor in Pareto: See Cpk ranking by factor value\u003C/li>\n\u003Cli>Use factor like any other categorical variable\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Export with Factor\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Export to CSV includes new factor column\u003C/li>\n\u003Cli>Share data with team, factor labels preserved\u003C/li>\n\u003Cli>Reproducible analysis with named categories\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"real-world-examples\">Real-World Examples\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#real-world-examples\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Real-World Examples”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-1-investigating-outliers\">Example 1: Investigating Outliers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-1-investigating-outliers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example 1: Investigating Outliers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Scenario\u003C/strong>: Coffee roasting temperatures have 5 points above USL.\u003C/p>\n\u003Cp>\u003Cstrong>Steps\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Brush the 5 high points in IChart\u003C/li>\n\u003Cli>SelectionPanel shows: “#12, #18, #23, #29, #34”\u003C/li>\n\u003Cli>Click “Create Factor” → Name: “Temperature Outliers”\u003C/li>\n\u003Cli>System filters to show only these 5 points\u003C/li>\n\u003Cli>Boxplot shows: “Temperature Outliers” vs “Other”\u003C/li>\n\u003Cli>Drill by Operator: See if outliers concentrated in one operator\u003C/li>\n\u003Cli>Export CSV with “Temperature Outliers” column for report\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Result\u003C/strong>: Identified that 4/5 outliers occurred with Operator C during morning shift.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-2-time-window-analysis\">Example 2: Time Window Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-2-time-window-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example 2: Time Window Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Scenario\u003C/strong>: Suspecting morning shift produces better results.\u003C/p>\n\u003Cp>\u003Cstrong>Steps\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Brush points from 6am-12pm in IChart\u003C/li>\n\u003Cli>SelectionPanel shows: “24 points selected”\u003C/li>\n\u003Cli>Create Factor → Name: “Morning Shift”\u003C/li>\n\u003Cli>Remove filter to see full dataset\u003C/li>\n\u003Cli>Boxplot: Compare “Morning Shift” vs “Other”\u003C/li>\n\u003Cli>Stats show: Morning Cpk = 1.8, Other Cpk = 1.2\u003C/li>\n\u003Cli>Present finding: Morning shift has 50% better capability\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Result\u003C/strong>: Identified process difference between shifts, recommend standardizing setup procedures.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-3-pattern-group-identification\">Example 3: Pattern Group Identification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-3-pattern-group-identification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example 3: Pattern Group Identification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Scenario\u003C/strong>: Cyclic pattern appears in sachet fill weights.\u003C/p>\n\u003Cp>\u003Cstrong>Steps\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Brush the 8 points in cyclic peaks\u003C/li>\n\u003Cli>Create Factor → Name: “Cyclic Events”\u003C/li>\n\u003Cli>Filter to show only cyclic points\u003C/li>\n\u003Cli>Drill by Machine: See which machine shows pattern\u003C/li>\n\u003Cli>Drill by Time: Confirm pattern occurs every 2 hours\u003C/li>\n\u003Cli>Export with “Cyclic Events” label for maintenance\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Result\u003C/strong>: Found pattern linked to heat exchanger cycling, added to PM schedule.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tips--best-practices\">Tips & Best Practices\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tips--best-practices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tips & Best Practices”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"naming-conventions\">Naming Conventions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#naming-conventions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Naming Conventions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Good Names\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>✅ “High Temperature Outliers” (descriptive, actionable)\u003C/li>\n\u003Cli>✅ “Morning Shift Production” (context + category)\u003C/li>\n\u003Cli>✅ “Machine 3 Warm-Up Period” (specific event)\u003C/li>\n\u003Cli>✅ “Operator Training Week” (time-based event)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Avoid\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>❌ “Group1” (not descriptive)\u003C/li>\n\u003Cli>❌ “Data” (too generic)\u003C/li>\n\u003Cli>❌ “Selected” (doesn’t convey meaning)\u003C/li>\n\u003Cli>❌ “X” (cryptic)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"when-to-create-factors\">When to Create Factors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-create-factors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Create Factors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Good Use Cases\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Outlier investigation (isolate special causes)\u003C/li>\n\u003Cli>Time window analysis (shift comparisons)\u003C/li>\n\u003Cli>Pattern identification (cyclic events)\u003C/li>\n\u003Cli>Event labeling (maintenance periods)\u003C/li>\n\u003Cli>Hypothesis testing (before/after changes)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Better Done with Filters\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Temporary exploration (use filter chips instead)\u003C/li>\n\u003Cli>Already have categorical column (use existing factor)\u003C/li>\n\u003Cli>Single-use analysis (no need for persistence)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"workflow-efficiency\">Workflow Efficiency\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#workflow-efficiency\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow Efficiency”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Before Brushing\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Decide what you’re looking for (outliers, patterns, time windows)\u003C/li>\n\u003Cli>Check if existing factors already capture this (Shift, Operator, etc.)\u003C/li>\n\u003Cli>Consider if multiple factors needed (create separately)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>After Creating Factor\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Remove filter chip to verify factor column exists\u003C/li>\n\u003Cli>Try drill-down with new factor in Boxplot/Pareto\u003C/li>\n\u003Cli>Export early to save work (factor persists in CSV)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Multiple Factors\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Can create multiple factors from different selections\u003C/li>\n\u003Cli>Each creates independent column\u003C/li>\n\u003Cli>Can drill by multiple factors sequentially\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"troubleshooting\">Troubleshooting\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#troubleshooting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Troubleshooting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"issue-a-factor-with-this-name-already-exists\">Issue: “A factor with this name already exists”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#issue-a-factor-with-this-name-already-exists\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Issue: “A factor with this name already exists””\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Cause\u003C/strong>: Column name already in dataset (original column or previously created factor)\u003C/p>\n\u003Cp>\u003Cstrong>Solution\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Use a different name: “High Temp Events v2”\u003C/li>\n\u003Cli>Or delete the old column first (if no longer needed)\u003C/li>\n\u003Cli>Check existing columns in factor dropdown\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"issue-selection-cleared-after-creating-factor\">Issue: Selection cleared after creating factor\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#issue-selection-cleared-after-creating-factor\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Issue: Selection cleared after creating factor”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Cause\u003C/strong>: This is intentional behavior. After creating factor, you’re now using a filter instead of a selection.\u003C/p>\n\u003Cp>\u003Cstrong>Solution\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>This is expected! The filter chip shows your factor filter.\u003C/li>\n\u003Cli>Points are still “selected” via the filter, not brush selection.\u003C/li>\n\u003Cli>To modify, remove filter chip and brush new selection.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"issue-factor-not-appearing-in-boxplot-dropdown\">Issue: Factor not appearing in Boxplot dropdown\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#issue-factor-not-appearing-in-boxplot-dropdown\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Issue: Factor not appearing in Boxplot dropdown”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Cause\u003C/strong>: Factor was created but filter is still active, hiding other values.\u003C/p>\n\u003Cp>\u003Cstrong>Solution\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Remove the auto-applied filter chip\u003C/li>\n\u003Cli>Full dataset returns, including “Other” category\u003C/li>\n\u003Cli>Factor now appears in dropdown with both values\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"issue-created-factor-by-mistake\">Issue: Created factor by mistake\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#issue-created-factor-by-mistake\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Issue: Created factor by mistake”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Cause\u003C/strong>: Clicked “Create & Filter” with wrong name or selection.\u003C/p>\n\u003Cp>\u003Cstrong>Solution\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>No built-in undo (intentional design)\u003C/li>\n\u003Cli>Can manually remove from data:\n\u003Col>\n\u003Cli>Export to CSV\u003C/li>\n\u003Cli>Delete factor column in Excel\u003C/li>\n\u003Cli>Re-import cleaned CSV\u003C/li>\n\u003C/ol>\n\u003C/li>\n\u003Cli>Or create new selection with correct name\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-notes\">Technical Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-structure\">Data Structure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Before Factor Creation\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Value\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">45.2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Operator\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">A\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Time\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">09:15\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Value\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">39.1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Operator\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">B\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Time\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">09:16\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[ { "Value": 45.2, "Operator": "A", "Time": "09:15" }, { "Value": 39.1, "Operator": "B", "Time": "09:16" }]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>After Creating “High Temp” Factor (row 1 selected)\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Value\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">45.2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Operator\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">A\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Time\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">09:15\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"High Temp\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">High Temp\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Value\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">39.1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Operator\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">B\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Time\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">09:16\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"High Temp\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Other\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[ { "Value": 45.2, "Operator": "A", "Time": "09:15", "High Temp": "High Temp" }, { "Value": 39.1, "Operator": "B", "Time": "09:16", "High Temp": "Other" }]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filter-application\">Filter Application\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filter-application\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter Application”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Auto-filter\u003C/strong> applies: \u003Ccode dir=\"auto\">{ \"High Temp\": [\"High Temp\"] }\u003C/code>\u003C/p>\n\u003Cp>This means: Show only rows where \u003Ccode dir=\"auto\">\"High Temp\"\u003C/code> column equals \u003Ccode dir=\"auto\">\"High Temp\"\u003C/code> value.\u003C/p>\n\u003Cp>To see all data: Remove filter chip → Shows both “High Temp” and “Other” rows.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"api-reference-for-developers\">API Reference (For Developers)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#api-reference-for-developers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “API Reference (For Developers)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"selectionpanel-props\">SelectionPanel Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#selectionpanel-props\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SelectionPanel Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> SelectionPanelProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedIndices\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Selected row indices (0-based)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DataRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Filtered dataset\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Outcome column name\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">columnAliases\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Record\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Display name overrides\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factors\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Factor columns to show\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">timeColumn\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Time column name\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onClearSelection\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Clear callback\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onCreateFactor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Open modal callback\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface SelectionPanelProps { selectedIndices: Set\u003Cnumber>; // Selected row indices (0-based) data: DataRow[]; // Filtered dataset outcome: string | null; // Outcome column name columnAliases?: Record\u003Cstring, string>; // Display name overrides factors?: string[]; // Factor columns to show timeColumn?: string | null; // Time column name onClearSelection: () => void; // Clear callback onCreateFactor: () => void; // Open modal callback}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"createfactormodal-props\">CreateFactorModal Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#createfactormodal-props\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CreateFactorModal Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> CreateFactorModalProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isOpen\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Modal open state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onClose\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Close callback\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedCount\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Number of selected points\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">existingFactors\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Existing column names (for validation)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onCreateFactor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">factorName\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Create callback\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface CreateFactorModalProps { isOpen: boolean; // Modal open state onClose: () => void; // Close callback selectedCount: number; // Number of selected points existingFactors: string[]; // Existing column names (for validation) onCreateFactor: (factorName: string) => void; // Create callback}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-utilities\">Core Utilities\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-utilities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Utilities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Create factor column from selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createFactorFromSelection\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DataRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">selectedIndices\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">factorName\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DataRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Validate factor name uniqueness\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isValidFactorName\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">factorName\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">existingColumns\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Extract all column names from dataset\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getColumnNames\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DataRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Create factor column from selectionfunction createFactorFromSelection( data: DataRow[], selectedIndices: Set\u003Cnumber>, factorName: string): DataRow[];// Validate factor name uniquenessfunction isValidFactorName(factorName: string, existingColumns: string[]): boolean;// Extract all column names from datasetfunction getColumnNames(data: DataRow[]): string[];\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"future-enhancements-not-in-phase-2\">Future Enhancements (Not in Phase 2)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#future-enhancements-not-in-phase-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Future Enhancements (Not in Phase 2)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Undo factor creation\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Rename factor after creation\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Multi-value factor (not just “Factor Name” / “Other”)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Factor templates (save common selections)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Merge multiple selections into one factor\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Color coding in SelectionPanel by health status\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feedback--support\">Feedback & Support\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feedback--support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feedback & Support”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Found a bug?\u003C/strong> Report at: \u003Ca href=\"https://github.com/ruvnet/variscout/issues\">GitHub Issues\u003C/a>\u003C/p>\n\u003Cp>\u003Cstrong>Have a feature request?\u003C/strong> Create an issue with label: \u003Ccode dir=\"auto\">enhancement\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>Need help?\u003C/strong> Check the \u003Ca href=\"../index.md\">main documentation\u003C/a> or \u003Ca href=\"./minitab-brushing.md\">Minitab Brushing\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cp>\u003Cstrong>Last Updated\u003C/strong>: 2026-02-04\n\u003Cstrong>Phase\u003C/strong>: 2 Complete ✅\n\u003Cstrong>Next\u003C/strong>: Phase 3 - Data Table Sync\u003C/p>", + { + "headings": 3252, + "localImagePaths": 3338, + "remoteImagePaths": 3339, + "frontmatter": 3340, + "imagePaths": 3341 + }, + [ + 3253, 3255, 3256, 3259, 3262, 3265, 3268, 3271, 3274, 3277, 3280, 3283, 3286, 3289, 3292, 3295, + 3298, 3299, 3302, 3305, 3308, 3311, 3314, 3317, 3320, 3323, 3326, 3329, 3332, 3335 + ], + { "depth": 30, "slug": 3254, "text": 3242 }, + "create-factor-from-selection---user-guide", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 3257, "text": 3258 }, + "user-workflow", + "User Workflow", + { "depth": 79, "slug": 3260, "text": 3261 }, + "step-1-brush-points-in-ichart", + "Step 1: Brush Points in IChart", + { "depth": 79, "slug": 3263, "text": 3264 }, + "step-2-review-selection-in-selectionpanel", + "Step 2: Review Selection in SelectionPanel", + { "depth": 79, "slug": 3266, "text": 3267 }, + "step-3-name-your-factor", + "Step 3: Name Your Factor", + { "depth": 79, "slug": 3269, "text": 3270 }, + "step-4-auto-filter-applied", + "Step 4: Auto-Filter Applied", + { "depth": 79, "slug": 3272, "text": 3273 }, + "step-5-analyze--export", + "Step 5: Analyze & Export", + { "depth": 33, "slug": 3275, "text": 3276 }, + "real-world-examples", + "Real-World Examples", + { "depth": 79, "slug": 3278, "text": 3279 }, + "example-1-investigating-outliers", + "Example 1: Investigating Outliers", + { "depth": 79, "slug": 3281, "text": 3282 }, + "example-2-time-window-analysis", + "Example 2: Time Window Analysis", + { "depth": 79, "slug": 3284, "text": 3285 }, + "example-3-pattern-group-identification", + "Example 3: Pattern Group Identification", + { "depth": 33, "slug": 3287, "text": 3288 }, + "tips--best-practices", + "Tips & Best Practices", + { "depth": 79, "slug": 3290, "text": 3291 }, + "naming-conventions", + "Naming Conventions", + { "depth": 79, "slug": 3293, "text": 3294 }, + "when-to-create-factors", + "When to Create Factors", + { "depth": 79, "slug": 3296, "text": 3297 }, + "workflow-efficiency", + "Workflow Efficiency", + { "depth": 33, "slug": 3221, "text": 3222 }, + { "depth": 79, "slug": 3300, "text": 3301 }, + "issue-a-factor-with-this-name-already-exists", + "Issue: “A factor with this name already exists”", + { "depth": 79, "slug": 3303, "text": 3304 }, + "issue-selection-cleared-after-creating-factor", + "Issue: Selection cleared after creating factor", + { "depth": 79, "slug": 3306, "text": 3307 }, + "issue-factor-not-appearing-in-boxplot-dropdown", + "Issue: Factor not appearing in Boxplot dropdown", + { "depth": 79, "slug": 3309, "text": 3310 }, + "issue-created-factor-by-mistake", + "Issue: Created factor by mistake", + { "depth": 33, "slug": 3312, "text": 3313 }, + "technical-notes", + "Technical Notes", + { "depth": 79, "slug": 3315, "text": 3316 }, + "data-structure", + "Data Structure", + { "depth": 79, "slug": 3318, "text": 3319 }, + "filter-application", + "Filter Application", + { "depth": 33, "slug": 3321, "text": 3322 }, + "api-reference-for-developers", + "API Reference (For Developers)", + { "depth": 79, "slug": 3324, "text": 3325 }, + "selectionpanel-props", + "SelectionPanel Props", + { "depth": 79, "slug": 3327, "text": 3328 }, + "createfactormodal-props", + "CreateFactorModal Props", + { "depth": 79, "slug": 3330, "text": 3331 }, + "core-utilities", + "Core Utilities", + { "depth": 33, "slug": 3333, "text": 3334 }, + "future-enhancements-not-in-phase-2", + "Future Enhancements (Not in Phase 2)", + { "depth": 33, "slug": 3336, "text": 3337 }, + "feedback--support", + "Feedback & Support", + [], + [], + { "title": 3242 }, + [], + "archive/implementation-summary", + { "id": 3342, "data": 3344, "body": 3349, "filePath": 3350, "digest": 3351, "rendered": 3352 }, + { + "title": 3345, + "editUrl": 16, + "head": 3346, + "template": 18, + "sidebar": 3347, + "pagefind": 16, + "draft": 20 + }, + "Phase 2 Implementation Summary: Create Factor from Selection", + [], + { "hidden": 20, "attrs": 3348 }, + {}, + "> **ARCHIVED**: This document describes historical implementation details. Do not reference for current work.\n\n# Phase 2 Implementation Summary: Create Factor from Selection\n\n**Implementation Date**: 2026-02-04\n**Developer**: Claude Code\n**Status**: ✅ Complete and Functional\n**Build Status**: ✅ All packages compile successfully\n\n---\n\n## Executive Summary\n\nSuccessfully implemented Phase 2 of the Minitab-style brushing feature, enabling users to create custom-named factors from point selections in IChart. The implementation adds two new UI components, core utility functions, and seamless integration with the existing filter system.\n\n**Key Achievement**: Users can now brush points → name them → auto-filter → analyze, creating persistent factors for drill-down analysis.\n\n---\n\n## What Was Built\n\n### 1. New Components (2)\n\n#### SelectionPanel (`packages/ui/src/components/SelectionPanel/`)\n\n- Persistent panel showing selected point details\n- Displays first 5 points with row numbers, outcome values, factors, time\n- [Clear] and [Create Factor] action buttons\n- Blue-themed UI to differentiate from filter chips\n- Responsive design matching FilterBreadcrumb pattern\n\n**Key Features**:\n\n- Smart truncation: Shows \"and N more\" for overflow\n- Column alias support for user-friendly labels\n- Compact mobile-friendly layout\n- Accessible with ARIA labels\n\n#### CreateFactorModal (`packages/ui/src/components/CreateFactorModal/`)\n\n- Modal dialog for naming new factors\n- Real-time validation against existing columns\n- Preview of how points will be marked (selected vs \"Other\")\n- Keyboard shortcuts (Enter, Escape)\n- Auto-focuses input with default suggestion\n\n**Key Features**:\n\n- Duplicate name detection\n- Empty name validation\n- Clear error messaging\n- User-friendly preview\n- Confirmation flow\n\n---\n\n### 2. Core Utilities (`packages/core/src/utils/selection.ts`)\n\n```typescript\n// Create new factor column from selection\ncreateFactorFromSelection(\n data: DataRow[],\n selectedIndices: Set\u003Cnumber>,\n factorName: string\n): DataRow[]\n\n// Validate factor name uniqueness\nisValidFactorName(\n factorName: string,\n existingColumns: string[]\n): boolean\n\n// Extract all column names\ngetColumnNames(data: DataRow[]): string[]\n```\n\n**Type Safety**: All functions use `DataRow` type, fully type-safe across boundaries.\n\n---\n\n### 3. Dashboard Integration\n\nModified `apps/pwa/src/components/Dashboard.tsx`:\n\n- Added SelectionPanel below FilterBreadcrumb (sticky header)\n- Conditional render when `selectedPoints.size > 0`\n- Wired up CreateFactorModal with state management\n- Implemented complete factor creation workflow:\n 1. User clicks \"Create Factor\" → Modal opens\n 2. User names factor → Validation runs\n 3. User confirms → System creates column + auto-filters\n 4. Selection clears → Filter chip appears\n\n**State Flow**:\n\n```\nselectedPoints (DataContext)\n ↓\nSelectionPanel (renders)\n ↓\nUser clicks \"Create Factor\"\n ↓\nCreateFactorModal (opens)\n ↓\nUser enters \"High Temp Events\"\n ↓\ncreateFactorFromSelection()\n ↓\nsetRawData() + setFilters()\n ↓\nclearSelection()\n ↓\nFilterBreadcrumb shows chip\n```\n\n---\n\n## User Workflow\n\n### Complete End-to-End Experience\n\n1. **Brush Points in IChart** (Phase 1)\n - Drag to select region → Blue rectangle\n - Ctrl+click to toggle, Shift+click to add\n - Selected points: 6px + white stroke\n - Unselected: 0.3 opacity (dimmed)\n\n2. **SelectionPanel Appears** (Phase 2)\n\n ```\n ┌─────────────────────────────────────────────┐\n │ 12 points selected [Clear] [Create Factor] │\n ├─────────────────────────────────────────────┤\n │ #23: Value=45.2, Operator=A, Time=09:15 │\n │ #47: Value=43.8, Operator=B, Time=09:30 │\n │ ... and 10 more points │\n └─────────────────────────────────────────────┘\n ```\n\n3. **Create Factor Modal** (Phase 2)\n - User clicks \"Create Factor\"\n - Types custom name: \"High Temperature Events\"\n - Validation: ✅ Unique name\n - Clicks \"Create & Filter\"\n\n4. **Auto-Filter Applied** (Phase 2)\n - New column added to rawData\n - Filter: `High Temperature Events: High Temperature Events`\n - Filter chip appears in FilterBreadcrumb\n - Selection cleared (now using filter)\n - IChart zooms to filtered view\n\n5. **Factor Persists** (Phase 2)\n - Available in Boxplot/Pareto dropdowns\n - Can drill down: \"High Temperature Events\" vs \"Other\"\n - Exports with factor column included\n - Remove filter chip to see full dataset\n\n---\n\n## Code Quality\n\n### TypeScript Compilation\n\n- ✅ Zero TypeScript errors\n- ✅ All imports resolve correctly\n- ✅ Type safety maintained across package boundaries\n- ✅ Strict mode enabled\n\n### Build Results\n\n```bash\n# @variscout/ui build\n✓ 2050 modules transformed\n✓ built in 3.71s\n\n# @variscout/pwa TypeScript check\nNo errors found ✓\n```\n\n### Package Exports\n\n- `@variscout/ui` → `SelectionPanel`, `CreateFactorModal`\n- `@variscout/core` → `createFactorFromSelection`, `isValidFactorName`, `getColumnNames`\n\n---\n\n## Design Patterns Used\n\n### Component Architecture\n\n- **Separation of Concerns**: UI components in `@variscout/ui`, logic in `@variscout/core`\n- **Props-Based**: No context dependency, fully controlled components\n- **Reusable**: Can be used in Azure app or future Excel Add-in\n\n### State Management\n\n- **Central State**: Leverages existing `useDataState` hook from Phase 1\n- **Local Modal State**: Dashboard manages modal open/close\n- **Immutable Updates**: Uses `createFactorFromSelection` pure function\n\n### Validation Strategy\n\n- **Real-Time**: Validation on every keystroke\n- **Non-Blocking**: User sees errors but can still type\n- **Clear Feedback**: Color-coded error messages with icons\n\n### Styling Consistency\n\n- **SelectionPanel**: Blue theme (`bg-blue-500/10`) to differentiate from filters\n- **Modal**: Dark theme matching PWA design system\n- **Responsive**: Works on mobile and desktop\n\n---\n\n## Testing Performed\n\n### Manual Testing ✅\n\n- [x] SelectionPanel appears when points brushed\n- [x] Shows correct count and first 5 points\n- [x] Overflow indicator shows \"and N more\"\n- [x] Clear button clears selection and hides panel\n- [x] Create Factor button opens modal\n- [x] Modal validates empty names\n- [x] Modal validates duplicate names\n- [x] Factor creation adds column to rawData\n- [x] Auto-filter applies correctly\n- [x] Filter chip appears in FilterBreadcrumb\n- [x] Selection clears after factor created\n- [x] Can remove filter chip to see full data\n- [x] New factor appears in Boxplot/Pareto dropdowns\n- [x] Can drill down by new factor\n- [x] Export includes new factor column\n\n### TypeScript Verification ✅\n\n- Ran `pnpm --filter @variscout/pwa exec tsc --noEmit`\n- Zero errors, all types resolve correctly\n\n### Build Verification ✅\n\n- Built `@variscout/ui` package successfully\n- No runtime errors during dev server startup\n\n---\n\n## Files Created (6 new)\n\n1. `packages/ui/src/components/SelectionPanel/SelectionPanel.tsx`\n2. `packages/ui/src/components/SelectionPanel/index.ts`\n3. `packages/ui/src/components/CreateFactorModal/CreateFactorModal.tsx`\n4. `packages/ui/src/components/CreateFactorModal/index.ts`\n5. `packages/core/src/utils/selection.ts`\n6. `PHASE2_COMPLETE.md`\n\n---\n\n## Files Modified (3)\n\n1. `packages/ui/src/index.ts` - Added component exports\n2. `packages/core/src/index.ts` - Added utility exports\n3. `apps/pwa/src/components/Dashboard.tsx` - Integration + workflow\n\n---\n\n## Performance Characteristics\n\n- **SelectionPanel Render**: O(5) - Shows max 5 points\n- **Factor Creation**: O(n) - Maps over entire dataset once\n- **Validation**: O(m) - Checks against m existing columns (typically \u003C 50)\n- **Memory**: Minimal - Selection uses Set (efficient), factor adds one column\n\n**Optimizations**:\n\n- `useMemo` for displayPoints calculation\n- `useCallback` for all event handlers\n- Conditional rendering (panel only when `selectedPoints.size > 0`)\n\n---\n\n## Known Limitations (By Design)\n\n1. **No undo** - Factor creation is permanent (can manually delete)\n2. **IChart-only** - No ScatterPlot/Boxplot brushing (different use cases)\n3. **Binary factor** - Only \"Factor Name\" vs \"Other\" (not multi-value)\n4. **Selection cleared on filter change** - Intentional to prevent confusion\n\n---\n\n## Documentation Created\n\n1. **PHASE2_COMPLETE.md** - Technical completion summary\n2. **CREATE_FACTOR_GUIDE.md** - User guide with examples\n3. **IMPLEMENTATION_SUMMARY.md** - This file\n\n---\n\n## What's Next: Phase 3\n\n### Goal: Data Table Sync (1 day)\n\n**Bi-directional synchronization**:\n\n- IChart selection → Table rows highlight (blue background)\n- Table row click → IChart point highlights\n- Table scrolls to first selected row\n- Visual consistency across views\n\n**Implementation Plan**:\n\n1. Add `selectedPoints` prop to DataPanel\n2. Add row highlighting CSS\n3. Add row click handler → `addToSelection([rowIndex])`\n4. Add scroll-to-row logic\n5. Test bi-directional sync\n\n---\n\n## Success Criteria Met ✅\n\n### Phase 2 Requirements\n\n- [x] SelectionPanel shows selected points\n- [x] User can name factor with custom input\n- [x] Validation prevents duplicates and empty names\n- [x] Factor creation adds column to dataset\n- [x] Auto-filter applies to selected points\n- [x] Filter chip appears in breadcrumb\n- [x] Selection clears after factor created\n- [x] Factor persists for drill-down\n- [x] Keyboard shortcuts work (Enter, Escape)\n- [x] TypeScript compiles without errors\n- [x] Build succeeds\n- [x] Manual testing passes\n\n### Code Quality\n\n- [x] Type-safe across all boundaries\n- [x] Follows existing patterns (FilterBreadcrumb, Modal)\n- [x] Reusable components (no context dependency)\n- [x] Accessible (ARIA labels, keyboard support)\n- [x] Responsive (mobile-friendly)\n- [x] Performant (memoization, conditional rendering)\n\n### Documentation\n\n- [x] User guide created\n- [x] Technical summary written\n- [x] Code examples provided\n- [x] Troubleshooting section added\n\n---\n\n## Lessons Learned\n\n### What Went Well\n\n1. **Reuse of Existing Patterns**: Mirroring FilterBreadcrumb design made UI consistent\n2. **Type Safety**: DataRow type prevented runtime errors, caught issues at compile time\n3. **Pure Functions**: `createFactorFromSelection` easy to test and reason about\n4. **Auto-Filter Integration**: Leveraged existing filter system, no new code needed\n\n### Challenges Overcome\n\n1. **Modal State Management**: Decided to keep it local to Dashboard (not global context)\n2. **Validation Timing**: Real-time validation better than on-submit only\n3. **Selection Clearing**: Initially unclear when to clear, settled on \"after factor creation\"\n\n### Best Practices Applied\n\n1. **Separation of Concerns**: UI in `@variscout/ui`, logic in `@variscout/core`\n2. **Props Over Context**: Components fully controlled, easier to test\n3. **Immutable Updates**: Never mutate rawData directly, always create new array\n4. **User Feedback**: Validation errors shown immediately, no surprises\n\n---\n\n## Metrics\n\n- **Lines of Code Added**: ~800 (components + utilities + integration)\n- **Components Created**: 2 (SelectionPanel, CreateFactorModal)\n- **Utilities Created**: 3 (createFactorFromSelection, isValidFactorName, getColumnNames)\n- **Build Time**: 3.71s (@variscout/ui)\n- **TypeScript Errors**: 0\n- **Manual Tests Passed**: 14/14\n\n---\n\n## Phase Progress\n\n- ✅ **Phase 1**: Core Hook + I-Chart (Complete)\n- ✅ **Phase 2**: Selection Panel + Create Factor (Complete) ← **YOU ARE HERE**\n- ⏳ **Phase 3**: Data Table Sync (1 day)\n- ⏳ **Phase 4**: Performance Mode Integration (1 day)\n- ⏳ **Phase 5**: Polish + Edge Cases (1 day)\n\n**Total Progress**: 2/5 phases (40% complete)\n**Estimated Remaining**: 3 days\n\n---\n\n## Conclusion\n\nPhase 2 implementation successfully delivers a complete Create Factor workflow. Users can now brush points in IChart, name them with custom factors, and automatically filter to analyze the selection. The implementation is type-safe, performant, well-documented, and follows established patterns from the existing codebase.\n\n**Status**: ✅ **READY FOR PHASE 3**\n\n---\n\n**Last Updated**: 2026-02-04\n**Next Milestone**: Phase 3 - Data Table Sync\n**Estimated Completion**: 2026-02-05", + "src/content/docs/archive/implementation-summary.md", + "9ce16f41a4cd5728", + { "html": 3353, "metadata": 3354 }, + "\u003Cblockquote>\n\u003Cp>\u003Cstrong>ARCHIVED\u003C/strong>: This document describes historical implementation details. Do not reference for current work.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"phase-2-implementation-summary-create-factor-from-selection\">Phase 2 Implementation Summary: Create Factor from Selection\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-implementation-summary-create-factor-from-selection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2 Implementation Summary: Create Factor from Selection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Implementation Date\u003C/strong>: 2026-02-04\n\u003Cstrong>Developer\u003C/strong>: Claude Code\n\u003Cstrong>Status\u003C/strong>: ✅ Complete and Functional\n\u003Cstrong>Build Status\u003C/strong>: ✅ All packages compile successfully\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"executive-summary\">Executive Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#executive-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Executive Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Successfully implemented Phase 2 of the Minitab-style brushing feature, enabling users to create custom-named factors from point selections in IChart. The implementation adds two new UI components, core utility functions, and seamless integration with the existing filter system.\u003C/p>\n\u003Cp>\u003Cstrong>Key Achievement\u003C/strong>: Users can now brush points → name them → auto-filter → analyze, creating persistent factors for drill-down analysis.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-was-built\">What Was Built\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-was-built\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Was Built”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-new-components-2\">1. New Components (2)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-new-components-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. New Components (2)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"selectionpanel-packagesuisrccomponentsselectionpanel\">SelectionPanel (\u003Ccode dir=\"auto\">packages/ui/src/components/SelectionPanel/\u003C/code>)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#selectionpanel-packagesuisrccomponentsselectionpanel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SelectionPanel (packages/ui/src/components/SelectionPanel/)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Persistent panel showing selected point details\u003C/li>\n\u003Cli>Displays first 5 points with row numbers, outcome values, factors, time\u003C/li>\n\u003Cli>[Clear] and [Create Factor] action buttons\u003C/li>\n\u003Cli>Blue-themed UI to differentiate from filter chips\u003C/li>\n\u003Cli>Responsive design matching FilterBreadcrumb pattern\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Key Features\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Smart truncation: Shows “and N more” for overflow\u003C/li>\n\u003Cli>Column alias support for user-friendly labels\u003C/li>\n\u003Cli>Compact mobile-friendly layout\u003C/li>\n\u003Cli>Accessible with ARIA labels\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"createfactormodal-packagesuisrccomponentscreatefactormodal\">CreateFactorModal (\u003Ccode dir=\"auto\">packages/ui/src/components/CreateFactorModal/\u003C/code>)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#createfactormodal-packagesuisrccomponentscreatefactormodal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CreateFactorModal (packages/ui/src/components/CreateFactorModal/)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Modal dialog for naming new factors\u003C/li>\n\u003Cli>Real-time validation against existing columns\u003C/li>\n\u003Cli>Preview of how points will be marked (selected vs “Other”)\u003C/li>\n\u003Cli>Keyboard shortcuts (Enter, Escape)\u003C/li>\n\u003Cli>Auto-focuses input with default suggestion\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Key Features\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Duplicate name detection\u003C/li>\n\u003Cli>Empty name validation\u003C/li>\n\u003Cli>Clear error messaging\u003C/li>\n\u003Cli>User-friendly preview\u003C/li>\n\u003Cli>Confirmation flow\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-core-utilities-packagescoresrcutilsselectionts\">2. Core Utilities (\u003Ccode dir=\"auto\">packages/core/src/utils/selection.ts\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-core-utilities-packagescoresrcutilsselectionts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Core Utilities (packages/core/src/utils/selection.ts)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Create new factor column from selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createFactorFromSelection\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data: DataRow[],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedIndices: Set\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">number\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factorName: string\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">): DataRow[]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Validate factor name uniqueness\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isValidFactorName\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factorName: string,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">existingColumns: string[]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">): boolean\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Extract all column names\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getColumnNames\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(data: DataRow[]): string[]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Create new factor column from selectioncreateFactorFromSelection( data: DataRow[], selectedIndices: Set\u003Cnumber>, factorName: string): DataRow[]// Validate factor name uniquenessisValidFactorName( factorName: string, existingColumns: string[]): boolean// Extract all column namesgetColumnNames(data: DataRow[]): string[]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Type Safety\u003C/strong>: All functions use \u003Ccode dir=\"auto\">DataRow\u003C/code> type, fully type-safe across boundaries.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-dashboard-integration\">3. Dashboard Integration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-dashboard-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Dashboard Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Modified \u003Ccode dir=\"auto\">apps/pwa/src/components/Dashboard.tsx\u003C/code>:\u003C/p>\n\u003Cul>\n\u003Cli>Added SelectionPanel below FilterBreadcrumb (sticky header)\u003C/li>\n\u003Cli>Conditional render when \u003Ccode dir=\"auto\">selectedPoints.size > 0\u003C/code>\u003C/li>\n\u003Cli>Wired up CreateFactorModal with state management\u003C/li>\n\u003Cli>Implemented complete factor creation workflow:\n\u003Col>\n\u003Cli>User clicks “Create Factor” → Modal opens\u003C/li>\n\u003Cli>User names factor → Validation runs\u003C/li>\n\u003Cli>User confirms → System creates column + auto-filters\u003C/li>\n\u003Cli>Selection clears → Filter chip appears\u003C/li>\n\u003C/ol>\n\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>State Flow\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">selectedPoints (DataContext)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SelectionPanel (renders)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User clicks \"Create Factor\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CreateFactorModal (opens)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User enters \"High Temp Events\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">createFactorFromSelection()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">setRawData() + setFilters()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">clearSelection()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">FilterBreadcrumb shows chip\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"selectedPoints (DataContext) ↓SelectionPanel (renders) ↓User clicks "Create Factor" ↓CreateFactorModal (opens) ↓User enters "High Temp Events" ↓createFactorFromSelection() ↓setRawData() + setFilters() ↓clearSelection() ↓FilterBreadcrumb shows chip\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"user-workflow\">User Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#user-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"complete-end-to-end-experience\">Complete End-to-End Experience\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#complete-end-to-end-experience\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Complete End-to-End Experience”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Brush Points in IChart\u003C/strong> (Phase 1)\u003C/p>\n\u003Cul>\n\u003Cli>Drag to select region → Blue rectangle\u003C/li>\n\u003Cli>Ctrl+click to toggle, Shift+click to add\u003C/li>\n\u003Cli>Selected points: 6px + white stroke\u003C/li>\n\u003Cli>Unselected: 0.3 opacity (dimmed)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>SelectionPanel Appears\u003C/strong> (Phase 2)\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 12 points selected [Clear] [Create Factor] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ #23: Value=45.2, Operator=A, Time=09:15 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ #47: Value=43.8, Operator=B, Time=09:30 │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ... and 10 more points │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────┐│ 12 points selected [Clear] [Create Factor] │├─────────────────────────────────────────────┤│ #23: Value=45.2, Operator=A, Time=09:15 ││ #47: Value=43.8, Operator=B, Time=09:30 ││ ... and 10 more points │└─────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Create Factor Modal\u003C/strong> (Phase 2)\u003C/p>\n\u003Cul>\n\u003Cli>User clicks “Create Factor”\u003C/li>\n\u003Cli>Types custom name: “High Temperature Events”\u003C/li>\n\u003Cli>Validation: ✅ Unique name\u003C/li>\n\u003Cli>Clicks “Create & Filter”\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Auto-Filter Applied\u003C/strong> (Phase 2)\u003C/p>\n\u003Cul>\n\u003Cli>New column added to rawData\u003C/li>\n\u003Cli>Filter: \u003Ccode dir=\"auto\">High Temperature Events: High Temperature Events\u003C/code>\u003C/li>\n\u003Cli>Filter chip appears in FilterBreadcrumb\u003C/li>\n\u003Cli>Selection cleared (now using filter)\u003C/li>\n\u003Cli>IChart zooms to filtered view\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Factor Persists\u003C/strong> (Phase 2)\u003C/p>\n\u003Cul>\n\u003Cli>Available in Boxplot/Pareto dropdowns\u003C/li>\n\u003Cli>Can drill down: “High Temperature Events” vs “Other”\u003C/li>\n\u003Cli>Exports with factor column included\u003C/li>\n\u003Cli>Remove filter chip to see full dataset\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"code-quality\">Code Quality\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#code-quality\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Code Quality”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"typescript-compilation\">TypeScript Compilation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#typescript-compilation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “TypeScript Compilation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ Zero TypeScript errors\u003C/li>\n\u003Cli>✅ All imports resolve correctly\u003C/li>\n\u003Cli>✅ Type safety maintained across package boundaries\u003C/li>\n\u003Cli>✅ Strict mode enabled\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"build-results\">Build Results\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#build-results\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Build Results”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># @variscout/ui build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">✓\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2050\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">modules\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">transformed\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">✓\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">built\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">in\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">3.71s\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># @variscout/pwa TypeScript check\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">No\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">errors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">found\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">✓\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"✓ 2050 modules transformed✓ built in 3.71sNo errors found ✓\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"package-exports\">Package Exports\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#package-exports\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Package Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code> → \u003Ccode dir=\"auto\">SelectionPanel\u003C/code>, \u003Ccode dir=\"auto\">CreateFactorModal\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">@variscout/core\u003C/code> → \u003Ccode dir=\"auto\">createFactorFromSelection\u003C/code>, \u003Ccode dir=\"auto\">isValidFactorName\u003C/code>, \u003Ccode dir=\"auto\">getColumnNames\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"design-patterns-used\">Design Patterns Used\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#design-patterns-used\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Patterns Used”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"component-architecture\">Component Architecture\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#component-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Component Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Separation of Concerns\u003C/strong>: UI components in \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>, logic in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Props-Based\u003C/strong>: No context dependency, fully controlled components\u003C/li>\n\u003Cli>\u003Cstrong>Reusable\u003C/strong>: Can be used in Azure app or future Excel Add-in\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"state-management\">State Management\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#state-management\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “State Management”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Central State\u003C/strong>: Leverages existing \u003Ccode dir=\"auto\">useDataState\u003C/code> hook from Phase 1\u003C/li>\n\u003Cli>\u003Cstrong>Local Modal State\u003C/strong>: Dashboard manages modal open/close\u003C/li>\n\u003Cli>\u003Cstrong>Immutable Updates\u003C/strong>: Uses \u003Ccode dir=\"auto\">createFactorFromSelection\u003C/code> pure function\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"validation-strategy\">Validation Strategy\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#validation-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Validation Strategy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Real-Time\u003C/strong>: Validation on every keystroke\u003C/li>\n\u003Cli>\u003Cstrong>Non-Blocking\u003C/strong>: User sees errors but can still type\u003C/li>\n\u003Cli>\u003Cstrong>Clear Feedback\u003C/strong>: Color-coded error messages with icons\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"styling-consistency\">Styling Consistency\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#styling-consistency\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Styling Consistency”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>SelectionPanel\u003C/strong>: Blue theme (\u003Ccode dir=\"auto\">bg-blue-500/10\u003C/code>) to differentiate from filters\u003C/li>\n\u003Cli>\u003Cstrong>Modal\u003C/strong>: Dark theme matching PWA design system\u003C/li>\n\u003Cli>\u003Cstrong>Responsive\u003C/strong>: Works on mobile and desktop\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"testing-performed\">Testing Performed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#testing-performed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Testing Performed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"manual-testing\">Manual Testing ✅\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#manual-testing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Manual Testing ✅”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> SelectionPanel appears when points brushed\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Shows correct count and first 5 points\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Overflow indicator shows “and N more”\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Clear button clears selection and hides panel\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Create Factor button opens modal\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Modal validates empty names\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Modal validates duplicate names\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Factor creation adds column to rawData\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Auto-filter applies correctly\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Filter chip appears in FilterBreadcrumb\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Selection clears after factor created\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Can remove filter chip to see full data\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> New factor appears in Boxplot/Pareto dropdowns\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Can drill down by new factor\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Export includes new factor column\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"typescript-verification\">TypeScript Verification ✅\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#typescript-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “TypeScript Verification ✅”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Ran \u003Ccode dir=\"auto\">pnpm --filter @variscout/pwa exec tsc --noEmit\u003C/code>\u003C/li>\n\u003Cli>Zero errors, all types resolve correctly\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"build-verification\">Build Verification ✅\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#build-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Build Verification ✅”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Built \u003Ccode dir=\"auto\">@variscout/ui\u003C/code> package successfully\u003C/li>\n\u003Cli>No runtime errors during dev server startup\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"files-created-6-new\">Files Created (6 new)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#files-created-6-new\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Files Created (6 new)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Ccode dir=\"auto\">packages/ui/src/components/SelectionPanel/SelectionPanel.tsx\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">packages/ui/src/components/SelectionPanel/index.ts\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">packages/ui/src/components/CreateFactorModal/CreateFactorModal.tsx\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">packages/ui/src/components/CreateFactorModal/index.ts\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">packages/core/src/utils/selection.ts\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">PHASE2_COMPLETE.md\u003C/code>\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"files-modified-3\">Files Modified (3)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#files-modified-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Files Modified (3)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Ccode dir=\"auto\">packages/ui/src/index.ts\u003C/code> - Added component exports\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">packages/core/src/index.ts\u003C/code> - Added utility exports\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">apps/pwa/src/components/Dashboard.tsx\u003C/code> - Integration + workflow\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performance-characteristics\">Performance Characteristics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performance-characteristics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Characteristics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>SelectionPanel Render\u003C/strong>: O(5) - Shows max 5 points\u003C/li>\n\u003Cli>\u003Cstrong>Factor Creation\u003C/strong>: O(n) - Maps over entire dataset once\u003C/li>\n\u003Cli>\u003Cstrong>Validation\u003C/strong>: O(m) - Checks against m existing columns (typically < 50)\u003C/li>\n\u003Cli>\u003Cstrong>Memory\u003C/strong>: Minimal - Selection uses Set (efficient), factor adds one column\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Optimizations\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">useMemo\u003C/code> for displayPoints calculation\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useCallback\u003C/code> for all event handlers\u003C/li>\n\u003Cli>Conditional rendering (panel only when \u003Ccode dir=\"auto\">selectedPoints.size > 0\u003C/code>)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"known-limitations-by-design\">Known Limitations (By Design)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#known-limitations-by-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Known Limitations (By Design)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>No undo\u003C/strong> - Factor creation is permanent (can manually delete)\u003C/li>\n\u003Cli>\u003Cstrong>IChart-only\u003C/strong> - No ScatterPlot/Boxplot brushing (different use cases)\u003C/li>\n\u003Cli>\u003Cstrong>Binary factor\u003C/strong> - Only “Factor Name” vs “Other” (not multi-value)\u003C/li>\n\u003Cli>\u003Cstrong>Selection cleared on filter change\u003C/strong> - Intentional to prevent confusion\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"documentation-created\">Documentation Created\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#documentation-created\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Documentation Created”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>PHASE2_COMPLETE.md\u003C/strong> - Technical completion summary\u003C/li>\n\u003Cli>\u003Cstrong>CREATE_FACTOR_GUIDE.md\u003C/strong> - User guide with examples\u003C/li>\n\u003Cli>\u003Cstrong>IMPLEMENTATION_SUMMARY.md\u003C/strong> - This file\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whats-next-phase-3\">What’s Next: Phase 3\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whats-next-phase-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What’s Next: Phase 3”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"goal-data-table-sync-1-day\">Goal: Data Table Sync (1 day)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#goal-data-table-sync-1-day\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Goal: Data Table Sync (1 day)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Bi-directional synchronization\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>IChart selection → Table rows highlight (blue background)\u003C/li>\n\u003Cli>Table row click → IChart point highlights\u003C/li>\n\u003Cli>Table scrolls to first selected row\u003C/li>\n\u003Cli>Visual consistency across views\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Implementation Plan\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Add \u003Ccode dir=\"auto\">selectedPoints\u003C/code> prop to DataPanel\u003C/li>\n\u003Cli>Add row highlighting CSS\u003C/li>\n\u003Cli>Add row click handler → \u003Ccode dir=\"auto\">addToSelection([rowIndex])\u003C/code>\u003C/li>\n\u003Cli>Add scroll-to-row logic\u003C/li>\n\u003Cli>Test bi-directional sync\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-criteria-met\">Success Criteria Met ✅\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-criteria-met\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Criteria Met ✅”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-2-requirements\">Phase 2 Requirements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2 Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> SelectionPanel shows selected points\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> User can name factor with custom input\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Validation prevents duplicates and empty names\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Factor creation adds column to dataset\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Auto-filter applies to selected points\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Filter chip appears in breadcrumb\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Selection clears after factor created\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Factor persists for drill-down\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Keyboard shortcuts work (Enter, Escape)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> TypeScript compiles without errors\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Build succeeds\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Manual testing passes\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"code-quality-1\">Code Quality\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#code-quality-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Code Quality”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Type-safe across all boundaries\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Follows existing patterns (FilterBreadcrumb, Modal)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Reusable components (no context dependency)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Accessible (ARIA labels, keyboard support)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Responsive (mobile-friendly)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Performant (memoization, conditional rendering)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"documentation\">Documentation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> User guide created\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Technical summary written\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Code examples provided\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Troubleshooting section added\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"lessons-learned\">Lessons Learned\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#lessons-learned\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Lessons Learned”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-went-well\">What Went Well\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-went-well\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Went Well”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Reuse of Existing Patterns\u003C/strong>: Mirroring FilterBreadcrumb design made UI consistent\u003C/li>\n\u003Cli>\u003Cstrong>Type Safety\u003C/strong>: DataRow type prevented runtime errors, caught issues at compile time\u003C/li>\n\u003Cli>\u003Cstrong>Pure Functions\u003C/strong>: \u003Ccode dir=\"auto\">createFactorFromSelection\u003C/code> easy to test and reason about\u003C/li>\n\u003Cli>\u003Cstrong>Auto-Filter Integration\u003C/strong>: Leveraged existing filter system, no new code needed\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"challenges-overcome\">Challenges Overcome\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#challenges-overcome\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Challenges Overcome”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Modal State Management\u003C/strong>: Decided to keep it local to Dashboard (not global context)\u003C/li>\n\u003Cli>\u003Cstrong>Validation Timing\u003C/strong>: Real-time validation better than on-submit only\u003C/li>\n\u003Cli>\u003Cstrong>Selection Clearing\u003C/strong>: Initially unclear when to clear, settled on “after factor creation”\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"best-practices-applied\">Best Practices Applied\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#best-practices-applied\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Best Practices Applied”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Separation of Concerns\u003C/strong>: UI in \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>, logic in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Props Over Context\u003C/strong>: Components fully controlled, easier to test\u003C/li>\n\u003Cli>\u003Cstrong>Immutable Updates\u003C/strong>: Never mutate rawData directly, always create new array\u003C/li>\n\u003Cli>\u003Cstrong>User Feedback\u003C/strong>: Validation errors shown immediately, no surprises\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"metrics\">Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Metrics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Lines of Code Added\u003C/strong>: ~800 (components + utilities + integration)\u003C/li>\n\u003Cli>\u003Cstrong>Components Created\u003C/strong>: 2 (SelectionPanel, CreateFactorModal)\u003C/li>\n\u003Cli>\u003Cstrong>Utilities Created\u003C/strong>: 3 (createFactorFromSelection, isValidFactorName, getColumnNames)\u003C/li>\n\u003Cli>\u003Cstrong>Build Time\u003C/strong>: 3.71s (@variscout/ui)\u003C/li>\n\u003Cli>\u003Cstrong>TypeScript Errors\u003C/strong>: 0\u003C/li>\n\u003Cli>\u003Cstrong>Manual Tests Passed\u003C/strong>: 14/14\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-progress\">Phase Progress\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-progress\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase Progress”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ \u003Cstrong>Phase 1\u003C/strong>: Core Hook + I-Chart (Complete)\u003C/li>\n\u003Cli>✅ \u003Cstrong>Phase 2\u003C/strong>: Selection Panel + Create Factor (Complete) ← \u003Cstrong>YOU ARE HERE\u003C/strong>\u003C/li>\n\u003Cli>⏳ \u003Cstrong>Phase 3\u003C/strong>: Data Table Sync (1 day)\u003C/li>\n\u003Cli>⏳ \u003Cstrong>Phase 4\u003C/strong>: Performance Mode Integration (1 day)\u003C/li>\n\u003Cli>⏳ \u003Cstrong>Phase 5\u003C/strong>: Polish + Edge Cases (1 day)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Total Progress\u003C/strong>: 2/5 phases (40% complete)\n\u003Cstrong>Estimated Remaining\u003C/strong>: 3 days\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"conclusion\">Conclusion\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#conclusion\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Conclusion”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Phase 2 implementation successfully delivers a complete Create Factor workflow. Users can now brush points in IChart, name them with custom factors, and automatically filter to analyze the selection. The implementation is type-safe, performant, well-documented, and follows established patterns from the existing codebase.\u003C/p>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: ✅ \u003Cstrong>READY FOR PHASE 3\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>\u003Cstrong>Last Updated\u003C/strong>: 2026-02-04\n\u003Cstrong>Next Milestone\u003C/strong>: Phase 3 - Data Table Sync\n\u003Cstrong>Estimated Completion\u003C/strong>: 2026-02-05\u003C/p>", + { + "headings": 3355, + "localImagePaths": 3475, + "remoteImagePaths": 3476, + "frontmatter": 3477, + "imagePaths": 3478 + }, + [ + 3356, 3358, 3361, 3364, 3367, 3370, 3373, 3376, 3379, 3380, 3383, 3386, 3389, 3392, 3395, 3398, + 3401, 3404, 3407, 3410, 3413, 3416, 3419, 3422, 3425, 3428, 3431, 3434, 3437, 3440, 3443, 3446, + 3449, 3451, 3454, 3457, 3460, 3463, 3466, 3469, 3472 + ], + { "depth": 30, "slug": 3357, "text": 3345 }, + "phase-2-implementation-summary-create-factor-from-selection", + { "depth": 33, "slug": 3359, "text": 3360 }, + "executive-summary", + "Executive Summary", + { "depth": 33, "slug": 3362, "text": 3363 }, + "what-was-built", + "What Was Built", + { "depth": 79, "slug": 3365, "text": 3366 }, + "1-new-components-2", + "1. New Components (2)", + { "depth": 621, "slug": 3368, "text": 3369 }, + "selectionpanel-packagesuisrccomponentsselectionpanel", + "SelectionPanel (packages/ui/src/components/SelectionPanel/)", + { "depth": 621, "slug": 3371, "text": 3372 }, + "createfactormodal-packagesuisrccomponentscreatefactormodal", + "CreateFactorModal (packages/ui/src/components/CreateFactorModal/)", + { "depth": 79, "slug": 3374, "text": 3375 }, + "2-core-utilities-packagescoresrcutilsselectionts", + "2. Core Utilities (packages/core/src/utils/selection.ts)", + { "depth": 79, "slug": 3377, "text": 3378 }, + "3-dashboard-integration", + "3. Dashboard Integration", + { "depth": 33, "slug": 3257, "text": 3258 }, + { "depth": 79, "slug": 3381, "text": 3382 }, + "complete-end-to-end-experience", + "Complete End-to-End Experience", + { "depth": 33, "slug": 3384, "text": 3385 }, + "code-quality", + "Code Quality", + { "depth": 79, "slug": 3387, "text": 3388 }, + "typescript-compilation", + "TypeScript Compilation", + { "depth": 79, "slug": 3390, "text": 3391 }, + "build-results", + "Build Results", + { "depth": 79, "slug": 3393, "text": 3394 }, + "package-exports", + "Package Exports", + { "depth": 33, "slug": 3396, "text": 3397 }, + "design-patterns-used", + "Design Patterns Used", + { "depth": 79, "slug": 3399, "text": 3400 }, + "component-architecture", + "Component Architecture", + { "depth": 79, "slug": 3402, "text": 3403 }, + "state-management", + "State Management", + { "depth": 79, "slug": 3405, "text": 3406 }, + "validation-strategy", + "Validation Strategy", + { "depth": 79, "slug": 3408, "text": 3409 }, + "styling-consistency", + "Styling Consistency", + { "depth": 33, "slug": 3411, "text": 3412 }, + "testing-performed", + "Testing Performed", + { "depth": 79, "slug": 3414, "text": 3415 }, + "manual-testing", + "Manual Testing ✅", + { "depth": 79, "slug": 3417, "text": 3418 }, + "typescript-verification", + "TypeScript Verification ✅", + { "depth": 79, "slug": 3420, "text": 3421 }, + "build-verification", + "Build Verification ✅", + { "depth": 33, "slug": 3423, "text": 3424 }, + "files-created-6-new", + "Files Created (6 new)", + { "depth": 33, "slug": 3426, "text": 3427 }, + "files-modified-3", + "Files Modified (3)", + { "depth": 33, "slug": 3429, "text": 3430 }, + "performance-characteristics", + "Performance Characteristics", + { "depth": 33, "slug": 3432, "text": 3433 }, + "known-limitations-by-design", + "Known Limitations (By Design)", + { "depth": 33, "slug": 3435, "text": 3436 }, + "documentation-created", + "Documentation Created", + { "depth": 33, "slug": 3438, "text": 3439 }, + "whats-next-phase-3", + "What’s Next: Phase 3", + { "depth": 79, "slug": 3441, "text": 3442 }, + "goal-data-table-sync-1-day", + "Goal: Data Table Sync (1 day)", + { "depth": 33, "slug": 3444, "text": 3445 }, + "success-criteria-met", + "Success Criteria Met ✅", + { "depth": 79, "slug": 3447, "text": 3448 }, + "phase-2-requirements", + "Phase 2 Requirements", + { "depth": 79, "slug": 3450, "text": 3385 }, + "code-quality-1", + { "depth": 79, "slug": 3452, "text": 3453 }, + "documentation", + "Documentation", + { "depth": 33, "slug": 3455, "text": 3456 }, + "lessons-learned", + "Lessons Learned", + { "depth": 79, "slug": 3458, "text": 3459 }, + "what-went-well", + "What Went Well", + { "depth": 79, "slug": 3461, "text": 3462 }, + "challenges-overcome", + "Challenges Overcome", + { "depth": 79, "slug": 3464, "text": 3465 }, + "best-practices-applied", + "Best Practices Applied", + { "depth": 33, "slug": 3467, "text": 3468 }, + "metrics", + "Metrics", + { "depth": 33, "slug": 3470, "text": 3471 }, + "phase-progress", + "Phase Progress", + { "depth": 33, "slug": 3473, "text": 3474 }, + "conclusion", + "Conclusion", + [], + [], + { "title": 3345 }, + [], + "archive/minitab-brushing", + { "id": 3479, "data": 3481, "body": 3486, "filePath": 3487, "digest": 3488, "rendered": 3489 }, + { + "title": 3482, + "editUrl": 16, + "head": 3483, + "template": 18, + "sidebar": 3484, + "pagefind": 16, + "draft": 20 + }, + "Minitab-Style Brushing Feature", + [], + { "hidden": 20, "attrs": 3485 }, + {}, + "> **ARCHIVED**: This document describes historical implementation details. Do not reference for current work.\n\n# Minitab-Style Brushing Feature\n\n## Overview\n\nImplemented comprehensive multi-point selection with Minitab-style brushing for VariScout charts. This feature enables users to select and analyze multiple data points across charts using rectangular brush selection and modifier key interactions.\n\n## Implementation Status\n\n### Phase 1: Core Hook + I-Chart ✅ (Completed)\n\n1. **Created `useMultiSelection` hook** (`packages/charts/src/hooks/useMultiSelection.ts`)\n - Rectangular brush selection using mouse drag\n - Point matching within brush extent (scale inversions)\n - Ctrl+click to toggle individual points\n - Shift+click to add points to selection\n - Visual styling helpers (opacity, size, stroke)\n - Keyboard-friendly with proper event handling\n\n2. **Added selection state to `useDataState`** (`packages/hooks/src/useDataState.ts`)\n - `selectedPoints: Set\u003Cnumber>` - selected point indices in filteredData\n - `selectionIndexMap: Map\u003Cnumber, number>` - mapping to original rawData indices\n - Selection actions: `setSelectedPoints`, `addToSelection`, `removeFromSelection`, `clearSelection`, `togglePointSelection`\n - Auto-clear selection when filters change (prevents confusion)\n\n3. **Modified IChart to support brush selection** (`packages/charts/src/IChart.tsx`)\n - New props: `enableBrushSelection`, `selectedPoints`, `onSelectionChange`\n - Integrated `useMultiSelection` hook\n - Renders brush rectangle during selection\n - Points styled based on selection state:\n - Selected: 6px radius, 2px white stroke, full opacity\n - Unselected (when selection exists): 4px radius, 0.3 opacity\n - No selection: 4px radius, full opacity\n\n4. **Unit tests** (`packages/charts/src/hooks/__tests__/useMultiSelection.test.ts`)\n - Tests for selection detection\n - Opacity/size/stroke calculations\n - Modifier key interactions (Ctrl, Shift)\n - Enable/disable brush behavior\n\n## Architecture\n\n### State Flow\n\n```\nChart → Brush Interaction → useMultiSelection → onSelectionChange callback\n ↓\n DataContext.selectedPoints\n ↓\n All Charts Re-render\n ↓\n Points highlighted/dimmed\n```\n\n### Key Design Decisions\n\n1. **Controlled State Pattern**: Charts receive `selectedPoints` and `onSelectionChange` props (controlled component pattern)\n2. **Central State**: Selection state lives in DataContext for automatic cross-chart synchronization\n3. **Filter Integration**: Selection clears on filter changes to avoid user confusion\n4. **Index Mapping**: `selectionIndexMap` maintains link between filtered and original data\n\n## Visual Feedback\n\n### Selected Points\n\n- **Size**: 6px radius (+2px from default)\n- **Stroke**: 2px white stroke\n- **Opacity**: 1.0 (full)\n- **Color**: Maintains semantic meaning (red/green/amber/blue)\n\n### Unselected Points (when selection exists)\n\n- **Size**: 4px radius (default)\n- **Stroke**: Default chrome stroke\n- **Opacity**: 0.3 (dimmed)\n\n### Brush Rectangle\n\n- **Fill**: `rgba(59, 130, 246, 0.1)` (blue, 10% opacity)\n- **Stroke**: `rgba(59, 130, 246, 0.5)` (blue, 50% opacity)\n- **Width**: 1.5px\n- **Cursor**: `crosshair` when brush enabled\n\n## Usage Example\n\n### In Dashboard Component\n\n```tsx\nimport { useData } from '../context/DataContext';\n\nconst Dashboard = () => {\n const { selectedPoints, setSelectedPoints, clearSelection, filteredData } = useData();\n\n return (\n \u003CIChart\n data={chartData}\n stats={stats}\n specs={specs}\n enableBrushSelection={true}\n selectedPoints={selectedPoints}\n onSelectionChange={indices => setSelectedPoints(indices)}\n parentWidth={800}\n parentHeight={400}\n />\n );\n};\n```\n\n### Interaction Patterns\n\n1. **Rectangular Brush**: Click and drag to select region\n2. **Ctrl+Click**: Toggle individual point in/out of selection\n3. **Shift+Click**: Add individual point to selection\n4. **Regular Click**: Replace selection with clicked point\n5. **Click Background**: Clear brush (selection persists)\n\n## Comparison with Minitab\n\n| Feature | Minitab | VariScout | Notes |\n| --------------------- | ------- | ---------- | --------------------- |\n| Rectangular brush | ✅ | ✅ | Drag to select region |\n| Multi-point selection | ✅ | ✅ | Ctrl/Shift modifiers |\n| Cross-chart sync | ✅ | ⚠️ Partial | Phase 2 (pending) |\n| Selection info panel | ✅ | ❌ | Phase 3 (pending) |\n| Filter to selection | ✅ | ❌ | Phase 3 (pending) |\n| Export selected | ✅ | ❌ | Phase 3 (pending) |\n| Indicator column | ✅ | ❌ | Phase 3 (pending) |\n\n## Next Phases (Pending)\n\n### Phase 2: Cross-Chart Sync (1-2 days)\n\n- Wire up ScatterPlot with brush selection\n- Wire up Boxplot (category-level selection)\n- Test synchronization across all charts\n- Implement data table bi-directional sync\n\n### Phase 3: Selection Panel + Actions (2 days)\n\n- Build `SelectionPanel` component (similar to FilterBreadcrumb)\n- Show selected rows with values\n- Actions: Clear, Filter to selection, Export to CSV, Create indicator column\n\n### Phase 4: Performance Mode (1 day)\n\n- Channel-level selection in PerformanceIChart\n- Convert channel selection to point indices on drill-down\n\n### Phase 5: Excel Add-in (1-2 days)\n\n- Fluent UI variant of SelectionPanel\n- Integrate with state bridge\n- Test with Excel tables\n\n### Phase 6: Polish + Edge Cases (1 day)\n\n- Keyboard shortcuts (Escape to clear)\n- Mobile touch handling\n- Large dataset performance testing\n\n## Files Modified\n\n### Core Implementation\n\n- `packages/hooks/src/useDataState.ts` - Selection state and actions\n- `packages/charts/src/hooks/useMultiSelection.ts` - Brush logic hook (new)\n- `packages/charts/src/IChart.tsx` - Brush integration\n- `packages/charts/src/types.ts` - New props for brush selection\n- `packages/charts/src/index.ts` - Export useMultiSelection\n\n### Tests\n\n- `packages/charts/src/hooks/__tests__/useMultiSelection.test.ts` - Unit tests (new)\n\n## Technical Notes\n\n### Performance Considerations\n\n- Uses `Set\u003Cnumber>` for O(1) lookup of selected indices\n- `useMemo` for expensive calculations (brush extent matching)\n- Efficient re-renders via controlled state pattern\n\n### Accessibility\n\n- Keyboard navigation support planned (Escape to clear)\n- Screen reader announcements for selection count\n- ARIA labels for selected points\n\n### Cross-Platform\n\n- Works in PWA, Azure, and Excel Add-in\n- Consistent visual feedback across platforms\n- Theme-aware (dark/light modes)\n\n## Edge Cases Handled\n\n1. **Filter Changes**: Selection auto-clears when filters change (with warning planned)\n2. **Empty Brush**: No-op if brush rectangle contains no points\n3. **Brush Outside Bounds**: Clamped to chart bounds automatically\n4. **Performance Mode Switch**: Selection clears on mode transition\n\n## Known Limitations\n\n1. **No persistence**: Selection not saved to project (intentional - transient analysis tool)\n2. **Single-chart only**: Phase 1 only enables IChart (ScatterPlot/Boxplot in Phase 2)\n3. **No touch gestures**: Mobile support pending (Phase 6)\n4. **No selection panel**: Visual feedback only (Phase 3 adds panel)\n\n## References\n\n- [Minitab Brushing Documentation](https://support.minitab.com/en-us/minitab/help-and-how-to/graphs/general-graph-options/focus-on-critical-data/brushing-data-points/)\n- [Implementation Plan](/.claude/transcripts/plan-minitab-brushing.md) (if exists)\n- [Design System - Interaction Patterns](/docs/design-system/interaction-patterns.md) (future)", + "src/content/docs/archive/minitab-brushing.md", + "882e005ee6b3c59b", + { "html": 3490, "metadata": 3491 }, + "\u003Cblockquote>\n\u003Cp>\u003Cstrong>ARCHIVED\u003C/strong>: This document describes historical implementation details. Do not reference for current work.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"minitab-style-brushing-feature\">Minitab-Style Brushing Feature\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#minitab-style-brushing-feature\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Minitab-Style Brushing Feature”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Implemented comprehensive multi-point selection with Minitab-style brushing for VariScout charts. This feature enables users to select and analyze multiple data points across charts using rectangular brush selection and modifier key interactions.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation-status\">Implementation Status\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-status\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation Status”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-1-core-hook--i-chart--completed\">Phase 1: Core Hook + I-Chart ✅ (Completed)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-1-core-hook--i-chart--completed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 1: Core Hook + I-Chart ✅ (Completed)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Created \u003Ccode dir=\"auto\">useMultiSelection\u003C/code> hook\u003C/strong> (\u003Ccode dir=\"auto\">packages/charts/src/hooks/useMultiSelection.ts\u003C/code>)\u003C/p>\n\u003Cul>\n\u003Cli>Rectangular brush selection using mouse drag\u003C/li>\n\u003Cli>Point matching within brush extent (scale inversions)\u003C/li>\n\u003Cli>Ctrl+click to toggle individual points\u003C/li>\n\u003Cli>Shift+click to add points to selection\u003C/li>\n\u003Cli>Visual styling helpers (opacity, size, stroke)\u003C/li>\n\u003Cli>Keyboard-friendly with proper event handling\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Added selection state to \u003Ccode dir=\"auto\">useDataState\u003C/code>\u003C/strong> (\u003Ccode dir=\"auto\">packages/hooks/src/useDataState.ts\u003C/code>)\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">selectedPoints: Set<number>\u003C/code> - selected point indices in filteredData\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">selectionIndexMap: Map<number, number>\u003C/code> - mapping to original rawData indices\u003C/li>\n\u003Cli>Selection actions: \u003Ccode dir=\"auto\">setSelectedPoints\u003C/code>, \u003Ccode dir=\"auto\">addToSelection\u003C/code>, \u003Ccode dir=\"auto\">removeFromSelection\u003C/code>, \u003Ccode dir=\"auto\">clearSelection\u003C/code>, \u003Ccode dir=\"auto\">togglePointSelection\u003C/code>\u003C/li>\n\u003Cli>Auto-clear selection when filters change (prevents confusion)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Modified IChart to support brush selection\u003C/strong> (\u003Ccode dir=\"auto\">packages/charts/src/IChart.tsx\u003C/code>)\u003C/p>\n\u003Cul>\n\u003Cli>New props: \u003Ccode dir=\"auto\">enableBrushSelection\u003C/code>, \u003Ccode dir=\"auto\">selectedPoints\u003C/code>, \u003Ccode dir=\"auto\">onSelectionChange\u003C/code>\u003C/li>\n\u003Cli>Integrated \u003Ccode dir=\"auto\">useMultiSelection\u003C/code> hook\u003C/li>\n\u003Cli>Renders brush rectangle during selection\u003C/li>\n\u003Cli>Points styled based on selection state:\n\u003Cul>\n\u003Cli>Selected: 6px radius, 2px white stroke, full opacity\u003C/li>\n\u003Cli>Unselected (when selection exists): 4px radius, 0.3 opacity\u003C/li>\n\u003Cli>No selection: 4px radius, full opacity\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Unit tests\u003C/strong> (\u003Ccode dir=\"auto\">packages/charts/src/hooks/__tests__/useMultiSelection.test.ts\u003C/code>)\u003C/p>\n\u003Cul>\n\u003Cli>Tests for selection detection\u003C/li>\n\u003Cli>Opacity/size/stroke calculations\u003C/li>\n\u003Cli>Modifier key interactions (Ctrl, Shift)\u003C/li>\n\u003Cli>Enable/disable brush behavior\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"architecture\">Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"state-flow\">State Flow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#state-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “State Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Chart → Brush Interaction → useMultiSelection → onSelectionChange callback\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext.selectedPoints\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">All Charts Re-render\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Points highlighted/dimmed\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Chart → Brush Interaction → useMultiSelection → onSelectionChange callback ↓ DataContext.selectedPoints ↓ All Charts Re-render ↓ Points highlighted/dimmed\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-design-decisions\">Key Design Decisions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-design-decisions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Design Decisions”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Controlled State Pattern\u003C/strong>: Charts receive \u003Ccode dir=\"auto\">selectedPoints\u003C/code> and \u003Ccode dir=\"auto\">onSelectionChange\u003C/code> props (controlled component pattern)\u003C/li>\n\u003Cli>\u003Cstrong>Central State\u003C/strong>: Selection state lives in DataContext for automatic cross-chart synchronization\u003C/li>\n\u003Cli>\u003Cstrong>Filter Integration\u003C/strong>: Selection clears on filter changes to avoid user confusion\u003C/li>\n\u003Cli>\u003Cstrong>Index Mapping\u003C/strong>: \u003Ccode dir=\"auto\">selectionIndexMap\u003C/code> maintains link between filtered and original data\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visual-feedback\">Visual Feedback\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visual-feedback\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Feedback”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"selected-points\">Selected Points\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#selected-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Selected Points”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Size\u003C/strong>: 6px radius (+2px from default)\u003C/li>\n\u003Cli>\u003Cstrong>Stroke\u003C/strong>: 2px white stroke\u003C/li>\n\u003Cli>\u003Cstrong>Opacity\u003C/strong>: 1.0 (full)\u003C/li>\n\u003Cli>\u003Cstrong>Color\u003C/strong>: Maintains semantic meaning (red/green/amber/blue)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"unselected-points-when-selection-exists\">Unselected Points (when selection exists)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#unselected-points-when-selection-exists\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Unselected Points (when selection exists)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Size\u003C/strong>: 4px radius (default)\u003C/li>\n\u003Cli>\u003Cstrong>Stroke\u003C/strong>: Default chrome stroke\u003C/li>\n\u003Cli>\u003Cstrong>Opacity\u003C/strong>: 0.3 (dimmed)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"brush-rectangle\">Brush Rectangle\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#brush-rectangle\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Brush Rectangle”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Fill\u003C/strong>: \u003Ccode dir=\"auto\">rgba(59, 130, 246, 0.1)\u003C/code> (blue, 10% opacity)\u003C/li>\n\u003Cli>\u003Cstrong>Stroke\u003C/strong>: \u003Ccode dir=\"auto\">rgba(59, 130, 246, 0.5)\u003C/code> (blue, 50% opacity)\u003C/li>\n\u003Cli>\u003Cstrong>Width\u003C/strong>: 1.5px\u003C/li>\n\u003Cli>\u003Cstrong>Cursor\u003C/strong>: \u003Ccode dir=\"auto\">crosshair\u003C/code> when brush enabled\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usage-example\">Usage Example\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usage-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"in-dashboard-component\">In Dashboard Component\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#in-dashboard-component\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “In Dashboard Component”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useData } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">../context/DataContext\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Dashboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">clearSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filteredData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">enableBrushSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onSelectionChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">indices\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(indices)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">800\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">400\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useData } from '../context/DataContext';const Dashboard = () => { const { selectedPoints, setSelectedPoints, clearSelection, filteredData } = useData(); return ( \u003CIChart data={chartData} stats={stats} specs={specs} enableBrushSelection={true} selectedPoints={selectedPoints} onSelectionChange={indices => setSelectedPoints(indices)} parentWidth={800} parentHeight={400} /> );};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interaction-patterns\">Interaction Patterns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interaction-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interaction Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Rectangular Brush\u003C/strong>: Click and drag to select region\u003C/li>\n\u003Cli>\u003Cstrong>Ctrl+Click\u003C/strong>: Toggle individual point in/out of selection\u003C/li>\n\u003Cli>\u003Cstrong>Shift+Click\u003C/strong>: Add individual point to selection\u003C/li>\n\u003Cli>\u003Cstrong>Regular Click\u003C/strong>: Replace selection with clicked point\u003C/li>\n\u003Cli>\u003Cstrong>Click Background\u003C/strong>: Clear brush (selection persists)\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"comparison-with-minitab\">Comparison with Minitab\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#comparison-with-minitab\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Comparison with Minitab”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Minitab\u003C/th>\u003Cth>VariScout\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Rectangular brush\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>Drag to select region\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multi-point selection\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>Ctrl/Shift modifiers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cross-chart sync\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>⚠️ Partial\u003C/td>\u003Ctd>Phase 2 (pending)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Selection info panel\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>❌\u003C/td>\u003Ctd>Phase 3 (pending)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filter to selection\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>❌\u003C/td>\u003Ctd>Phase 3 (pending)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Export selected\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>❌\u003C/td>\u003Ctd>Phase 3 (pending)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Indicator column\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>❌\u003C/td>\u003Ctd>Phase 3 (pending)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"next-phases-pending\">Next Phases (Pending)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#next-phases-pending\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Next Phases (Pending)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-2-cross-chart-sync-1-2-days\">Phase 2: Cross-Chart Sync (1-2 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-cross-chart-sync-1-2-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2: Cross-Chart Sync (1-2 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Wire up ScatterPlot with brush selection\u003C/li>\n\u003Cli>Wire up Boxplot (category-level selection)\u003C/li>\n\u003Cli>Test synchronization across all charts\u003C/li>\n\u003Cli>Implement data table bi-directional sync\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-3-selection-panel--actions-2-days\">Phase 3: Selection Panel + Actions (2 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3-selection-panel--actions-2-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3: Selection Panel + Actions (2 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Build \u003Ccode dir=\"auto\">SelectionPanel\u003C/code> component (similar to FilterBreadcrumb)\u003C/li>\n\u003Cli>Show selected rows with values\u003C/li>\n\u003Cli>Actions: Clear, Filter to selection, Export to CSV, Create indicator column\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-4-performance-mode-1-day\">Phase 4: Performance Mode (1 day)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-4-performance-mode-1-day\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 4: Performance Mode (1 day)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Channel-level selection in PerformanceIChart\u003C/li>\n\u003Cli>Convert channel selection to point indices on drill-down\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-5-excel-add-in-1-2-days\">Phase 5: Excel Add-in (1-2 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-5-excel-add-in-1-2-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 5: Excel Add-in (1-2 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Fluent UI variant of SelectionPanel\u003C/li>\n\u003Cli>Integrate with state bridge\u003C/li>\n\u003Cli>Test with Excel tables\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-6-polish--edge-cases-1-day\">Phase 6: Polish + Edge Cases (1 day)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-6-polish--edge-cases-1-day\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 6: Polish + Edge Cases (1 day)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Keyboard shortcuts (Escape to clear)\u003C/li>\n\u003Cli>Mobile touch handling\u003C/li>\n\u003Cli>Large dataset performance testing\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"files-modified\">Files Modified\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#files-modified\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Files Modified”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-implementation\">Core Implementation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">packages/hooks/src/useDataState.ts\u003C/code> - Selection state and actions\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">packages/charts/src/hooks/useMultiSelection.ts\u003C/code> - Brush logic hook (new)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">packages/charts/src/IChart.tsx\u003C/code> - Brush integration\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">packages/charts/src/types.ts\u003C/code> - New props for brush selection\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">packages/charts/src/index.ts\u003C/code> - Export useMultiSelection\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tests\">Tests\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tests\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tests”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">packages/charts/src/hooks/__tests__/useMultiSelection.test.ts\u003C/code> - Unit tests (new)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-notes\">Technical Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance-considerations\">Performance Considerations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Uses \u003Ccode dir=\"auto\">Set<number>\u003C/code> for O(1) lookup of selected indices\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useMemo\u003C/code> for expensive calculations (brush extent matching)\u003C/li>\n\u003Cli>Efficient re-renders via controlled state pattern\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"accessibility\">Accessibility\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#accessibility\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Accessibility”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Keyboard navigation support planned (Escape to clear)\u003C/li>\n\u003Cli>Screen reader announcements for selection count\u003C/li>\n\u003Cli>ARIA labels for selected points\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cross-platform\">Cross-Platform\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cross-platform\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Platform”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Works in PWA, Azure, and Excel Add-in\u003C/li>\n\u003Cli>Consistent visual feedback across platforms\u003C/li>\n\u003Cli>Theme-aware (dark/light modes)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"edge-cases-handled\">Edge Cases Handled\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#edge-cases-handled\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Edge Cases Handled”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Filter Changes\u003C/strong>: Selection auto-clears when filters change (with warning planned)\u003C/li>\n\u003Cli>\u003Cstrong>Empty Brush\u003C/strong>: No-op if brush rectangle contains no points\u003C/li>\n\u003Cli>\u003Cstrong>Brush Outside Bounds\u003C/strong>: Clamped to chart bounds automatically\u003C/li>\n\u003Cli>\u003Cstrong>Performance Mode Switch\u003C/strong>: Selection clears on mode transition\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"known-limitations\">Known Limitations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#known-limitations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Known Limitations”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>No persistence\u003C/strong>: Selection not saved to project (intentional - transient analysis tool)\u003C/li>\n\u003Cli>\u003Cstrong>Single-chart only\u003C/strong>: Phase 1 only enables IChart (ScatterPlot/Boxplot in Phase 2)\u003C/li>\n\u003Cli>\u003Cstrong>No touch gestures\u003C/strong>: Mobile support pending (Phase 6)\u003C/li>\n\u003Cli>\u003Cstrong>No selection panel\u003C/strong>: Visual feedback only (Phase 3 adds panel)\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"references\">References\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://support.minitab.com/en-us/minitab/help-and-how-to/graphs/general-graph-options/focus-on-critical-data/brushing-data-points/\">Minitab Brushing Documentation\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"/.claude/transcripts/plan-minitab-brushing.md\">Implementation Plan\u003C/a> (if exists)\u003C/li>\n\u003Cli>\u003Ca href=\"/docs/design-system/interaction-patterns.md\">Design System - Interaction Patterns\u003C/a> (future)\u003C/li>\n\u003C/ul>", + { + "headings": 3492, + "localImagePaths": 3577, + "remoteImagePaths": 3578, + "frontmatter": 3579, + "imagePaths": 3580 + }, + [ + 3493, 3495, 3496, 3499, 3502, 3503, 3506, 3509, 3512, 3515, 3518, 3521, 3524, 3527, 3530, 3533, + 3536, 3539, 3542, 3545, 3548, 3551, 3554, 3557, 3560, 3561, 3564, 3567, 3570, 3573, 3576 + ], + { "depth": 30, "slug": 3494, "text": 3482 }, + "minitab-style-brushing-feature", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 3497, "text": 3498 }, + "implementation-status", + "Implementation Status", + { "depth": 79, "slug": 3500, "text": 3501 }, + "phase-1-core-hook--i-chart--completed", + "Phase 1: Core Hook + I-Chart ✅ (Completed)", + { "depth": 33, "slug": 1819, "text": 1820 }, + { "depth": 79, "slug": 3504, "text": 3505 }, + "state-flow", + "State Flow", + { "depth": 79, "slug": 3507, "text": 3508 }, + "key-design-decisions", + "Key Design Decisions", + { "depth": 33, "slug": 3510, "text": 3511 }, + "visual-feedback", + "Visual Feedback", + { "depth": 79, "slug": 3513, "text": 3514 }, + "selected-points", + "Selected Points", + { "depth": 79, "slug": 3516, "text": 3517 }, + "unselected-points-when-selection-exists", + "Unselected Points (when selection exists)", + { "depth": 79, "slug": 3519, "text": 3520 }, + "brush-rectangle", + "Brush Rectangle", + { "depth": 33, "slug": 3522, "text": 3523 }, + "usage-example", + "Usage Example", + { "depth": 79, "slug": 3525, "text": 3526 }, + "in-dashboard-component", + "In Dashboard Component", + { "depth": 79, "slug": 3528, "text": 3529 }, + "interaction-patterns", + "Interaction Patterns", + { "depth": 33, "slug": 3531, "text": 3532 }, + "comparison-with-minitab", + "Comparison with Minitab", + { "depth": 33, "slug": 3534, "text": 3535 }, + "next-phases-pending", + "Next Phases (Pending)", + { "depth": 79, "slug": 3537, "text": 3538 }, + "phase-2-cross-chart-sync-1-2-days", + "Phase 2: Cross-Chart Sync (1-2 days)", + { "depth": 79, "slug": 3540, "text": 3541 }, + "phase-3-selection-panel--actions-2-days", + "Phase 3: Selection Panel + Actions (2 days)", + { "depth": 79, "slug": 3543, "text": 3544 }, + "phase-4-performance-mode-1-day", + "Phase 4: Performance Mode (1 day)", + { "depth": 79, "slug": 3546, "text": 3547 }, + "phase-5-excel-add-in-1-2-days", + "Phase 5: Excel Add-in (1-2 days)", + { "depth": 79, "slug": 3549, "text": 3550 }, + "phase-6-polish--edge-cases-1-day", + "Phase 6: Polish + Edge Cases (1 day)", + { "depth": 33, "slug": 3552, "text": 3553 }, + "files-modified", + "Files Modified", + { "depth": 79, "slug": 3555, "text": 3556 }, + "core-implementation", + "Core Implementation", + { "depth": 79, "slug": 3558, "text": 3559 }, + "tests", + "Tests", + { "depth": 33, "slug": 3312, "text": 3313 }, + { "depth": 79, "slug": 3562, "text": 3563 }, + "performance-considerations", + "Performance Considerations", + { "depth": 79, "slug": 3565, "text": 3566 }, + "accessibility", + "Accessibility", + { "depth": 79, "slug": 3568, "text": 3569 }, + "cross-platform", + "Cross-Platform", + { "depth": 33, "slug": 3571, "text": 3572 }, + "edge-cases-handled", + "Edge Cases Handled", + { "depth": 33, "slug": 3574, "text": 3575 }, + "known-limitations", + "Known Limitations", + { "depth": 33, "slug": 878, "text": 879 }, + [], + [], + { "title": 3482 }, + [], + "archive/performance-mode-optimization", + { "id": 3581, "data": 3583, "body": 3588, "filePath": 3589, "digest": 3590, "rendered": 3591 }, + { + "title": 3584, + "editUrl": 16, + "head": 3585, + "template": 18, + "sidebar": 3586, + "pagefind": 16, + "draft": 20 + }, + "Performance Mode Optimization - Implementation Summary", + [], + { "hidden": 20, "attrs": 3587 }, + {}, + "> **ARCHIVED**: This document describes historical implementation details. Do not reference for current work.\n\n# Performance Mode Optimization - Implementation Summary\n\n**Date**: 2026-02-04\n**Status**: ✅ Completed\n**Build Status**: ✅ All packages compile without errors\n\n## Overview\n\nSuccessfully implemented Performance Mode optimization for 100+ column datasets by simplifying the dashboard layout from 4 charts to 2 charts.\n\n## Changes Made\n\n### Layout Transformation\n\n**Before** (4-chart grid):\n\n```\n┌─────────────────────────────────────────────────────┐\n│ I-Chart (Cpk scatter) - Full width │\n└─────────────────────────────────────────────────────┘\n┌──────────────┬──────────────┬──────────────────────┐\n│ Boxplot │ Pareto │ Histogram │\n│ (worst 5) │ (worst 20) │ (selected channel) │\n│ 33% width │ 33% width │ 33% width │\n└──────────────┴──────────────┴──────────────────────┘\n```\n\n**After** (2-chart simplified):\n\n```\n┌─────────────────────────────────────────────────────┐\n│ I-Chart (Cpk scatter) - Full width │\n│ Y-axis shows Cpk ranking (lowest = worst) │\n│ Click point → Drill to Dashboard │\n└─────────────────────────────────────────────────────┘\n┌─────────────────────────────────────────────────────┐\n│ Boxplot - Full width │\n│ Shows worst 15 channels │\n│ Click box → \"Analyze Head_42 in detail?\" → │\n│ → Drills to standard Dashboard (I-Chart view) │\n└─────────────────────────────────────────────────────┘\n```\n\n### Files Modified\n\n#### 1. PWA (`apps/pwa/src/components/PerformanceDashboard.tsx`)\n\n- ✅ Removed `PerformancePareto` and `PerformanceCapability` imports\n- ✅ Updated `FocusedChart` type: removed 'pareto' and 'capability'\n- ✅ Updated `chartOrder` array to `['ichart', 'boxplot']`\n- ✅ Added `handleBoxplotClick()` callback with confirmation prompt\n- ✅ Removed Pareto and Capability focus mode blocks\n- ✅ Simplified grid from `lg:grid-cols-3` to single-column (`grid-rows-2`)\n- ✅ Updated I-Chart to `col-span-full`\n- ✅ Updated Boxplot to full width with `maxDisplayed={15}`\n- ✅ Removed Pareto and Capability chart sections\n- ✅ Added info tooltip to I-Chart: \"Measures ranked by Cpk (lowest first). Click point to analyze in detail.\"\n- ✅ Updated Boxplot heading: \"Worst 15 Measures (Click to Analyze)\"\n- ✅ Updated file header comment to reflect new layout\n\n#### 2. Azure App (`apps/azure/src/components/PerformanceDashboard.tsx`)\n\n- ✅ Applied identical changes as PWA (same pattern)\n\n#### 3. Excel Add-in (`apps/excel-addin/src/content/ContentPerformanceDashboard.tsx`)\n\n- ✅ Removed `PerformanceParetoBase` and `PerformanceCapabilityBase` imports\n- ✅ Added `handleBoxplotClick()` callback with confirmation\n- ✅ Updated `bottomRow` style to `flexDirection: 'column'` (single chart)\n- ✅ Updated chart dimensions to use full width for Boxplot\n- ✅ Removed Pareto and Capability chart sections\n- ✅ Removed unused `selectedChannel` variable\n- ✅ Updated Boxplot label: \"Worst 15 Channels (Click to Analyze)\"\n- ✅ Updated file header comment\n\n### Key Features Implemented\n\n1. **Drill-down Workflow**:\n - Clicking Boxplot triggers confirmation: \"Analyze {measureId} in detail? This will switch to standard Dashboard view.\"\n - Confirmation → `onDrillToMeasure(measureId)` → Standard Dashboard with full analysis tools\n\n2. **Scalability Improvements**:\n - Boxplot expanded from 33% → 100% width\n - Can display 15 channels clearly (6x improvement from previous 5 at 33% width)\n - Focus mode shows up to 30 channels (maxDisplayed={Infinity})\n\n3. **Focus Mode Updates**:\n - Arrow key navigation cycles only between I-Chart and Boxplot\n - Escape key exits focus mode\n - Focus mode headings updated to reflect drill-down workflow\n\n4. **User Guidance**:\n - I-Chart tooltip: \"Measures ranked by Cpk (lowest first). Click point to analyze in detail.\"\n - Boxplot heading: \"Worst 15 Measures (Click to Analyze)\"\n - Confirmation prompts prevent accidental navigation\n\n## Rationale\n\n### Why Remove Pareto Chart?\n\n- At 100+ channels, becomes unreadable (1-2px bars)\n- I-Chart Y-axis already provides ranking (lowest Cpk = worst)\n- Color coding shows health status (red/amber/green)\n\n### Why Remove Histogram (Capability Chart)?\n\n- Standard Dashboard already has histogram via PerformanceCapability\n- Dashboard offers time-series I-Chart, control limits, brushing, factors\n- Performance Mode focuses on overview, not detail\n\n### Why Keep Only Boxplot?\n\n- At full width, can show 15-30 boxes clearly\n- Side-by-side distribution comparison\n- Shows outliers, quartiles, skewness\n- Natural drill-down entry point for investigation\n\n## Verification\n\n### Build Status\n\n```bash\npnpm build\n# ✅ All packages compiled successfully with 0 TypeScript errors\n```\n\n### TypeScript Strict Mode\n\n- All changes maintain strict type checking\n- No type errors or warnings\n- Unused variables removed (selectedChannel in Excel Add-in)\n\n### Cross-App Consistency\n\n- PWA, Azure, and Excel Add-in all implement identical patterns\n- Tailwind CSS (PWA/Azure) vs inline styles (Excel) both updated\n- Base chart variants used in Excel for explicit sizing\n\n## Testing Checklist\n\nManual testing recommended:\n\n- [ ] PWA: Load 10-20 column dataset → Verify simplified 2-row layout\n- [ ] PWA: Load 100-column dataset → Verify Boxplot shows 15 worst channels\n- [ ] PWA: Click Boxplot box → Verify confirmation prompt → Drill to Dashboard\n- [ ] PWA: Focus mode → Verify arrow keys cycle between I-Chart and Boxplot only\n- [ ] Azure: Same tests as PWA\n- [ ] Excel: Test with Excel Add-in → Verify base variants render correctly\n- [ ] Excel: Test confirmation prompt and drill-down workflow\n\n## Benefits\n\n1. **Readability**: Boxplot 6x wider → Can show 3x more channels clearly\n2. **Simplicity**: 2 charts instead of 4 → Less cognitive load\n3. **Workflow**: Clear path from overview → drill-down → investigation\n4. **Performance**: Removed 2 chart components → Faster rendering\n5. **Scalability**: Optimized for 100+ columns without sacrificing clarity\n\n## Rollback Plan\n\nIf issues arise, revert the following commits (in order):\n\n1. `apps/excel-addin/src/content/ContentPerformanceDashboard.tsx`\n2. `apps/azure/src/components/PerformanceDashboard.tsx`\n3. `apps/pwa/src/components/PerformanceDashboard.tsx`\n\nAll changes are layout-only, no data structure modifications.\n\n## Notes\n\n- PerformancePareto and PerformanceCapability charts remain in `@variscout/charts` package (not deleted)\n- Charts can be used in other contexts or custom implementations\n- Focus is on Performance Mode dashboard optimization only\n\n## Success Metrics\n\n- ✅ TypeScript compiles with 0 errors\n- ✅ All 3 apps updated consistently (PWA, Azure, Excel)\n- ✅ Grid layout simplified (2 rows instead of 4 charts)\n- ✅ Boxplot maxDisplayed increased from 5 → 15 (3x improvement)\n- ✅ Focus mode updated (only I-Chart and Boxplot navigation)\n- ✅ Confirmation prompts added for drill-down workflow\n- ✅ User guidance tooltips added (I-Chart info icon)\n- ✅ File header comments updated to reflect new architecture", + "src/content/docs/archive/performance-mode-optimization.md", + "21d3d9ba68559899", + { "html": 3592, "metadata": 3593 }, + "\u003Cblockquote>\n\u003Cp>\u003Cstrong>ARCHIVED\u003C/strong>: This document describes historical implementation details. Do not reference for current work.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"performance-mode-optimization---implementation-summary\">Performance Mode Optimization - Implementation Summary\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#performance-mode-optimization---implementation-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Mode Optimization - Implementation Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2026-02-04\n\u003Cstrong>Status\u003C/strong>: ✅ Completed\n\u003Cstrong>Build Status\u003C/strong>: ✅ All packages compile without errors\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Successfully implemented Performance Mode optimization for 100+ column datasets by simplifying the dashboard layout from 4 charts to 2 charts.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"changes-made\">Changes Made\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#changes-made\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Changes Made”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layout-transformation\">Layout Transformation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layout-transformation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layout Transformation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Before\u003C/strong> (4-chart grid):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ I-Chart (Cpk scatter) - Full width │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌──────────────┬──────────────┬──────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Boxplot │ Pareto │ Histogram │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (worst 5) │ (worst 20) │ (selected channel) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 33% width │ 33% width │ 33% width │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────────────┴──────────────┴──────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────┐│ I-Chart (Cpk scatter) - Full width │└─────────────────────────────────────────────────────┘┌──────────────┬──────────────┬──────────────────────┐│ Boxplot │ Pareto │ Histogram ││ (worst 5) │ (worst 20) │ (selected channel) ││ 33% width │ 33% width │ 33% width │└──────────────┴──────────────┴──────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>After\u003C/strong> (2-chart simplified):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ I-Chart (Cpk scatter) - Full width │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Y-axis shows Cpk ranking (lowest = worst) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Click point → Drill to Dashboard │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Boxplot - Full width │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Shows worst 15 channels │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Click box → \"Analyze Head_42 in detail?\" → │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ → Drills to standard Dashboard (I-Chart view) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────┐│ I-Chart (Cpk scatter) - Full width ││ Y-axis shows Cpk ranking (lowest = worst) ││ Click point → Drill to Dashboard │└─────────────────────────────────────────────────────┘┌─────────────────────────────────────────────────────┐│ Boxplot - Full width ││ Shows worst 15 channels ││ Click box → "Analyze Head_42 in detail?" → ││ → Drills to standard Dashboard (I-Chart view) │└─────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"files-modified\">Files Modified\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#files-modified\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Files Modified”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"1-pwa-appspwasrccomponentsperformancedashboardtsx\">1. PWA (\u003Ccode dir=\"auto\">apps/pwa/src/components/PerformanceDashboard.tsx\u003C/code>)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#1-pwa-appspwasrccomponentsperformancedashboardtsx\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. PWA (apps/pwa/src/components/PerformanceDashboard.tsx)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ Removed \u003Ccode dir=\"auto\">PerformancePareto\u003C/code> and \u003Ccode dir=\"auto\">PerformanceCapability\u003C/code> imports\u003C/li>\n\u003Cli>✅ Updated \u003Ccode dir=\"auto\">FocusedChart\u003C/code> type: removed ‘pareto’ and ‘capability’\u003C/li>\n\u003Cli>✅ Updated \u003Ccode dir=\"auto\">chartOrder\u003C/code> array to \u003Ccode dir=\"auto\">['ichart', 'boxplot']\u003C/code>\u003C/li>\n\u003Cli>✅ Added \u003Ccode dir=\"auto\">handleBoxplotClick()\u003C/code> callback with confirmation prompt\u003C/li>\n\u003Cli>✅ Removed Pareto and Capability focus mode blocks\u003C/li>\n\u003Cli>✅ Simplified grid from \u003Ccode dir=\"auto\">lg:grid-cols-3\u003C/code> to single-column (\u003Ccode dir=\"auto\">grid-rows-2\u003C/code>)\u003C/li>\n\u003Cli>✅ Updated I-Chart to \u003Ccode dir=\"auto\">col-span-full\u003C/code>\u003C/li>\n\u003Cli>✅ Updated Boxplot to full width with \u003Ccode dir=\"auto\">maxDisplayed={15}\u003C/code>\u003C/li>\n\u003Cli>✅ Removed Pareto and Capability chart sections\u003C/li>\n\u003Cli>✅ Added info tooltip to I-Chart: “Measures ranked by Cpk (lowest first). Click point to analyze in detail.”\u003C/li>\n\u003Cli>✅ Updated Boxplot heading: “Worst 15 Measures (Click to Analyze)”\u003C/li>\n\u003Cli>✅ Updated file header comment to reflect new layout\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"2-azure-app-appsazuresrccomponentsperformancedashboardtsx\">2. Azure App (\u003Ccode dir=\"auto\">apps/azure/src/components/PerformanceDashboard.tsx\u003C/code>)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#2-azure-app-appsazuresrccomponentsperformancedashboardtsx\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Azure App (apps/azure/src/components/PerformanceDashboard.tsx)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ Applied identical changes as PWA (same pattern)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"3-excel-add-in-appsexcel-addinsrccontentcontentperformancedashboardtsx\">3. Excel Add-in (\u003Ccode dir=\"auto\">apps/excel-addin/src/content/ContentPerformanceDashboard.tsx\u003C/code>)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#3-excel-add-in-appsexcel-addinsrccontentcontentperformancedashboardtsx\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Excel Add-in (apps/excel-addin/src/content/ContentPerformanceDashboard.tsx)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ Removed \u003Ccode dir=\"auto\">PerformanceParetoBase\u003C/code> and \u003Ccode dir=\"auto\">PerformanceCapabilityBase\u003C/code> imports\u003C/li>\n\u003Cli>✅ Added \u003Ccode dir=\"auto\">handleBoxplotClick()\u003C/code> callback with confirmation\u003C/li>\n\u003Cli>✅ Updated \u003Ccode dir=\"auto\">bottomRow\u003C/code> style to \u003Ccode dir=\"auto\">flexDirection: 'column'\u003C/code> (single chart)\u003C/li>\n\u003Cli>✅ Updated chart dimensions to use full width for Boxplot\u003C/li>\n\u003Cli>✅ Removed Pareto and Capability chart sections\u003C/li>\n\u003Cli>✅ Removed unused \u003Ccode dir=\"auto\">selectedChannel\u003C/code> variable\u003C/li>\n\u003Cli>✅ Updated Boxplot label: “Worst 15 Channels (Click to Analyze)”\u003C/li>\n\u003Cli>✅ Updated file header comment\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-features-implemented\">Key Features Implemented\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-features-implemented\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Features Implemented”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Drill-down Workflow\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Clicking Boxplot triggers confirmation: “Analyze {measureId} in detail? This will switch to standard Dashboard view.”\u003C/li>\n\u003Cli>Confirmation → \u003Ccode dir=\"auto\">onDrillToMeasure(measureId)\u003C/code> → Standard Dashboard with full analysis tools\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Scalability Improvements\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Boxplot expanded from 33% → 100% width\u003C/li>\n\u003Cli>Can display 15 channels clearly (6x improvement from previous 5 at 33% width)\u003C/li>\n\u003Cli>Focus mode shows up to 30 channels (maxDisplayed={Infinity})\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Focus Mode Updates\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Arrow key navigation cycles only between I-Chart and Boxplot\u003C/li>\n\u003Cli>Escape key exits focus mode\u003C/li>\n\u003Cli>Focus mode headings updated to reflect drill-down workflow\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>User Guidance\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>I-Chart tooltip: “Measures ranked by Cpk (lowest first). Click point to analyze in detail.”\u003C/li>\n\u003Cli>Boxplot heading: “Worst 15 Measures (Click to Analyze)”\u003C/li>\n\u003Cli>Confirmation prompts prevent accidental navigation\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"rationale\">Rationale\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#rationale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Rationale”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-remove-pareto-chart\">Why Remove Pareto Chart?\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-remove-pareto-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Remove Pareto Chart?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>At 100+ channels, becomes unreadable (1-2px bars)\u003C/li>\n\u003Cli>I-Chart Y-axis already provides ranking (lowest Cpk = worst)\u003C/li>\n\u003Cli>Color coding shows health status (red/amber/green)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-remove-histogram-capability-chart\">Why Remove Histogram (Capability Chart)?\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-remove-histogram-capability-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Remove Histogram (Capability Chart)?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Standard Dashboard already has histogram via PerformanceCapability\u003C/li>\n\u003Cli>Dashboard offers time-series I-Chart, control limits, brushing, factors\u003C/li>\n\u003Cli>Performance Mode focuses on overview, not detail\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-keep-only-boxplot\">Why Keep Only Boxplot?\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-keep-only-boxplot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Keep Only Boxplot?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>At full width, can show 15-30 boxes clearly\u003C/li>\n\u003Cli>Side-by-side distribution comparison\u003C/li>\n\u003Cli>Shows outliers, quartiles, skewness\u003C/li>\n\u003Cli>Natural drill-down entry point for investigation\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"verification\">Verification\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"build-status\">Build Status\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#build-status\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Build Status”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># ✅ All packages compiled successfully with 0 TypeScript errors\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm build\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"typescript-strict-mode\">TypeScript Strict Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#typescript-strict-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “TypeScript Strict Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>All changes maintain strict type checking\u003C/li>\n\u003Cli>No type errors or warnings\u003C/li>\n\u003Cli>Unused variables removed (selectedChannel in Excel Add-in)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cross-app-consistency\">Cross-App Consistency\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cross-app-consistency\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-App Consistency”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>PWA, Azure, and Excel Add-in all implement identical patterns\u003C/li>\n\u003Cli>Tailwind CSS (PWA/Azure) vs inline styles (Excel) both updated\u003C/li>\n\u003Cli>Base chart variants used in Excel for explicit sizing\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"testing-checklist\">Testing Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#testing-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Testing Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Manual testing recommended:\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> PWA: Load 10-20 column dataset → Verify simplified 2-row layout\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> PWA: Load 100-column dataset → Verify Boxplot shows 15 worst channels\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> PWA: Click Boxplot box → Verify confirmation prompt → Drill to Dashboard\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> PWA: Focus mode → Verify arrow keys cycle between I-Chart and Boxplot only\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Azure: Same tests as PWA\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Excel: Test with Excel Add-in → Verify base variants render correctly\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Excel: Test confirmation prompt and drill-down workflow\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"benefits\">Benefits\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#benefits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Benefits”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Readability\u003C/strong>: Boxplot 6x wider → Can show 3x more channels clearly\u003C/li>\n\u003Cli>\u003Cstrong>Simplicity\u003C/strong>: 2 charts instead of 4 → Less cognitive load\u003C/li>\n\u003Cli>\u003Cstrong>Workflow\u003C/strong>: Clear path from overview → drill-down → investigation\u003C/li>\n\u003Cli>\u003Cstrong>Performance\u003C/strong>: Removed 2 chart components → Faster rendering\u003C/li>\n\u003Cli>\u003Cstrong>Scalability\u003C/strong>: Optimized for 100+ columns without sacrificing clarity\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"rollback-plan\">Rollback Plan\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#rollback-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Rollback Plan”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>If issues arise, revert the following commits (in order):\u003C/p>\n\u003Col>\n\u003Cli>\u003Ccode dir=\"auto\">apps/excel-addin/src/content/ContentPerformanceDashboard.tsx\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">apps/azure/src/components/PerformanceDashboard.tsx\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">apps/pwa/src/components/PerformanceDashboard.tsx\u003C/code>\u003C/li>\n\u003C/ol>\n\u003Cp>All changes are layout-only, no data structure modifications.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"notes\">Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>PerformancePareto and PerformanceCapability charts remain in \u003Ccode dir=\"auto\">@variscout/charts\u003C/code> package (not deleted)\u003C/li>\n\u003Cli>Charts can be used in other contexts or custom implementations\u003C/li>\n\u003Cli>Focus is on Performance Mode dashboard optimization only\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ TypeScript compiles with 0 errors\u003C/li>\n\u003Cli>✅ All 3 apps updated consistently (PWA, Azure, Excel)\u003C/li>\n\u003Cli>✅ Grid layout simplified (2 rows instead of 4 charts)\u003C/li>\n\u003Cli>✅ Boxplot maxDisplayed increased from 5 → 15 (3x improvement)\u003C/li>\n\u003Cli>✅ Focus mode updated (only I-Chart and Boxplot navigation)\u003C/li>\n\u003Cli>✅ Confirmation prompts added for drill-down workflow\u003C/li>\n\u003Cli>✅ User guidance tooltips added (I-Chart info icon)\u003C/li>\n\u003Cli>✅ File header comments updated to reflect new architecture\u003C/li>\n\u003C/ul>", + { + "headings": 3594, + "localImagePaths": 3650, + "remoteImagePaths": 3651, + "frontmatter": 3652, + "imagePaths": 3653 + }, + [ + 3595, 3597, 3598, 3601, 3604, 3605, 3608, 3611, 3614, 3617, 3618, 3621, 3624, 3627, 3630, 3633, + 3636, 3639, 3642, 3643, 3646, 3649 + ], + { "depth": 30, "slug": 3596, "text": 3584 }, + "performance-mode-optimization---implementation-summary", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 3599, "text": 3600 }, + "changes-made", + "Changes Made", + { "depth": 79, "slug": 3602, "text": 3603 }, + "layout-transformation", + "Layout Transformation", + { "depth": 79, "slug": 3552, "text": 3553 }, + { "depth": 621, "slug": 3606, "text": 3607 }, + "1-pwa-appspwasrccomponentsperformancedashboardtsx", + "1. PWA (apps/pwa/src/components/PerformanceDashboard.tsx)", + { "depth": 621, "slug": 3609, "text": 3610 }, + "2-azure-app-appsazuresrccomponentsperformancedashboardtsx", + "2. Azure App (apps/azure/src/components/PerformanceDashboard.tsx)", + { "depth": 621, "slug": 3612, "text": 3613 }, + "3-excel-add-in-appsexcel-addinsrccontentcontentperformancedashboardtsx", + "3. Excel Add-in (apps/excel-addin/src/content/ContentPerformanceDashboard.tsx)", + { "depth": 79, "slug": 3615, "text": 3616 }, + "key-features-implemented", + "Key Features Implemented", + { "depth": 33, "slug": 2527, "text": 2528 }, + { "depth": 79, "slug": 3619, "text": 3620 }, + "why-remove-pareto-chart", + "Why Remove Pareto Chart?", + { "depth": 79, "slug": 3622, "text": 3623 }, + "why-remove-histogram-capability-chart", + "Why Remove Histogram (Capability Chart)?", + { "depth": 79, "slug": 3625, "text": 3626 }, + "why-keep-only-boxplot", + "Why Keep Only Boxplot?", + { "depth": 33, "slug": 3628, "text": 3629 }, + "verification", + "Verification", + { "depth": 79, "slug": 3631, "text": 3632 }, + "build-status", + "Build Status", + { "depth": 79, "slug": 3634, "text": 3635 }, + "typescript-strict-mode", + "TypeScript Strict Mode", + { "depth": 79, "slug": 3637, "text": 3638 }, + "cross-app-consistency", + "Cross-App Consistency", + { "depth": 33, "slug": 3640, "text": 3641 }, + "testing-checklist", + "Testing Checklist", + { "depth": 33, "slug": 2156, "text": 2157 }, + { "depth": 33, "slug": 3644, "text": 3645 }, + "rollback-plan", + "Rollback Plan", + { "depth": 33, "slug": 3647, "text": 3648 }, + "notes", + "Notes", + { "depth": 33, "slug": 1417, "text": 1418 }, + [], + [], + { "title": 3584 }, + [], + "archive/phase1-complete", + { "id": 3654, "data": 3656, "body": 3661, "filePath": 3662, "digest": 3663, "rendered": 3664 }, + { + "title": 3657, + "editUrl": 16, + "head": 3658, + "template": 18, + "sidebar": 3659, + "pagefind": 16, + "draft": 20 + }, + "Phase 1 Complete: Minitab-Style Brushing Implementation", + [], + { "hidden": 20, "attrs": 3660 }, + {}, + "> **ARCHIVED**: This document describes historical implementation details. Do not reference for current work.\n\n# Phase 1 Complete: Minitab-Style Brushing Implementation\n\n## ✅ What Was Implemented\n\n### Core Infrastructure (Phase 1)\n\n1. **`useMultiSelection` Hook** (`packages/charts/src/hooks/useMultiSelection.ts`)\n - ✅ Rectangular brush selection via mouse drag\n - ✅ Point matching within brush extent using scale inversions\n - ✅ Ctrl+click to toggle individual points\n - ✅ Shift+click to add points to selection\n - ✅ Visual styling helpers (opacity, size, stroke)\n - ✅ Proper event handling and bounds clamping\n\n2. **Selection State Management** (`packages/hooks/src/useDataState.ts`)\n - ✅ `selectedPoints: Set\u003Cnumber>` - O(1) lookup performance\n - ✅ `selectionIndexMap: Map\u003Cnumber, number>` - filtered→original index mapping\n - ✅ Selection actions: `setSelectedPoints`, `addToSelection`, `removeFromSelection`, `clearSelection`, `togglePointSelection`\n - ✅ Auto-clear selection when filters change (prevents user confusion)\n\n3. **IChart Brush Integration** (`packages/charts/src/IChart.tsx`)\n - ✅ New props: `enableBrushSelection`, `selectedPoints`, `onSelectionChange`\n - ✅ Brush rectangle rendering with blue highlight\n - ✅ Selected points: 6px radius, 2px white stroke, full opacity\n - ✅ Unselected points (when selection exists): 0.3 opacity (dimmed)\n - ✅ Maintains semantic colors (red/green/amber/blue) during selection\n\n4. **Unit Tests** (`packages/charts/src/hooks/__tests__/useMultiSelection.test.ts`)\n - ✅ Selection detection tests\n - ✅ Opacity/size/stroke calculation tests\n - ✅ Modifier key interaction tests (Ctrl, Shift, regular click)\n - ✅ Enable/disable brush behavior tests\n\n5. **Documentation**\n - ✅ Feature overview (`docs/features/MINITAB_BRUSHING.md`)\n - ✅ Usage examples (`docs/features/BRUSHING_USAGE_EXAMPLE.md`)\n - ✅ Implementation notes and architecture\n\n## 🎯 Key Features\n\n### User Interactions\n\n```\n✅ Drag to select rectangular region\n✅ Ctrl+Click: Toggle individual point\n✅ Shift+Click: Add point to selection\n✅ Regular Click: Replace selection with point\n✅ Visual feedback: Selected (larger, white stroke), Unselected (dimmed)\n```\n\n### Architecture Highlights\n\n```\n✅ Controlled component pattern (props-based)\n✅ Central state in DataContext for cross-chart sync (Phase 2)\n✅ Efficient Set-based selection (O(1) lookup)\n✅ Automatic filter change handling\n✅ Platform-agnostic (PWA/Azure/Excel ready)\n```\n\n### Visual Design\n\n```\nSelected Points:\n ✅ Size: 6px radius (+2px)\n ✅ Stroke: 2px white\n ✅ Opacity: 1.0 (full)\n\nUnselected Points (when selection exists):\n ✅ Size: 4px (default)\n ✅ Opacity: 0.3 (dimmed)\n\nBrush Rectangle:\n ✅ Fill: rgba(59, 130, 246, 0.1)\n ✅ Stroke: rgba(59, 130, 246, 0.5)\n ✅ Cursor: crosshair\n```\n\n## 📊 Comparison with Minitab\n\n| Feature | Minitab | VariScout Phase 1 | Status |\n| --------------------- | ------- | ----------------- | -------- |\n| Rectangular brush | ✅ | ✅ | Complete |\n| Multi-point selection | ✅ | ✅ | Complete |\n| Ctrl/Shift modifiers | ✅ | ✅ | Complete |\n| Visual dimming | ✅ | ✅ | Complete |\n| Cross-chart sync | ✅ | ⏳ | Phase 2 |\n| Selection info panel | ✅ | ⏳ | Phase 3 |\n| Filter to selection | ✅ | ⏳ | Phase 3 |\n| Export selected | ✅ | ⏳ | Phase 3 |\n| Indicator column | ✅ | ⏳ | Phase 3 |\n\n## 🚀 How to Use (Phase 1)\n\n### Basic Usage in Dashboard\n\n```tsx\nimport { useData } from '../context/DataContext';\nimport { IChart } from '@variscout/charts';\n\nconst Dashboard = () => {\n const { selectedPoints, setSelectedPoints, clearSelection } = useData();\n\n return (\n \u003C>\n {selectedPoints.size > 0 && (\n \u003Cdiv>\n {selectedPoints.size} points selected\n \u003Cbutton onClick={clearSelection}>Clear\u003C/button>\n \u003C/div>\n )}\n\n \u003CIChart\n enableBrushSelection={true}\n selectedPoints={selectedPoints}\n onSelectionChange={indices => setSelectedPoints(indices)}\n {...otherProps}\n />\n \u003C/>\n );\n};\n```\n\n### Interaction Demo\n\n1. **Enable brushing**: Set `enableBrushSelection={true}` on IChart\n2. **Drag to select**: Click and drag to draw selection rectangle\n3. **Modify selection**: Ctrl+click to toggle, Shift+click to add\n4. **Clear selection**: Call `clearSelection()` action\n\n## 📁 Files Modified/Created\n\n### Created\n\n- ✅ `packages/charts/src/hooks/useMultiSelection.ts` (242 lines)\n- ✅ `packages/charts/src/hooks/__tests__/useMultiSelection.test.ts` (280 lines)\n- ✅ `docs/features/MINITAB_BRUSHING.md` (270 lines)\n- ✅ `docs/features/BRUSHING_USAGE_EXAMPLE.md` (380 lines)\n\n### Modified\n\n- ✅ `packages/hooks/src/useDataState.ts` (+45 lines)\n- ✅ `packages/charts/src/IChart.tsx` (+35 lines)\n- ✅ `packages/charts/src/types.ts` (+5 lines)\n- ✅ `packages/charts/src/index.ts` (+6 lines)\n\n**Total**: ~1,260 lines added across 8 files\n\n## ⏭️ Next Phases\n\n### Phase 2: Cross-Chart Sync (1-2 days)\n\n- [ ] Wire up ScatterPlot with brush selection\n- [ ] Wire up Boxplot (category-level selection)\n- [ ] Test synchronization across all charts\n- [ ] Implement data table bi-directional sync\n\n### Phase 3: Selection Panel + Actions (2 days)\n\n- [ ] Build `SelectionPanel` component (PWA/Tailwind)\n- [ ] Show selected rows with values (first 5 + \"and N more\")\n- [ ] Actions: Clear, Filter to selection, Export to CSV\n- [ ] Create indicator column (0/1 for selected/unselected)\n\n### Phase 4: Performance Mode (1 day)\n\n- [ ] Channel-level selection in PerformanceIChart\n- [ ] Convert channel selection to point indices on drill-down\n- [ ] Test with multi-measure datasets\n\n### Phase 5: Excel Add-in (1-2 days)\n\n- [ ] Create Fluent UI variant of SelectionPanel\n- [ ] Integrate with state bridge\n- [ ] Test with Excel tables and slicers\n\n### Phase 6: Polish + Edge Cases (1 day)\n\n- [ ] Keyboard shortcuts (Escape to clear)\n- [ ] Mobile touch handling\n- [ ] Empty selection states\n- [ ] Large dataset performance testing (1000+ points)\n\n**Total Remaining Effort**: 7-9 days\n\n## 🎉 Benefits Delivered\n\n1. **Minitab-Style UX**: Familiar interaction pattern for quality professionals\n2. **Multi-Point Analysis**: Investigate outliers across views\n3. **Clean Architecture**: Props-based, controlled component pattern\n4. **Cross-Platform**: Works in PWA, Azure, Excel (when integrated)\n5. **Performance**: O(1) selection lookups with Set-based state\n6. **Extensible**: Easy to add more charts in Phase 2\n\n## 🐛 Known Limitations (Phase 1)\n\n1. **Single Chart Only**: Only IChart has brush selection (ScatterPlot/Boxplot in Phase 2)\n2. **No Selection Panel**: Visual feedback only (panel in Phase 3)\n3. **No Persistence**: Selection not saved (intentional - transient tool)\n4. **No Touch Support**: Desktop-only (mobile in Phase 6)\n5. **Filter Clears Selection**: Auto-clear on filter change (warning banner in Phase 3)\n\n## 📈 Performance Notes\n\n- **Selection Lookup**: O(1) using `Set\u003Cnumber>`\n- **Brush Calculation**: ~1ms for 1000 points (scale inversions)\n- **Re-render Efficiency**: Only selected/unselected points re-render\n- **Memory**: ~200 bytes per selected point (Set overhead)\n\n## ✅ Testing Coverage\n\n### Unit Tests (9 tests)\n\n- ✅ Selection state initialization\n- ✅ Selected point detection\n- ✅ Opacity calculation (selected vs unselected)\n- ✅ Size calculation (6px vs 4px)\n- ✅ Stroke width calculation (2px vs 1px)\n- ✅ Ctrl+click toggle behavior\n- ✅ Shift+click add behavior\n- ✅ Regular click replace behavior\n- ✅ Brush enable/disable behavior\n\n### Integration Tests (Pending)\n\n- ⏳ Cross-chart selection sync (Phase 2)\n- ⏳ Data table bi-directional sync (Phase 2)\n- ⏳ Filter-to-selection action (Phase 3)\n- ⏳ Export-to-CSV action (Phase 3)\n\n## 🔗 Quick Links\n\n- **Feature Docs**: `docs/features/MINITAB_BRUSHING.md`\n- **Usage Examples**: `docs/features/BRUSHING_USAGE_EXAMPLE.md`\n- **Hook Implementation**: `packages/charts/src/hooks/useMultiSelection.ts`\n- **State Management**: `packages/hooks/src/useDataState.ts`\n- **IChart Integration**: `packages/charts/src/IChart.tsx`\n- **Unit Tests**: `packages/charts/src/hooks/__tests__/useMultiSelection.test.ts`\n\n## 🎬 Demo Video (To Be Recorded)\n\n_Placeholder for screen recording showing:_\n\n1. Rectangular brush selection\n2. Ctrl+click to toggle points\n3. Shift+click to add points\n4. Visual feedback (dimming/highlighting)\n5. Selection clear action\n\n---\n\n**Status**: ✅ Phase 1 Complete (2024-02-04)\n**Next**: Phase 2 - Cross-Chart Synchronization\n**Total Implementation Time**: ~3 hours\n**Code Quality**: TypeScript strict mode, unit tested, documented", + "src/content/docs/archive/phase1-complete.md", + "825a1bc4ec768f63", + { "html": 3665, "metadata": 3666 }, + "\u003Cblockquote>\n\u003Cp>\u003Cstrong>ARCHIVED\u003C/strong>: This document describes historical implementation details. Do not reference for current work.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"phase-1-complete-minitab-style-brushing-implementation\">Phase 1 Complete: Minitab-Style Brushing Implementation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#phase-1-complete-minitab-style-brushing-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 1 Complete: Minitab-Style Brushing Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-what-was-implemented\">✅ What Was Implemented\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-what-was-implemented\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “✅ What Was Implemented”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-infrastructure-phase-1\">Core Infrastructure (Phase 1)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-infrastructure-phase-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Infrastructure (Phase 1)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>\u003Ccode dir=\"auto\">useMultiSelection\u003C/code> Hook\u003C/strong> (\u003Ccode dir=\"auto\">packages/charts/src/hooks/useMultiSelection.ts\u003C/code>)\u003C/p>\n\u003Cul>\n\u003Cli>✅ Rectangular brush selection via mouse drag\u003C/li>\n\u003Cli>✅ Point matching within brush extent using scale inversions\u003C/li>\n\u003Cli>✅ Ctrl+click to toggle individual points\u003C/li>\n\u003Cli>✅ Shift+click to add points to selection\u003C/li>\n\u003Cli>✅ Visual styling helpers (opacity, size, stroke)\u003C/li>\n\u003Cli>✅ Proper event handling and bounds clamping\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Selection State Management\u003C/strong> (\u003Ccode dir=\"auto\">packages/hooks/src/useDataState.ts\u003C/code>)\u003C/p>\n\u003Cul>\n\u003Cli>✅ \u003Ccode dir=\"auto\">selectedPoints: Set<number>\u003C/code> - O(1) lookup performance\u003C/li>\n\u003Cli>✅ \u003Ccode dir=\"auto\">selectionIndexMap: Map<number, number>\u003C/code> - filtered→original index mapping\u003C/li>\n\u003Cli>✅ Selection actions: \u003Ccode dir=\"auto\">setSelectedPoints\u003C/code>, \u003Ccode dir=\"auto\">addToSelection\u003C/code>, \u003Ccode dir=\"auto\">removeFromSelection\u003C/code>, \u003Ccode dir=\"auto\">clearSelection\u003C/code>, \u003Ccode dir=\"auto\">togglePointSelection\u003C/code>\u003C/li>\n\u003Cli>✅ Auto-clear selection when filters change (prevents user confusion)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>IChart Brush Integration\u003C/strong> (\u003Ccode dir=\"auto\">packages/charts/src/IChart.tsx\u003C/code>)\u003C/p>\n\u003Cul>\n\u003Cli>✅ New props: \u003Ccode dir=\"auto\">enableBrushSelection\u003C/code>, \u003Ccode dir=\"auto\">selectedPoints\u003C/code>, \u003Ccode dir=\"auto\">onSelectionChange\u003C/code>\u003C/li>\n\u003Cli>✅ Brush rectangle rendering with blue highlight\u003C/li>\n\u003Cli>✅ Selected points: 6px radius, 2px white stroke, full opacity\u003C/li>\n\u003Cli>✅ Unselected points (when selection exists): 0.3 opacity (dimmed)\u003C/li>\n\u003Cli>✅ Maintains semantic colors (red/green/amber/blue) during selection\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Unit Tests\u003C/strong> (\u003Ccode dir=\"auto\">packages/charts/src/hooks/__tests__/useMultiSelection.test.ts\u003C/code>)\u003C/p>\n\u003Cul>\n\u003Cli>✅ Selection detection tests\u003C/li>\n\u003Cli>✅ Opacity/size/stroke calculation tests\u003C/li>\n\u003Cli>✅ Modifier key interaction tests (Ctrl, Shift, regular click)\u003C/li>\n\u003Cli>✅ Enable/disable brush behavior tests\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Documentation\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>✅ Feature overview (\u003Ccode dir=\"auto\">docs/features/MINITAB_BRUSHING.md\u003C/code>)\u003C/li>\n\u003Cli>✅ Usage examples (\u003Ccode dir=\"auto\">docs/features/BRUSHING_USAGE_EXAMPLE.md\u003C/code>)\u003C/li>\n\u003Cli>✅ Implementation notes and architecture\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-key-features\">🎯 Key Features\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-key-features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “🎯 Key Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-interactions\">User Interactions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-interactions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Interactions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Drag to select rectangular region\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Ctrl+Click: Toggle individual point\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Shift+Click: Add point to selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Regular Click: Replace selection with point\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Visual feedback: Selected (larger, white stroke), Unselected (dimmed)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"✅ Drag to select rectangular region✅ Ctrl+Click: Toggle individual point✅ Shift+Click: Add point to selection✅ Regular Click: Replace selection with point✅ Visual feedback: Selected (larger, white stroke), Unselected (dimmed)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"architecture-highlights\">Architecture Highlights\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#architecture-highlights\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture Highlights”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Controlled component pattern (props-based)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Central state in DataContext for cross-chart sync (Phase 2)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Efficient Set-based selection (O(1) lookup)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Automatic filter change handling\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Platform-agnostic (PWA/Azure/Excel ready)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"✅ Controlled component pattern (props-based)✅ Central state in DataContext for cross-chart sync (Phase 2)✅ Efficient Set-based selection (O(1) lookup)✅ Automatic filter change handling✅ Platform-agnostic (PWA/Azure/Excel ready)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"visual-design\">Visual Design\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#visual-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Selected Points:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Size: 6px radius (+2px)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Stroke: 2px white\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Opacity: 1.0 (full)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Unselected Points (when selection exists):\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Size: 4px (default)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Opacity: 0.3 (dimmed)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Brush Rectangle:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Fill: rgba(59, 130, 246, 0.1)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Stroke: rgba(59, 130, 246, 0.5)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">✅ Cursor: crosshair\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Selected Points: ✅ Size: 6px radius (+2px) ✅ Stroke: 2px white ✅ Opacity: 1.0 (full)Unselected Points (when selection exists): ✅ Size: 4px (default) ✅ Opacity: 0.3 (dimmed)Brush Rectangle: ✅ Fill: rgba(59, 130, 246, 0.1) ✅ Stroke: rgba(59, 130, 246, 0.5) ✅ Cursor: crosshair\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-comparison-with-minitab\">📊 Comparison with Minitab\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-comparison-with-minitab\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “📊 Comparison with Minitab”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Minitab\u003C/th>\u003Cth>VariScout Phase 1\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Rectangular brush\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>Complete\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multi-point selection\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>Complete\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Ctrl/Shift modifiers\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>Complete\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Visual dimming\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>Complete\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cross-chart sync\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>⏳\u003C/td>\u003Ctd>Phase 2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Selection info panel\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>⏳\u003C/td>\u003Ctd>Phase 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filter to selection\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>⏳\u003C/td>\u003Ctd>Phase 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Export selected\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>⏳\u003C/td>\u003Ctd>Phase 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Indicator column\u003C/td>\u003Ctd>✅\u003C/td>\u003Ctd>⏳\u003C/td>\u003Ctd>Phase 3\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-how-to-use-phase-1\">🚀 How to Use (Phase 1)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-how-to-use-phase-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “🚀 How to Use (Phase 1)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"basic-usage-in-dashboard\">Basic Usage in Dashboard\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#basic-usage-in-dashboard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Basic Usage in Dashboard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useData } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">../context/DataContext\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { IChart } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Dashboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">clearSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">size\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">size\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> points selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">clearSelection\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Clear\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">enableBrushSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onSelectionChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">indices\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(indices)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">otherProps\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useData } from '../context/DataContext';import { IChart } from '@variscout/charts';const Dashboard = () => { const { selectedPoints, setSelectedPoints, clearSelection } = useData(); return ( \u003C> {selectedPoints.size > 0 && ( \u003Cdiv> {selectedPoints.size} points selected \u003Cbutton onClick={clearSelection}>Clear\u003C/button> \u003C/div> )} \u003CIChart enableBrushSelection={true} selectedPoints={selectedPoints} onSelectionChange={indices => setSelectedPoints(indices)} {...otherProps} /> \u003C/> );};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interaction-demo\">Interaction Demo\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interaction-demo\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interaction Demo”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Enable brushing\u003C/strong>: Set \u003Ccode dir=\"auto\">enableBrushSelection={true}\u003C/code> on IChart\u003C/li>\n\u003Cli>\u003Cstrong>Drag to select\u003C/strong>: Click and drag to draw selection rectangle\u003C/li>\n\u003Cli>\u003Cstrong>Modify selection\u003C/strong>: Ctrl+click to toggle, Shift+click to add\u003C/li>\n\u003Cli>\u003Cstrong>Clear selection\u003C/strong>: Call \u003Ccode dir=\"auto\">clearSelection()\u003C/code> action\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-files-modifiedcreated\">📁 Files Modified/Created\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-files-modifiedcreated\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “📁 Files Modified/Created”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"created\">Created\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#created\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Created”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ \u003Ccode dir=\"auto\">packages/charts/src/hooks/useMultiSelection.ts\u003C/code> (242 lines)\u003C/li>\n\u003Cli>✅ \u003Ccode dir=\"auto\">packages/charts/src/hooks/__tests__/useMultiSelection.test.ts\u003C/code> (280 lines)\u003C/li>\n\u003Cli>✅ \u003Ccode dir=\"auto\">docs/features/MINITAB_BRUSHING.md\u003C/code> (270 lines)\u003C/li>\n\u003Cli>✅ \u003Ccode dir=\"auto\">docs/features/BRUSHING_USAGE_EXAMPLE.md\u003C/code> (380 lines)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"modified\">Modified\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#modified\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Modified”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ \u003Ccode dir=\"auto\">packages/hooks/src/useDataState.ts\u003C/code> (+45 lines)\u003C/li>\n\u003Cli>✅ \u003Ccode dir=\"auto\">packages/charts/src/IChart.tsx\u003C/code> (+35 lines)\u003C/li>\n\u003Cli>✅ \u003Ccode dir=\"auto\">packages/charts/src/types.ts\u003C/code> (+5 lines)\u003C/li>\n\u003Cli>✅ \u003Ccode dir=\"auto\">packages/charts/src/index.ts\u003C/code> (+6 lines)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Total\u003C/strong>: ~1,260 lines added across 8 files\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"️-next-phases\">⏭️ Next Phases\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#️-next-phases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “⏭️ Next Phases”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-2-cross-chart-sync-1-2-days\">Phase 2: Cross-Chart Sync (1-2 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-cross-chart-sync-1-2-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2: Cross-Chart Sync (1-2 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Wire up ScatterPlot with brush selection\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Wire up Boxplot (category-level selection)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Test synchronization across all charts\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Implement data table bi-directional sync\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-3-selection-panel--actions-2-days\">Phase 3: Selection Panel + Actions (2 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3-selection-panel--actions-2-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3: Selection Panel + Actions (2 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Build \u003Ccode dir=\"auto\">SelectionPanel\u003C/code> component (PWA/Tailwind)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Show selected rows with values (first 5 + “and N more”)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Actions: Clear, Filter to selection, Export to CSV\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Create indicator column (0/1 for selected/unselected)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-4-performance-mode-1-day\">Phase 4: Performance Mode (1 day)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-4-performance-mode-1-day\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 4: Performance Mode (1 day)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Channel-level selection in PerformanceIChart\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Convert channel selection to point indices on drill-down\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Test with multi-measure datasets\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-5-excel-add-in-1-2-days\">Phase 5: Excel Add-in (1-2 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-5-excel-add-in-1-2-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 5: Excel Add-in (1-2 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Create Fluent UI variant of SelectionPanel\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Integrate with state bridge\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Test with Excel tables and slicers\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-6-polish--edge-cases-1-day\">Phase 6: Polish + Edge Cases (1 day)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-6-polish--edge-cases-1-day\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 6: Polish + Edge Cases (1 day)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Keyboard shortcuts (Escape to clear)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Mobile touch handling\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Empty selection states\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Large dataset performance testing (1000+ points)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Total Remaining Effort\u003C/strong>: 7-9 days\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-benefits-delivered\">🎉 Benefits Delivered\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-benefits-delivered\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “🎉 Benefits Delivered”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Minitab-Style UX\u003C/strong>: Familiar interaction pattern for quality professionals\u003C/li>\n\u003Cli>\u003Cstrong>Multi-Point Analysis\u003C/strong>: Investigate outliers across views\u003C/li>\n\u003Cli>\u003Cstrong>Clean Architecture\u003C/strong>: Props-based, controlled component pattern\u003C/li>\n\u003Cli>\u003Cstrong>Cross-Platform\u003C/strong>: Works in PWA, Azure, Excel (when integrated)\u003C/li>\n\u003Cli>\u003Cstrong>Performance\u003C/strong>: O(1) selection lookups with Set-based state\u003C/li>\n\u003Cli>\u003Cstrong>Extensible\u003C/strong>: Easy to add more charts in Phase 2\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-known-limitations-phase-1\">🐛 Known Limitations (Phase 1)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-known-limitations-phase-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “🐛 Known Limitations (Phase 1)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Single Chart Only\u003C/strong>: Only IChart has brush selection (ScatterPlot/Boxplot in Phase 2)\u003C/li>\n\u003Cli>\u003Cstrong>No Selection Panel\u003C/strong>: Visual feedback only (panel in Phase 3)\u003C/li>\n\u003Cli>\u003Cstrong>No Persistence\u003C/strong>: Selection not saved (intentional - transient tool)\u003C/li>\n\u003Cli>\u003Cstrong>No Touch Support\u003C/strong>: Desktop-only (mobile in Phase 6)\u003C/li>\n\u003Cli>\u003Cstrong>Filter Clears Selection\u003C/strong>: Auto-clear on filter change (warning banner in Phase 3)\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-performance-notes\">📈 Performance Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-performance-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “📈 Performance Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Selection Lookup\u003C/strong>: O(1) using \u003Ccode dir=\"auto\">Set<number>\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Brush Calculation\u003C/strong>: ~1ms for 1000 points (scale inversions)\u003C/li>\n\u003Cli>\u003Cstrong>Re-render Efficiency\u003C/strong>: Only selected/unselected points re-render\u003C/li>\n\u003Cli>\u003Cstrong>Memory\u003C/strong>: ~200 bytes per selected point (Set overhead)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-testing-coverage\">✅ Testing Coverage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-testing-coverage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “✅ Testing Coverage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"unit-tests-9-tests\">Unit Tests (9 tests)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#unit-tests-9-tests\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Unit Tests (9 tests)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ Selection state initialization\u003C/li>\n\u003Cli>✅ Selected point detection\u003C/li>\n\u003Cli>✅ Opacity calculation (selected vs unselected)\u003C/li>\n\u003Cli>✅ Size calculation (6px vs 4px)\u003C/li>\n\u003Cli>✅ Stroke width calculation (2px vs 1px)\u003C/li>\n\u003Cli>✅ Ctrl+click toggle behavior\u003C/li>\n\u003Cli>✅ Shift+click add behavior\u003C/li>\n\u003Cli>✅ Regular click replace behavior\u003C/li>\n\u003Cli>✅ Brush enable/disable behavior\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"integration-tests-pending\">Integration Tests (Pending)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#integration-tests-pending\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integration Tests (Pending)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>⏳ Cross-chart selection sync (Phase 2)\u003C/li>\n\u003Cli>⏳ Data table bi-directional sync (Phase 2)\u003C/li>\n\u003Cli>⏳ Filter-to-selection action (Phase 3)\u003C/li>\n\u003Cli>⏳ Export-to-CSV action (Phase 3)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-quick-links\">🔗 Quick Links\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-quick-links\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “🔗 Quick Links”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Feature Docs\u003C/strong>: \u003Ccode dir=\"auto\">docs/features/MINITAB_BRUSHING.md\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Usage Examples\u003C/strong>: \u003Ccode dir=\"auto\">docs/features/BRUSHING_USAGE_EXAMPLE.md\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Hook Implementation\u003C/strong>: \u003Ccode dir=\"auto\">packages/charts/src/hooks/useMultiSelection.ts\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>State Management\u003C/strong>: \u003Ccode dir=\"auto\">packages/hooks/src/useDataState.ts\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>IChart Integration\u003C/strong>: \u003Ccode dir=\"auto\">packages/charts/src/IChart.tsx\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Unit Tests\u003C/strong>: \u003Ccode dir=\"auto\">packages/charts/src/hooks/__tests__/useMultiSelection.test.ts\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"-demo-video-to-be-recorded\">🎬 Demo Video (To Be Recorded)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#-demo-video-to-be-recorded\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “🎬 Demo Video (To Be Recorded)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>Placeholder for screen recording showing:\u003C/em>\u003C/p>\n\u003Col>\n\u003Cli>Rectangular brush selection\u003C/li>\n\u003Cli>Ctrl+click to toggle points\u003C/li>\n\u003Cli>Shift+click to add points\u003C/li>\n\u003Cli>Visual feedback (dimming/highlighting)\u003C/li>\n\u003Cli>Selection clear action\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: ✅ Phase 1 Complete (2024-02-04)\n\u003Cstrong>Next\u003C/strong>: Phase 2 - Cross-Chart Synchronization\n\u003Cstrong>Total Implementation Time\u003C/strong>: ~3 hours\n\u003Cstrong>Code Quality\u003C/strong>: TypeScript strict mode, unit tested, documented\u003C/p>", + { + "headings": 3667, + "localImagePaths": 3741, + "remoteImagePaths": 3742, + "frontmatter": 3743, + "imagePaths": 3744 + }, + [ + 3668, 3670, 3673, 3676, 3679, 3682, 3685, 3688, 3691, 3694, 3697, 3700, 3703, 3706, 3709, 3712, + 3713, 3714, 3715, 3716, 3717, 3720, 3723, 3726, 3729, 3732, 3735, 3738 + ], + { "depth": 30, "slug": 3669, "text": 3657 }, + "phase-1-complete-minitab-style-brushing-implementation", + { "depth": 33, "slug": 3671, "text": 3672 }, + "-what-was-implemented", + "✅ What Was Implemented", + { "depth": 79, "slug": 3674, "text": 3675 }, + "core-infrastructure-phase-1", + "Core Infrastructure (Phase 1)", + { "depth": 33, "slug": 3677, "text": 3678 }, + "-key-features", + "🎯 Key Features", + { "depth": 79, "slug": 3680, "text": 3681 }, + "user-interactions", + "User Interactions", + { "depth": 79, "slug": 3683, "text": 3684 }, + "architecture-highlights", + "Architecture Highlights", + { "depth": 79, "slug": 3686, "text": 3687 }, + "visual-design", + "Visual Design", + { "depth": 33, "slug": 3689, "text": 3690 }, + "-comparison-with-minitab", + "📊 Comparison with Minitab", + { "depth": 33, "slug": 3692, "text": 3693 }, + "-how-to-use-phase-1", + "🚀 How to Use (Phase 1)", + { "depth": 79, "slug": 3695, "text": 3696 }, + "basic-usage-in-dashboard", + "Basic Usage in Dashboard", + { "depth": 79, "slug": 3698, "text": 3699 }, + "interaction-demo", + "Interaction Demo", + { "depth": 33, "slug": 3701, "text": 3702 }, + "-files-modifiedcreated", + "📁 Files Modified/Created", + { "depth": 79, "slug": 3704, "text": 3705 }, + "created", + "Created", + { "depth": 79, "slug": 3707, "text": 3708 }, + "modified", + "Modified", + { "depth": 33, "slug": 3710, "text": 3711 }, + "️-next-phases", + "⏭️ Next Phases", + { "depth": 79, "slug": 3537, "text": 3538 }, + { "depth": 79, "slug": 3540, "text": 3541 }, + { "depth": 79, "slug": 3543, "text": 3544 }, + { "depth": 79, "slug": 3546, "text": 3547 }, + { "depth": 79, "slug": 3549, "text": 3550 }, + { "depth": 33, "slug": 3718, "text": 3719 }, + "-benefits-delivered", + "🎉 Benefits Delivered", + { "depth": 33, "slug": 3721, "text": 3722 }, + "-known-limitations-phase-1", + "🐛 Known Limitations (Phase 1)", + { "depth": 33, "slug": 3724, "text": 3725 }, + "-performance-notes", + "📈 Performance Notes", + { "depth": 33, "slug": 3727, "text": 3728 }, + "-testing-coverage", + "✅ Testing Coverage", + { "depth": 79, "slug": 3730, "text": 3731 }, + "unit-tests-9-tests", + "Unit Tests (9 tests)", + { "depth": 79, "slug": 3733, "text": 3734 }, + "integration-tests-pending", + "Integration Tests (Pending)", + { "depth": 33, "slug": 3736, "text": 3737 }, + "-quick-links", + "🔗 Quick Links", + { "depth": 33, "slug": 3739, "text": 3740 }, + "-demo-video-to-be-recorded", + "🎬 Demo Video (To Be Recorded)", + [], + [], + { "title": 3657 }, + [], + "archive/phases3-5-complete", + { "id": 3745, "data": 3747, "body": 3752, "filePath": 3753, "digest": 3754, "rendered": 3755 }, + { + "title": 3748, + "editUrl": 16, + "head": 3749, + "template": 18, + "sidebar": 3750, + "pagefind": 16, + "draft": 20 + }, + "Phases 3-5 Complete: Data Table Sync + Performance Integration + Polish", + [], + { "hidden": 20, "attrs": 3751 }, + {}, + "> **ARCHIVED**: This document describes historical implementation details. Do not reference for current work.\n\n# Phases 3-5 Complete: Data Table Sync + Performance Integration + Polish\n\n**Date**: 2026-02-04\n**Status**: All Remaining Phases Complete (3/3)\n**Overall Progress**: 5/5 phases (100% complete)\n\n---\n\n## Phase 3: Data Table Sync ✅\n\n### What Was Implemented\n\n**Bi-directional synchronization between IChart and DataTable**:\n\n1. **IChart → DataTable**: When points are brushed in IChart, corresponding rows highlight in the data table with blue background\n2. **DataTable → IChart**: Click a table row to toggle that point in/out of the IChart selection\n3. **Auto-scroll**: Table automatically scrolls to first selected row when selection changes\n4. **Visual Consistency**: Selected rows show `bg-blue-500/20` background, matching IChart selection theme\n\n### Files Modified\n\n**DataPanel Component** (`apps/pwa/src/components/DataPanel.tsx`):\n\n- Added `selectedIndices` prop (Set\u003Cnumber>) for multi-point selection\n- Added `onToggleSelection` callback for row click handling\n- Updated row rendering to show blue background for selected rows\n- Added scroll-to-row logic when selection changes\n- Row click now toggles selection instead of just highlighting\n\n**App Component** (`apps/pwa/src/App.tsx`):\n\n- Added `selectedPoints` and `togglePointSelection` from DataContext\n- Passed props to DataPanel: `selectedIndices={selectedPoints}`, `onToggleSelection={togglePointSelection}`\n\n### User Experience\n\n```\nUser brushes 3 points in IChart (#23, #47, #52)\n ↓\nDataTable rows 23, 47, 52 show blue background\n ↓\nTable scrolls to row 23 (first selected)\n ↓\nUser clicks row 30 in table\n ↓\nPoint #30 highlights in IChart\n ↓\nSelectionPanel updates: \"4 points selected\"\n```\n\n### Technical Implementation\n\n**State Flow**:\n\n```typescript\n// IChart brush → DataContext.selectedPoints\nsetSelectedPoints(new Set([23, 47, 52]))\n ↓\n// DataTable reads selectedPoints\nconst isSelected = selectedIndices?.has(originalIndex)\n ↓\n// Row styling\nclassName={isSelected ? 'bg-blue-500/20' : 'hover:bg-surface-tertiary/50'}\n ↓\n// Table row click → Toggle selection\nonClick={() => onToggleSelection?.(originalIndex)}\n ↓\n// DataContext togglePointSelection\ntogglePointSelection(30) // Adds or removes from set\n```\n\n---\n\n## Phase 4: Performance Mode Integration ✅\n\n### What Was Implemented\n\n**Clear selection when switching modes**:\n\n1. **View Changes**: Selection cleared when switching between Dashboard, Regression, Gage R&R, and Performance views\n2. **Performance Mode Entry**: Selection cleared when entering Performance Mode from detection modal\n3. **Performance Mode Exit**: Selection cleared when returning to Performance Mode from drilled I-Chart\n4. **Manual Entry**: Selection cleared when applying manual entry configuration\n\n### Files Modified\n\n**App Component** (`apps/pwa/src/App.tsx`):\n\n- Added `clearSelection` from DataContext\n- Added `clearSelection()` calls in:\n - `handleViewChange()` - When switching views from settings\n - `handleEnablePerformanceMode()` - When entering Performance Mode from detection\n - `handleBackToPerformance()` - When returning to Performance Mode\n - Manual entry config application - Both Performance and Dashboard modes\n\n### Why This Matters\n\n**Problem**: Selection state persisting across mode changes causes confusion:\n\n- Selected points from standard I-Chart don't make sense in Performance Mode (different data structure)\n- Returning to Performance Mode with stale selection is confusing\n- Switching analysis views should provide fresh start\n\n**Solution**: Proactive clearing ensures clean state transitions:\n\n- Users always start with clear slate when changing modes\n- No stale selection state\n- Predictable behavior across all view transitions\n\n### User Experience\n\n```\nUser has 12 points selected in IChart\n ↓\nUser clicks \"Performance Mode\" in settings\n ↓\nSelection automatically cleared (no warning needed)\n ↓\nPerformance Mode loads with clean state\n ↓\nUser drills into specific measure\n ↓\nStandard I-Chart shows (selection still clear)\n ↓\nUser brushes new points in drilled view\n ↓\nUser clicks \"Back to Performance\"\n ↓\nSelection cleared again\n```\n\n---\n\n## Phase 5: Polish and Edge Cases ✅\n\n### What Was Implemented\n\n**Keyboard Shortcuts**:\n\n1. **Escape Key**: Clear selection when points are selected\n - Added keyboard navigation handler in Dashboard\n - Only active when `selectedPoints.size > 0`\n - Same pattern as existing Focus Mode and Presentation Mode handlers\n\n2. **Visual Hint**: SelectionPanel shows \"(Press Esc to clear)\" hint\n - Displayed next to point count\n - Hidden on mobile (space constraint)\n - Helps users discover keyboard shortcut\n\n### Files Modified\n\n**Dashboard Component** (`apps/pwa/src/components/Dashboard.tsx`):\n\n```typescript\n// Keyboard handler for Selection clearing (Phase 5: Polish)\nuseKeyboardNavigation({\n focusedItem: selectedPoints.size > 0 ? 'selection' : null,\n onEscape: clearSelection,\n});\n```\n\n**SelectionPanel Component** (`packages/ui/src/components/SelectionPanel/SelectionPanel.tsx`):\n\n```typescript\n\u003Cspan className=\"text-sm font-medium text-blue-300\">\n {sortedIndices.length} {sortedIndices.length === 1 ? 'point' : 'points'} selected\n\u003C/span>\n\u003Cspan className=\"text-xs text-content-muted hidden sm:inline\">(Press Esc to clear)\u003C/span>\n```\n\n### User Experience\n\n**Keyboard Shortcut**:\n\n```\nUser has 12 points selected\n ↓\nUser presses Escape key\n ↓\nSelection cleared immediately\n ↓\nSelectionPanel disappears\n ↓\nIChart returns to normal view (no dimmed points)\n```\n\n**Visual Hint**:\n\n```\nSelectionPanel header shows:\n\"12 points selected (Press Esc to clear)\"\n ^\n Helps user discover shortcut\n```\n\n### What Was Already Handled\n\n**Filter Change Behavior** (from Phase 1):\n\n- Selection automatically cleared when filters change\n- Prevents confusion when dataset changes\n- No warning banner needed (immediate clearing is intuitive)\n\n**Performance Characteristics** (from Phase 2):\n\n- SelectionPanel shows max 5 points (no performance issues with large selections)\n- `createFactorFromSelection()` is O(n) - efficient even for 10,000+ rows\n- Selection uses Set (O(1) lookups)\n\n**Mobile Responsiveness** (from Phase 2):\n\n- SelectionPanel responsive layout matches FilterBreadcrumb\n- Blue theme differentiates from gray filter chips\n- Keyboard hint hidden on mobile (sm breakpoint)\n\n---\n\n## Overall Implementation Summary\n\n### All 5 Phases Complete\n\n| Phase | Feature | Status | Effort |\n| ------- | ------------------------------ | ----------- | -------- |\n| Phase 1 | Core Hook + I-Chart Brushing | ✅ Complete | 2-3 days |\n| Phase 2 | SelectionPanel + Create Factor | ✅ Complete | 2 days |\n| Phase 3 | Data Table Sync | ✅ Complete | 1 day |\n| Phase 4 | Performance Mode Integration | ✅ Complete | 1 day |\n| Phase 5 | Polish + Edge Cases | ✅ Complete | 1 day |\n\n**Total Time**: Completed in 2 sessions (Phase 1 earlier, Phases 2-5 today)\n\n---\n\n## Verification Results\n\n### TypeScript Compilation\n\n- ✅ Zero errors related to brushing implementation\n- ✅ All imports resolve correctly\n- ✅ Type safety maintained across all packages\n\n### Build Success\n\n- ✅ `@variscout/ui` package builds successfully\n- ✅ `@variscout/core` exports verified\n- ✅ PWA compiles without errors\n\n### Manual Testing Checklist\n\n**Phase 3 (Data Table Sync)**:\n\n- [x] Brush points in IChart → Table rows highlight\n- [x] Table scrolls to first selected row\n- [x] Click table row → Point toggles in IChart selection\n- [x] Selection count updates in SelectionPanel\n- [x] Bi-directional sync stays consistent\n\n**Phase 4 (Performance Mode)**:\n\n- [x] Switch to Performance Mode → Selection cleared\n- [x] Return to Performance Mode from drill → Selection cleared\n- [x] Switch to Regression view → Selection cleared\n- [x] Switch to Gage R&R view → Selection cleared\n- [x] No stale selection state across modes\n\n**Phase 5 (Polish)**:\n\n- [x] Press Escape → Selection clears\n- [x] Keyboard shortcut hint visible in SelectionPanel\n- [x] Hint hidden on mobile (responsive)\n- [x] Escape handler only active when selection exists\n\n---\n\n## Technical Details\n\n### State Management Flow (Complete)\n\n```\nUser Interaction\n ↓\n┌─────────────────────────────────────────┐\n│ IChart Brushing (Phase 1) │\n│ - Drag to select │\n│ - Ctrl+click to toggle │\n│ - Shift+click to add │\n└─────────────────────────────────────────┘\n ↓\nDataContext.selectedPoints (Set\u003Cnumber>)\n ↓\n┌──────────────────┬──────────────────┬──────────────────┐\n│ │ │ │\n▼ ▼ ▼ ▼\nSelectionPanel DataTable IChart Dashboard\n(Phase 2) (Phase 3) Visual Keyboard\nShows details Blue highlight Selected Escape key\nCreate Factor Click to toggle points (Phase 5)\n Scroll to first larger/white\n stroke\n```\n\n### Keyboard Navigation Integration\n\n**Existing Patterns**:\n\n- Focus Mode: Escape exits focus\n- Presentation Mode: Escape exits presentation\n\n**New Pattern** (Phase 5):\n\n- Selection Mode: Escape clears selection\n- Follows same `useKeyboardNavigation` hook pattern\n- Only active when `selectedPoints.size > 0`\n\n### Auto-Clear Triggers (Phase 4)\n\nSelection cleared in these scenarios:\n\n1. **Filter Change** (Phase 1) - Prevents confusion when dataset changes\n2. **View Change** (Phase 4) - Clean slate for different analysis types\n3. **Performance Mode Entry** (Phase 4) - Different data structure\n4. **Performance Mode Exit** (Phase 4) - Return to overview\n5. **Escape Key** (Phase 5) - User-initiated clear\n\n---\n\n## Files Modified Summary\n\n### Core State (Phase 3-4)\n\n- `packages/hooks/src/useDataState.ts` - Already had selection state (Phase 1)\n- No changes needed - state management complete from Phase 1\n\n### Components (Phase 3, 5)\n\n- `apps/pwa/src/components/DataPanel.tsx` - Added multi-selection support\n- `packages/ui/src/components/SelectionPanel/SelectionPanel.tsx` - Added keyboard hint\n- `apps/pwa/src/components/Dashboard.tsx` - Added Escape key handler\n\n### Integration (Phase 3-4)\n\n- `apps/pwa/src/App.tsx` - Connected DataPanel, added clearSelection calls\n\n### Documentation\n\n- `PHASES3-5_COMPLETE.md` (this file)\n\n---\n\n## Known Behaviors (By Design)\n\n1. **Selection cleared on filter change** (Phase 1) - Prevents confusion\n2. **Selection cleared on mode change** (Phase 4) - Clean state transitions\n3. **IChart-only brushing** (Phase 1) - No ScatterPlot/Boxplot brushing\n4. **No persistent selection** - Ephemeral state, factors are persistent\n5. **No undo for factor creation** (Phase 2) - Factors are permanent columns\n\n---\n\n## User Workflows (Complete End-to-End)\n\n### Workflow 1: Outlier Investigation with Table Sync\n\n```\n1. User brushes 5 high points in IChart\n ↓\n2. SelectionPanel appears: \"5 points selected (Press Esc to clear)\"\n ↓\n3. Data table scrolls to first selected row, shows blue highlight\n ↓\n4. User clicks row 30 in table\n ↓\n5. Point 30 adds to selection, IChart updates\n ↓\n6. SelectionPanel: \"6 points selected\"\n ↓\n7. User clicks \"Create Factor\" → Names \"Temperature Outliers\"\n ↓\n8. System creates factor, auto-filters, clears selection\n ↓\n9. Factor persists for drill-down and export\n```\n\n### Workflow 2: Mode Switching with Clean State\n\n```\n1. User brushes 12 points in standard I-Chart\n ↓\n2. SelectionPanel shows details\n ↓\n3. User switches to Performance Mode in settings\n ↓\n4. Selection automatically cleared (no warning)\n ↓\n5. Performance Mode loads fresh\n ↓\n6. User drills into \"Head_1\" measure\n ↓\n7. Standard I-Chart shows (still no selection)\n ↓\n8. User brushes new points in drilled view\n ↓\n9. User clicks \"Back to Performance\"\n ↓\n10. Selection cleared again, clean return\n```\n\n### Workflow 3: Keyboard Shortcut Usage\n\n```\n1. User brushes 8 points\n ↓\n2. SelectionPanel: \"8 points selected (Press Esc to clear)\"\n ↓\n3. User realizes wrong points selected\n ↓\n4. User presses Escape key\n ↓\n5. Selection clears immediately\n ↓\n6. SelectionPanel disappears\n ↓\n7. IChart returns to normal (no dimming)\n ↓\n8. User brushes correct points\n```\n\n---\n\n## Success Criteria Met ✅\n\n### Phase 3 Requirements\n\n- [x] IChart selection → Table rows highlight\n- [x] Table row click → IChart point highlights\n- [x] Table scrolls to first selected row\n- [x] Bi-directional sync consistent\n- [x] Visual: Blue background on selected rows\n\n### Phase 4 Requirements\n\n- [x] Selection cleared on view change\n- [x] Selection cleared entering Performance Mode\n- [x] Selection cleared exiting Performance Mode\n- [x] No stale selection across modes\n- [x] Clean state transitions\n\n### Phase 5 Requirements\n\n- [x] Escape key clears selection\n- [x] Keyboard hint in SelectionPanel\n- [x] Responsive hint visibility\n- [x] Handler only active when needed\n- [x] Follows existing patterns\n\n### Overall Quality\n\n- [x] TypeScript: 0 errors\n- [x] Build: All packages compile\n- [x] Integration: Seamless across features\n- [x] Performance: No regressions\n- [x] User Experience: Intuitive workflows\n\n---\n\n## Performance Characteristics\n\n### Selection Operations\n\n- **Toggle point**: O(1) - Set add/delete\n- **Clear selection**: O(1) - Set clear\n- **Check if selected**: O(1) - Set has()\n- **Table scroll**: O(n) - Find first selected (n = filtered rows)\n\n### Memory Usage\n\n- **Set storage**: Minimal - just indices (numbers)\n- **No data duplication**: Points reference original data\n- **Scale tested**: Works efficiently with 1000+ points\n\n### Render Performance\n\n- **DataTable**: Only selected rows get different styling\n- **IChart**: Selection state in props (React memo-friendly)\n- **SelectionPanel**: Shows max 5 points (no DOM bloat)\n\n---\n\n## Documentation Created\n\n1. **PHASES3-5_COMPLETE.md** (this file) - Technical summary\n2. **Phase 2 docs still apply**:\n - PHASE2_COMPLETE.md - Technical details\n - CREATE_FACTOR_GUIDE.md - User guide\n - IMPLEMENTATION_SUMMARY.md - Executive summary\n\n---\n\n## What's Next\n\n### Feature Complete! 🎉\n\nAll 5 phases of Minitab-style brushing are now complete:\n\n- ✅ Core brushing interaction (Phase 1)\n- ✅ Create Factor workflow (Phase 2)\n- ✅ Data Table sync (Phase 3)\n- ✅ Performance Mode integration (Phase 4)\n- ✅ Polish and shortcuts (Phase 5)\n\n### Ready for Production\n\nThe brushing feature is now:\n\n- Fully implemented across all components\n- Type-safe and well-tested\n- Documented with user guides\n- Integrated with existing features\n- Polished with keyboard shortcuts\n\n### Potential Future Enhancements (Optional)\n\n- **Ctrl+A to select all points** - Could be added if users request\n- **Selection statistics** - Show mean/std of selected points in panel\n- **Selection history** - Undo/redo for selections\n- **Named selections** - Save selections for later (like bookmarks)\n- **Export selected rows** - Direct export button in SelectionPanel\n\n---\n\n**Status**: ✅ **ALL PHASES COMPLETE**\n**Progress**: 5/5 phases (100%)\n**Ready**: Production-ready implementation", + "src/content/docs/archive/phases3-5-complete.md", + "1722b5675ba56542", + { "html": 3756, "metadata": 3757 }, + "\u003Cblockquote>\n\u003Cp>\u003Cstrong>ARCHIVED\u003C/strong>: This document describes historical implementation details. Do not reference for current work.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"phases-3-5-complete-data-table-sync--performance-integration--polish\">Phases 3-5 Complete: Data Table Sync + Performance Integration + Polish\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#phases-3-5-complete-data-table-sync--performance-integration--polish\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phases 3-5 Complete: Data Table Sync + Performance Integration + Polish”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Date\u003C/strong>: 2026-02-04\n\u003Cstrong>Status\u003C/strong>: All Remaining Phases Complete (3/3)\n\u003Cstrong>Overall Progress\u003C/strong>: 5/5 phases (100% complete)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-3-data-table-sync\">Phase 3: Data Table Sync ✅\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3-data-table-sync\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3: Data Table Sync ✅”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-was-implemented\">What Was Implemented\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-was-implemented\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Was Implemented”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Bi-directional synchronization between IChart and DataTable\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>IChart → DataTable\u003C/strong>: When points are brushed in IChart, corresponding rows highlight in the data table with blue background\u003C/li>\n\u003Cli>\u003Cstrong>DataTable → IChart\u003C/strong>: Click a table row to toggle that point in/out of the IChart selection\u003C/li>\n\u003Cli>\u003Cstrong>Auto-scroll\u003C/strong>: Table automatically scrolls to first selected row when selection changes\u003C/li>\n\u003Cli>\u003Cstrong>Visual Consistency\u003C/strong>: Selected rows show \u003Ccode dir=\"auto\">bg-blue-500/20\u003C/code> background, matching IChart selection theme\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"files-modified\">Files Modified\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#files-modified\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Files Modified”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>DataPanel Component\u003C/strong> (\u003Ccode dir=\"auto\">apps/pwa/src/components/DataPanel.tsx\u003C/code>):\u003C/p>\n\u003Cul>\n\u003Cli>Added \u003Ccode dir=\"auto\">selectedIndices\u003C/code> prop (Set\u003Cnumber>) for multi-point selection\u003C/number>\u003C/li>\n\u003Cli>Added \u003Ccode dir=\"auto\">onToggleSelection\u003C/code> callback for row click handling\u003C/li>\n\u003Cli>Updated row rendering to show blue background for selected rows\u003C/li>\n\u003Cli>Added scroll-to-row logic when selection changes\u003C/li>\n\u003Cli>Row click now toggles selection instead of just highlighting\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>App Component\u003C/strong> (\u003Ccode dir=\"auto\">apps/pwa/src/App.tsx\u003C/code>):\u003C/p>\n\u003Cul>\n\u003Cli>Added \u003Ccode dir=\"auto\">selectedPoints\u003C/code> and \u003Ccode dir=\"auto\">togglePointSelection\u003C/code> from DataContext\u003C/li>\n\u003Cli>Passed props to DataPanel: \u003Ccode dir=\"auto\">selectedIndices={selectedPoints}\u003C/code>, \u003Ccode dir=\"auto\">onToggleSelection={togglePointSelection}\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-experience\">User Experience\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-experience\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Experience”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User brushes 3 points in IChart (#23, #47, #52)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataTable rows 23, 47, 52 show blue background\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Table scrolls to row 23 (first selected)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User clicks row 30 in table\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Point #30 highlights in IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SelectionPanel updates: \"4 points selected\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"User brushes 3 points in IChart (#23, #47, #52) ↓DataTable rows 23, 47, 52 show blue background ↓Table scrolls to row 23 (first selected) ↓User clicks row 30 in table ↓Point #30 highlights in IChart ↓SelectionPanel updates: "4 points selected"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"technical-implementation\">Technical Implementation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#technical-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>State Flow\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// IChart brush → DataContext.selectedPoints\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedPoints\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">new\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">([\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">23\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">47\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">52\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// DataTable reads selectedPoints\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isSelected\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedIndices\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">has\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(originalIndex)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Row styling\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{isSelected ? \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-blue-500/20\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> : \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">hover:bg-surface-tertiary/50\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Table row click → Toggle selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{() => onToggleSelection?.(originalIndex)}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// DataContext togglePointSelection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">togglePointSelection\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">30\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Adds or removes from set\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// IChart brush → DataContext.selectedPointssetSelectedPoints(new Set([23, 47, 52])) ↓// DataTable reads selectedPointsconst isSelected = selectedIndices?.has(originalIndex) ↓// Row stylingclassName={isSelected ? 'bg-blue-500/20' : 'hover:bg-surface-tertiary/50'} ↓// Table row click → Toggle selectiononClick={() => onToggleSelection?.(originalIndex)} ↓// DataContext togglePointSelectiontogglePointSelection(30) // Adds or removes from set\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-4-performance-mode-integration\">Phase 4: Performance Mode Integration ✅\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-4-performance-mode-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 4: Performance Mode Integration ✅”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-was-implemented-1\">What Was Implemented\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-was-implemented-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Was Implemented”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Clear selection when switching modes\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>View Changes\u003C/strong>: Selection cleared when switching between Dashboard, Regression, Gage R&R, and Performance views\u003C/li>\n\u003Cli>\u003Cstrong>Performance Mode Entry\u003C/strong>: Selection cleared when entering Performance Mode from detection modal\u003C/li>\n\u003Cli>\u003Cstrong>Performance Mode Exit\u003C/strong>: Selection cleared when returning to Performance Mode from drilled I-Chart\u003C/li>\n\u003Cli>\u003Cstrong>Manual Entry\u003C/strong>: Selection cleared when applying manual entry configuration\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"files-modified-1\">Files Modified\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#files-modified-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Files Modified”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>App Component\u003C/strong> (\u003Ccode dir=\"auto\">apps/pwa/src/App.tsx\u003C/code>):\u003C/p>\n\u003Cul>\n\u003Cli>Added \u003Ccode dir=\"auto\">clearSelection\u003C/code> from DataContext\u003C/li>\n\u003Cli>Added \u003Ccode dir=\"auto\">clearSelection()\u003C/code> calls in:\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">handleViewChange()\u003C/code> - When switching views from settings\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">handleEnablePerformanceMode()\u003C/code> - When entering Performance Mode from detection\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">handleBackToPerformance()\u003C/code> - When returning to Performance Mode\u003C/li>\n\u003Cli>Manual entry config application - Both Performance and Dashboard modes\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-this-matters\">Why This Matters\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-this-matters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why This Matters”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: Selection state persisting across mode changes causes confusion:\u003C/p>\n\u003Cul>\n\u003Cli>Selected points from standard I-Chart don’t make sense in Performance Mode (different data structure)\u003C/li>\n\u003Cli>Returning to Performance Mode with stale selection is confusing\u003C/li>\n\u003Cli>Switching analysis views should provide fresh start\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Solution\u003C/strong>: Proactive clearing ensures clean state transitions:\u003C/p>\n\u003Cul>\n\u003Cli>Users always start with clear slate when changing modes\u003C/li>\n\u003Cli>No stale selection state\u003C/li>\n\u003Cli>Predictable behavior across all view transitions\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-experience-1\">User Experience\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-experience-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Experience”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User has 12 points selected in IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User clicks \"Performance Mode\" in settings\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Selection automatically cleared (no warning needed)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Performance Mode loads with clean state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User drills into specific measure\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Standard I-Chart shows (selection still clear)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User brushes new points in drilled view\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User clicks \"Back to Performance\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Selection cleared again\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"User has 12 points selected in IChart ↓User clicks "Performance Mode" in settings ↓Selection automatically cleared (no warning needed) ↓Performance Mode loads with clean state ↓User drills into specific measure ↓Standard I-Chart shows (selection still clear) ↓User brushes new points in drilled view ↓User clicks "Back to Performance" ↓Selection cleared again\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-5-polish-and-edge-cases\">Phase 5: Polish and Edge Cases ✅\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-5-polish-and-edge-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 5: Polish and Edge Cases ✅”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-was-implemented-2\">What Was Implemented\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-was-implemented-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Was Implemented”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Keyboard Shortcuts\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Escape Key\u003C/strong>: Clear selection when points are selected\u003C/p>\n\u003Cul>\n\u003Cli>Added keyboard navigation handler in Dashboard\u003C/li>\n\u003Cli>Only active when \u003Ccode dir=\"auto\">selectedPoints.size > 0\u003C/code>\u003C/li>\n\u003Cli>Same pattern as existing Focus Mode and Presentation Mode handlers\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Visual Hint\u003C/strong>: SelectionPanel shows “(Press Esc to clear)” hint\u003C/p>\n\u003Cul>\n\u003Cli>Displayed next to point count\u003C/li>\n\u003Cli>Hidden on mobile (space constraint)\u003C/li>\n\u003Cli>Helps users discover keyboard shortcut\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"files-modified-2\">Files Modified\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#files-modified-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Files Modified”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Dashboard Component\u003C/strong> (\u003Ccode dir=\"auto\">apps/pwa/src/components/Dashboard.tsx\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Keyboard handler for Selection clearing (Phase 5: Polish)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useKeyboardNavigation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">focusedItem: selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">size\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">selection\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onEscape: clearSelection,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Keyboard handler for Selection clearing (Phase 5: Polish)useKeyboardNavigation({ focusedItem: selectedPoints.size > 0 ? 'selection' : null, onEscape: clearSelection,});\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>SelectionPanel Component\u003C/strong> (\u003Ccode dir=\"auto\">packages/ui/src/components/SelectionPanel/SelectionPanel.tsx\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">span className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm font-medium text-blue-300\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{sortedIndices\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">length\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} {sortedIndices\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">length\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">point\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">points\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">span\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">span className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs text-content-muted hidden sm:inline\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(Press Esc to clear)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">span\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cspan className="text-sm font-medium text-blue-300"> {sortedIndices.length} {sortedIndices.length === 1 ? 'point' : 'points'} selected\u003C/span>\u003Cspan className="text-xs text-content-muted hidden sm:inline">(Press Esc to clear)\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-experience-2\">User Experience\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-experience-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Experience”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Keyboard Shortcut\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User has 12 points selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User presses Escape key\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Selection cleared immediately\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SelectionPanel disappears\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">IChart returns to normal view (no dimmed points)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"User has 12 points selected ↓User presses Escape key ↓Selection cleared immediately ↓SelectionPanel disappears ↓IChart returns to normal view (no dimmed points)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Visual Hint\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SelectionPanel header shows:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"12 points selected (Press Esc to clear)\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">^\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Helps user discover shortcut\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"SelectionPanel header shows:"12 points selected (Press Esc to clear)" ^ Helps user discover shortcut\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-was-already-handled\">What Was Already Handled\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-was-already-handled\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Was Already Handled”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Filter Change Behavior\u003C/strong> (from Phase 1):\u003C/p>\n\u003Cul>\n\u003Cli>Selection automatically cleared when filters change\u003C/li>\n\u003Cli>Prevents confusion when dataset changes\u003C/li>\n\u003Cli>No warning banner needed (immediate clearing is intuitive)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Performance Characteristics\u003C/strong> (from Phase 2):\u003C/p>\n\u003Cul>\n\u003Cli>SelectionPanel shows max 5 points (no performance issues with large selections)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">createFactorFromSelection()\u003C/code> is O(n) - efficient even for 10,000+ rows\u003C/li>\n\u003Cli>Selection uses Set (O(1) lookups)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Mobile Responsiveness\u003C/strong> (from Phase 2):\u003C/p>\n\u003Cul>\n\u003Cli>SelectionPanel responsive layout matches FilterBreadcrumb\u003C/li>\n\u003Cli>Blue theme differentiates from gray filter chips\u003C/li>\n\u003Cli>Keyboard hint hidden on mobile (sm breakpoint)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overall-implementation-summary\">Overall Implementation Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overall-implementation-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overall Implementation Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"all-5-phases-complete\">All 5 Phases Complete\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#all-5-phases-complete\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “All 5 Phases Complete”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Phase\u003C/th>\u003Cth>Feature\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Effort\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Phase 1\u003C/td>\u003Ctd>Core Hook + I-Chart Brushing\u003C/td>\u003Ctd>✅ Complete\u003C/td>\u003Ctd>2-3 days\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Phase 2\u003C/td>\u003Ctd>SelectionPanel + Create Factor\u003C/td>\u003Ctd>✅ Complete\u003C/td>\u003Ctd>2 days\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Phase 3\u003C/td>\u003Ctd>Data Table Sync\u003C/td>\u003Ctd>✅ Complete\u003C/td>\u003Ctd>1 day\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Phase 4\u003C/td>\u003Ctd>Performance Mode Integration\u003C/td>\u003Ctd>✅ Complete\u003C/td>\u003Ctd>1 day\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Phase 5\u003C/td>\u003Ctd>Polish + Edge Cases\u003C/td>\u003Ctd>✅ Complete\u003C/td>\u003Ctd>1 day\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Total Time\u003C/strong>: Completed in 2 sessions (Phase 1 earlier, Phases 2-5 today)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"verification-results\">Verification Results\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#verification-results\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Verification Results”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"typescript-compilation\">TypeScript Compilation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#typescript-compilation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “TypeScript Compilation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ Zero errors related to brushing implementation\u003C/li>\n\u003Cli>✅ All imports resolve correctly\u003C/li>\n\u003Cli>✅ Type safety maintained across all packages\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"build-success\">Build Success\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#build-success\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Build Success”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ \u003Ccode dir=\"auto\">@variscout/ui\u003C/code> package builds successfully\u003C/li>\n\u003Cli>✅ \u003Ccode dir=\"auto\">@variscout/core\u003C/code> exports verified\u003C/li>\n\u003Cli>✅ PWA compiles without errors\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"manual-testing-checklist\">Manual Testing Checklist\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#manual-testing-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Manual Testing Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Phase 3 (Data Table Sync)\u003C/strong>:\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Brush points in IChart → Table rows highlight\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Table scrolls to first selected row\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Click table row → Point toggles in IChart selection\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Selection count updates in SelectionPanel\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Bi-directional sync stays consistent\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Phase 4 (Performance Mode)\u003C/strong>:\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Switch to Performance Mode → Selection cleared\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Return to Performance Mode from drill → Selection cleared\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Switch to Regression view → Selection cleared\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Switch to Gage R&R view → Selection cleared\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> No stale selection state across modes\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Phase 5 (Polish)\u003C/strong>:\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Press Escape → Selection clears\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Keyboard shortcut hint visible in SelectionPanel\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Hint hidden on mobile (responsive)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Escape handler only active when selection exists\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-details\">Technical Details\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-details\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Details”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"state-management-flow-complete\">State Management Flow (Complete)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#state-management-flow-complete\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “State Management Flow (Complete)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User Interaction\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ IChart Brushing (Phase 1) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Drag to select │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Ctrl+click to toggle │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Shift+click to add │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext.selectedPoints (Set<number>)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌──────────────────┬──────────────────┬──────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼ ▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SelectionPanel DataTable IChart Dashboard\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">(Phase 2) (Phase 3) Visual Keyboard\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Shows details Blue highlight Selected Escape key\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Create Factor Click to toggle points (Phase 5)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Scroll to first larger/white\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">stroke\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"User Interaction ↓┌─────────────────────────────────────────┐│ IChart Brushing (Phase 1) ││ - Drag to select ││ - Ctrl+click to toggle ││ - Shift+click to add │└─────────────────────────────────────────┘ ↓DataContext.selectedPoints (Set\u003Cnumber>) ↓┌──────────────────┬──────────────────┬──────────────────┐│ │ │ │▼ ▼ ▼ ▼SelectionPanel DataTable IChart Dashboard(Phase 2) (Phase 3) Visual KeyboardShows details Blue highlight Selected Escape keyCreate Factor Click to toggle points (Phase 5) Scroll to first larger/white stroke\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"keyboard-navigation-integration\">Keyboard Navigation Integration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#keyboard-navigation-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyboard Navigation Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Existing Patterns\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Focus Mode: Escape exits focus\u003C/li>\n\u003Cli>Presentation Mode: Escape exits presentation\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>New Pattern\u003C/strong> (Phase 5):\u003C/p>\n\u003Cul>\n\u003Cli>Selection Mode: Escape clears selection\u003C/li>\n\u003Cli>Follows same \u003Ccode dir=\"auto\">useKeyboardNavigation\u003C/code> hook pattern\u003C/li>\n\u003Cli>Only active when \u003Ccode dir=\"auto\">selectedPoints.size > 0\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"auto-clear-triggers-phase-4\">Auto-Clear Triggers (Phase 4)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#auto-clear-triggers-phase-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Auto-Clear Triggers (Phase 4)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Selection cleared in these scenarios:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Filter Change\u003C/strong> (Phase 1) - Prevents confusion when dataset changes\u003C/li>\n\u003Cli>\u003Cstrong>View Change\u003C/strong> (Phase 4) - Clean slate for different analysis types\u003C/li>\n\u003Cli>\u003Cstrong>Performance Mode Entry\u003C/strong> (Phase 4) - Different data structure\u003C/li>\n\u003Cli>\u003Cstrong>Performance Mode Exit\u003C/strong> (Phase 4) - Return to overview\u003C/li>\n\u003Cli>\u003Cstrong>Escape Key\u003C/strong> (Phase 5) - User-initiated clear\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"files-modified-summary\">Files Modified Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#files-modified-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Files Modified Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-state-phase-3-4\">Core State (Phase 3-4)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-state-phase-3-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core State (Phase 3-4)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">packages/hooks/src/useDataState.ts\u003C/code> - Already had selection state (Phase 1)\u003C/li>\n\u003Cli>No changes needed - state management complete from Phase 1\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"components-phase-3-5\">Components (Phase 3, 5)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#components-phase-3-5\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Components (Phase 3, 5)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">apps/pwa/src/components/DataPanel.tsx\u003C/code> - Added multi-selection support\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">packages/ui/src/components/SelectionPanel/SelectionPanel.tsx\u003C/code> - Added keyboard hint\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">apps/pwa/src/components/Dashboard.tsx\u003C/code> - Added Escape key handler\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"integration-phase-3-4\">Integration (Phase 3-4)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#integration-phase-3-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integration (Phase 3-4)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">apps/pwa/src/App.tsx\u003C/code> - Connected DataPanel, added clearSelection calls\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"documentation\">Documentation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">PHASES3-5_COMPLETE.md\u003C/code> (this file)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"known-behaviors-by-design\">Known Behaviors (By Design)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#known-behaviors-by-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Known Behaviors (By Design)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Selection cleared on filter change\u003C/strong> (Phase 1) - Prevents confusion\u003C/li>\n\u003Cli>\u003Cstrong>Selection cleared on mode change\u003C/strong> (Phase 4) - Clean state transitions\u003C/li>\n\u003Cli>\u003Cstrong>IChart-only brushing\u003C/strong> (Phase 1) - No ScatterPlot/Boxplot brushing\u003C/li>\n\u003Cli>\u003Cstrong>No persistent selection\u003C/strong> - Ephemeral state, factors are persistent\u003C/li>\n\u003Cli>\u003Cstrong>No undo for factor creation\u003C/strong> (Phase 2) - Factors are permanent columns\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"user-workflows-complete-end-to-end\">User Workflows (Complete End-to-End)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#user-workflows-complete-end-to-end\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Workflows (Complete End-to-End)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"workflow-1-outlier-investigation-with-table-sync\">Workflow 1: Outlier Investigation with Table Sync\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#workflow-1-outlier-investigation-with-table-sync\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow 1: Outlier Investigation with Table Sync”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">1. User brushes 5 high points in IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">2. SelectionPanel appears: \"5 points selected (Press Esc to clear)\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">3. Data table scrolls to first selected row, shows blue highlight\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">4. User clicks row 30 in table\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">5. Point 30 adds to selection, IChart updates\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">6. SelectionPanel: \"6 points selected\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">7. User clicks \"Create Factor\" → Names \"Temperature Outliers\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">8. System creates factor, auto-filters, clears selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">9. Factor persists for drill-down and export\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"1. User brushes 5 high points in IChart ↓2. SelectionPanel appears: "5 points selected (Press Esc to clear)" ↓3. Data table scrolls to first selected row, shows blue highlight ↓4. User clicks row 30 in table ↓5. Point 30 adds to selection, IChart updates ↓6. SelectionPanel: "6 points selected" ↓7. User clicks "Create Factor" → Names "Temperature Outliers" ↓8. System creates factor, auto-filters, clears selection ↓9. Factor persists for drill-down and export\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"workflow-2-mode-switching-with-clean-state\">Workflow 2: Mode Switching with Clean State\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#workflow-2-mode-switching-with-clean-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow 2: Mode Switching with Clean State”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">1. User brushes 12 points in standard I-Chart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">2. SelectionPanel shows details\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">3. User switches to Performance Mode in settings\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">4. Selection automatically cleared (no warning)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">5. Performance Mode loads fresh\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">6. User drills into \"Head_1\" measure\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">7. Standard I-Chart shows (still no selection)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">8. User brushes new points in drilled view\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">9. User clicks \"Back to Performance\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">10. Selection cleared again, clean return\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"1. User brushes 12 points in standard I-Chart ↓2. SelectionPanel shows details ↓3. User switches to Performance Mode in settings ↓4. Selection automatically cleared (no warning) ↓5. Performance Mode loads fresh ↓6. User drills into "Head_1" measure ↓7. Standard I-Chart shows (still no selection) ↓8. User brushes new points in drilled view ↓9. User clicks "Back to Performance" ↓10. Selection cleared again, clean return\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"workflow-3-keyboard-shortcut-usage\">Workflow 3: Keyboard Shortcut Usage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#workflow-3-keyboard-shortcut-usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow 3: Keyboard Shortcut Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">1. User brushes 8 points\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">2. SelectionPanel: \"8 points selected (Press Esc to clear)\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">3. User realizes wrong points selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">4. User presses Escape key\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">5. Selection clears immediately\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">6. SelectionPanel disappears\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">7. IChart returns to normal (no dimming)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">8. User brushes correct points\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"1. User brushes 8 points ↓2. SelectionPanel: "8 points selected (Press Esc to clear)" ↓3. User realizes wrong points selected ↓4. User presses Escape key ↓5. Selection clears immediately ↓6. SelectionPanel disappears ↓7. IChart returns to normal (no dimming) ↓8. User brushes correct points\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-criteria-met\">Success Criteria Met ✅\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-criteria-met\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Criteria Met ✅”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-3-requirements\">Phase 3 Requirements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3 Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> IChart selection → Table rows highlight\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Table row click → IChart point highlights\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Table scrolls to first selected row\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Bi-directional sync consistent\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Visual: Blue background on selected rows\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-4-requirements\">Phase 4 Requirements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-4-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 4 Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Selection cleared on view change\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Selection cleared entering Performance Mode\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Selection cleared exiting Performance Mode\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> No stale selection across modes\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Clean state transitions\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-5-requirements\">Phase 5 Requirements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-5-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 5 Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Escape key clears selection\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Keyboard hint in SelectionPanel\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Responsive hint visibility\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Handler only active when needed\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Follows existing patterns\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"overall-quality\">Overall Quality\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#overall-quality\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overall Quality”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> TypeScript: 0 errors\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Build: All packages compile\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Integration: Seamless across features\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Performance: No regressions\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> User Experience: Intuitive workflows\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performance-characteristics\">Performance Characteristics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performance-characteristics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Characteristics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"selection-operations\">Selection Operations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#selection-operations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Selection Operations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Toggle point\u003C/strong>: O(1) - Set add/delete\u003C/li>\n\u003Cli>\u003Cstrong>Clear selection\u003C/strong>: O(1) - Set clear\u003C/li>\n\u003Cli>\u003Cstrong>Check if selected\u003C/strong>: O(1) - Set has()\u003C/li>\n\u003Cli>\u003Cstrong>Table scroll\u003C/strong>: O(n) - Find first selected (n = filtered rows)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"memory-usage\">Memory Usage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#memory-usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Memory Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Set storage\u003C/strong>: Minimal - just indices (numbers)\u003C/li>\n\u003Cli>\u003Cstrong>No data duplication\u003C/strong>: Points reference original data\u003C/li>\n\u003Cli>\u003Cstrong>Scale tested\u003C/strong>: Works efficiently with 1000+ points\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"render-performance\">Render Performance\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#render-performance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Render Performance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>DataTable\u003C/strong>: Only selected rows get different styling\u003C/li>\n\u003Cli>\u003Cstrong>IChart\u003C/strong>: Selection state in props (React memo-friendly)\u003C/li>\n\u003Cli>\u003Cstrong>SelectionPanel\u003C/strong>: Shows max 5 points (no DOM bloat)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"documentation-created\">Documentation Created\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#documentation-created\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Documentation Created”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>PHASES3-5_COMPLETE.md\u003C/strong> (this file) - Technical summary\u003C/li>\n\u003Cli>\u003Cstrong>Phase 2 docs still apply\u003C/strong>:\n\u003Cul>\n\u003Cli>PHASE2_COMPLETE.md - Technical details\u003C/li>\n\u003Cli>CREATE_FACTOR_GUIDE.md - User guide\u003C/li>\n\u003Cli>IMPLEMENTATION_SUMMARY.md - Executive summary\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whats-next\">What’s Next\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whats-next\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What’s Next”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"feature-complete\">Feature Complete! 🎉\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#feature-complete\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Complete! 🎉”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All 5 phases of Minitab-style brushing are now complete:\u003C/p>\n\u003Cul>\n\u003Cli>✅ Core brushing interaction (Phase 1)\u003C/li>\n\u003Cli>✅ Create Factor workflow (Phase 2)\u003C/li>\n\u003Cli>✅ Data Table sync (Phase 3)\u003C/li>\n\u003Cli>✅ Performance Mode integration (Phase 4)\u003C/li>\n\u003Cli>✅ Polish and shortcuts (Phase 5)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ready-for-production\">Ready for Production\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ready-for-production\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Ready for Production”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The brushing feature is now:\u003C/p>\n\u003Cul>\n\u003Cli>Fully implemented across all components\u003C/li>\n\u003Cli>Type-safe and well-tested\u003C/li>\n\u003Cli>Documented with user guides\u003C/li>\n\u003Cli>Integrated with existing features\u003C/li>\n\u003Cli>Polished with keyboard shortcuts\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"potential-future-enhancements-optional\">Potential Future Enhancements (Optional)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#potential-future-enhancements-optional\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Potential Future Enhancements (Optional)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Ctrl+A to select all points\u003C/strong> - Could be added if users request\u003C/li>\n\u003Cli>\u003Cstrong>Selection statistics\u003C/strong> - Show mean/std of selected points in panel\u003C/li>\n\u003Cli>\u003Cstrong>Selection history\u003C/strong> - Undo/redo for selections\u003C/li>\n\u003Cli>\u003Cstrong>Named selections\u003C/strong> - Save selections for later (like bookmarks)\u003C/li>\n\u003Cli>\u003Cstrong>Export selected rows\u003C/strong> - Direct export button in SelectionPanel\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: ✅ \u003Cstrong>ALL PHASES COMPLETE\u003C/strong>\n\u003Cstrong>Progress\u003C/strong>: 5/5 phases (100%)\n\u003Cstrong>Ready\u003C/strong>: Production-ready implementation\u003C/p>", + { + "headings": 3758, + "localImagePaths": 3890, + "remoteImagePaths": 3891, + "frontmatter": 3892, + "imagePaths": 3893 + }, + [ + 3759, 3761, 3764, 3767, 3768, 3771, 3774, 3777, 3779, 3781, 3784, 3786, 3789, 3791, 3793, 3795, + 3798, 3801, 3804, 3807, 3808, 3811, 3814, 3817, 3820, 3823, 3826, 3829, 3832, 3835, 3838, 3839, + 3842, 3845, 3848, 3851, 3854, 3855, 3858, 3861, 3864, 3867, 3868, 3871, 3874, 3877, 3878, 3881, + 3884, 3887 + ], + { "depth": 30, "slug": 3760, "text": 3748 }, + "phases-3-5-complete-data-table-sync--performance-integration--polish", + { "depth": 33, "slug": 3762, "text": 3763 }, + "phase-3-data-table-sync", + "Phase 3: Data Table Sync ✅", + { "depth": 79, "slug": 3765, "text": 3766 }, + "what-was-implemented", + "What Was Implemented", + { "depth": 79, "slug": 3552, "text": 3553 }, + { "depth": 79, "slug": 3769, "text": 3770 }, + "user-experience", + "User Experience", + { "depth": 79, "slug": 3772, "text": 3773 }, + "technical-implementation", + "Technical Implementation", + { "depth": 33, "slug": 3775, "text": 3776 }, + "phase-4-performance-mode-integration", + "Phase 4: Performance Mode Integration ✅", + { "depth": 79, "slug": 3778, "text": 3766 }, + "what-was-implemented-1", + { "depth": 79, "slug": 3780, "text": 3553 }, + "files-modified-1", + { "depth": 79, "slug": 3782, "text": 3783 }, + "why-this-matters", + "Why This Matters", + { "depth": 79, "slug": 3785, "text": 3770 }, + "user-experience-1", + { "depth": 33, "slug": 3787, "text": 3788 }, + "phase-5-polish-and-edge-cases", + "Phase 5: Polish and Edge Cases ✅", + { "depth": 79, "slug": 3790, "text": 3766 }, + "what-was-implemented-2", + { "depth": 79, "slug": 3792, "text": 3553 }, + "files-modified-2", + { "depth": 79, "slug": 3794, "text": 3770 }, + "user-experience-2", + { "depth": 79, "slug": 3796, "text": 3797 }, + "what-was-already-handled", + "What Was Already Handled", + { "depth": 33, "slug": 3799, "text": 3800 }, + "overall-implementation-summary", + "Overall Implementation Summary", + { "depth": 79, "slug": 3802, "text": 3803 }, + "all-5-phases-complete", + "All 5 Phases Complete", + { "depth": 33, "slug": 3805, "text": 3806 }, + "verification-results", + "Verification Results", + { "depth": 79, "slug": 3387, "text": 3388 }, + { "depth": 79, "slug": 3809, "text": 3810 }, + "build-success", + "Build Success", + { "depth": 79, "slug": 3812, "text": 3813 }, + "manual-testing-checklist", + "Manual Testing Checklist", + { "depth": 33, "slug": 3815, "text": 3816 }, + "technical-details", + "Technical Details", + { "depth": 79, "slug": 3818, "text": 3819 }, + "state-management-flow-complete", + "State Management Flow (Complete)", + { "depth": 79, "slug": 3821, "text": 3822 }, + "keyboard-navigation-integration", + "Keyboard Navigation Integration", + { "depth": 79, "slug": 3824, "text": 3825 }, + "auto-clear-triggers-phase-4", + "Auto-Clear Triggers (Phase 4)", + { "depth": 33, "slug": 3827, "text": 3828 }, + "files-modified-summary", + "Files Modified Summary", + { "depth": 79, "slug": 3830, "text": 3831 }, + "core-state-phase-3-4", + "Core State (Phase 3-4)", + { "depth": 79, "slug": 3833, "text": 3834 }, + "components-phase-3-5", + "Components (Phase 3, 5)", + { "depth": 79, "slug": 3836, "text": 3837 }, + "integration-phase-3-4", + "Integration (Phase 3-4)", + { "depth": 79, "slug": 3452, "text": 3453 }, + { "depth": 33, "slug": 3840, "text": 3841 }, + "known-behaviors-by-design", + "Known Behaviors (By Design)", + { "depth": 33, "slug": 3843, "text": 3844 }, + "user-workflows-complete-end-to-end", + "User Workflows (Complete End-to-End)", + { "depth": 79, "slug": 3846, "text": 3847 }, + "workflow-1-outlier-investigation-with-table-sync", + "Workflow 1: Outlier Investigation with Table Sync", + { "depth": 79, "slug": 3849, "text": 3850 }, + "workflow-2-mode-switching-with-clean-state", + "Workflow 2: Mode Switching with Clean State", + { "depth": 79, "slug": 3852, "text": 3853 }, + "workflow-3-keyboard-shortcut-usage", + "Workflow 3: Keyboard Shortcut Usage", + { "depth": 33, "slug": 3444, "text": 3445 }, + { "depth": 79, "slug": 3856, "text": 3857 }, + "phase-3-requirements", + "Phase 3 Requirements", + { "depth": 79, "slug": 3859, "text": 3860 }, + "phase-4-requirements", + "Phase 4 Requirements", + { "depth": 79, "slug": 3862, "text": 3863 }, + "phase-5-requirements", + "Phase 5 Requirements", + { "depth": 79, "slug": 3865, "text": 3866 }, + "overall-quality", + "Overall Quality", + { "depth": 33, "slug": 3429, "text": 3430 }, + { "depth": 79, "slug": 3869, "text": 3870 }, + "selection-operations", + "Selection Operations", + { "depth": 79, "slug": 3872, "text": 3873 }, + "memory-usage", + "Memory Usage", + { "depth": 79, "slug": 3875, "text": 3876 }, + "render-performance", + "Render Performance", + { "depth": 33, "slug": 3435, "text": 3436 }, + { "depth": 33, "slug": 3879, "text": 3880 }, + "whats-next", + "What’s Next", + { "depth": 79, "slug": 3882, "text": 3883 }, + "feature-complete", + "Feature Complete! 🎉", + { "depth": 79, "slug": 3885, "text": 3886 }, + "ready-for-production", + "Ready for Production", + { "depth": 79, "slug": 3888, "text": 3889 }, + "potential-future-enhancements-optional", + "Potential Future Enhancements (Optional)", + [], + [], + { "title": 3748 }, + [], + "archive/regression", + { "id": 3894, "data": 3896, "body": 3901, "filePath": 3902, "digest": 3903, "rendered": 3904 }, + { + "title": 3897, + "editUrl": 16, + "head": 3898, + "template": 18, + "sidebar": 3899, + "pagefind": 16, + "draft": 20 + }, + "Regression Analysis", + [], + { "hidden": 20, "attrs": 3900 }, + {}, + "# Regression Analysis\n\nRegression is VariScout's tool for exploring relationships between continuous variables.\n\n---\n\n## Purpose\n\n_\"Is there a relationship between X and Y?\"_\n\nRegression answers:\n\n- Does X predict Y?\n- How strong is the relationship?\n- What's the direction (positive/negative)?\n\n---\n\n## Key Metrics\n\n| Metric | Description |\n| ----------- | -------------------------------------- |\n| R² | Proportion of variance explained (0-1) |\n| Adjusted R² | R² adjusted for number of predictors |\n| Slope | Change in Y per unit X |\n| Intercept | Y value when X = 0 |\n| p-value | Significance of relationship |\n\n---\n\n## Interpretation Guide\n\n| R² Value | Interpretation |\n| --------- | -------------- |\n| 0.90-1.00 | Very strong |\n| 0.70-0.89 | Strong |\n| 0.50-0.69 | Moderate |\n| 0.30-0.49 | Weak |\n| \u003C0.30 | Very weak |\n\n---\n\n## Use in VariScout\n\n:::note\nRegression in VariScout serves as a **first step** to visually check if correlation exists. It answers \"is there a relationship?\" before investing in deeper predictive modeling.\n\nFor most variation analysis, the Four Lenses (I-Chart, Boxplot, Pareto, Capability) are sufficient.\n:::\n\n---\n\n## Multiple Regression\n\nWhen using multiple predictors:\n\n| Metric | Purpose |\n| ----------- | ---------------------------------------- |\n| Adjusted R² | Compare models with different predictors |\n| VIF | Check for multicollinearity |\n| p-values | Significance of each predictor |\n\n> **Design principle — Adjusted R², not R²**: In multi-predictor models, always evaluate model quality using Adjusted R². Raw R² increases mechanically with every added predictor, even noise. Adjusted R² penalizes unnecessary complexity and only increases when a new factor genuinely improves the model. Simple (single-predictor) regression shows raw R² since both metrics are equivalent with one predictor.\n\n### When to Use Multiple Regression\n\nUse multiple regression when:\n\n- You have **multiple potential predictors** (X variables)\n- You want to understand **which factors matter most**\n- You need to **control for confounding variables**\n- You're building a **predictive model**\n\n### VIF (Variance Inflation Factor)\n\nVIF detects **multicollinearity** - when predictors are correlated with each other.\n\n| VIF Value | Interpretation | Action |\n| --------- | -------------- | --------------------------- |\n| 1 | No correlation | Ideal |\n| 1-5 | Moderate | Usually acceptable |\n| 5-10 | High | Investigate |\n| >10 | Severe | Remove predictor or combine |\n\n**Why multicollinearity matters:**\n\n- Inflates coefficient standard errors\n- Makes individual predictor effects unreliable\n- Model still predicts well, but interpretation is compromised\n\n### Interpreting Coefficients\n\n| Element | Meaning |\n| -------------- | ---------------------------------------------------------- |\n| Coefficient | Change in Y per unit change in X (holding others constant) |\n| Standard Error | Uncertainty in coefficient estimate |\n| t-statistic | Coefficient / Standard Error |\n| p-value | Probability of seeing this t if true effect is zero |\n\n### Model Selection Tips\n\n1. **Start simple** - Add predictors one at a time\n2. **Check Adjusted R²** - Does adding a predictor improve it?\n3. **Monitor VIF** - Remove highly correlated predictors\n4. **Validate** - Test on held-out data if possible\n\n---\n\n## Interaction Effects\n\nInteractions occur when one factor's effect **depends on another factor's level**.\n\n_Example: \"Machine C is only problematic on Night shift\"_\n\n### Why Check for Interactions?\n\nSequential drill-down (ANOVA) captures **main effects** only. If factors interact:\n\n- Main effects may underestimate total explained variation\n- The combination matters more than individual factors\n- Action should target the specific combination, not factors separately\n\n### Enabling Interactions in VariScout\n\n1. Switch to **Advanced (GLM)** mode in Regression Panel\n2. Select categorical predictors (factors from drill-down)\n3. Toggle **\"Include interactions\"** checkbox\n4. Review the ANOVA table for significant interaction terms\n\n### Coming from Investigation Mindmap\n\nThe Investigation Mindmap provides two direct bridges to the Regression Panel:\n\n- **ConclusionPanel** (bottom of mindmap): When 2+ factors are drilled, the \"Refine in Regression\" button navigates to the Regression Panel with all investigated factors pre-populated as predictors.\n- **EdgeTooltip** (Interaction mode): Clicking an interaction edge shows delta-R², p-value, and standardized beta. The \"Model in Regression\" button navigates to the Regression Panel with that specific factor pair pre-populated.\n\nBoth buttons pre-fill the Regression Panel's predictor selection, so the analyst can immediately run the model without manual configuration.\n\n### Project in What-If\n\nWhen working in Advanced (GLM) mode, a **\"Project in What-If →\"** button bridges the regression model to the What-If Simulator for process improvement projections.\n\n**When it appears:**\n\n| Model State | Button | Message |\n| ------------------------------------------ | ------------ | ------------------------------------------------ |\n| All terms significant (p \u003C 0.05) | Green button | \"Model is well-specified\" |\n| Some terms non-significant, Adj. R² ≥ 0.30 | Amber button | \"Model available but some terms not significant\" |\n| Adj. R² \u003C 0.30 | No button | Model too weak for reliable projections |\n\n**What it does:** Passes the complete regression model (coefficients, terms, intercept) to the What-If page, where the Model-Driven Simulator lets you adjust factor levels and see projected mean shifts, Cpk changes, and yield impact.\n\n**Low-fit warning:** When Adj. R² \u003C 0.50, the Model-Driven Simulator header displays an amber warning: \"Low model fit — projections are approximate\".\n\n### Interpreting Interaction Terms\n\n| Term | Meaning |\n| ----------------- | ---------------------------------------- |\n| `Shift*Machine` | Effect of Shift depends on Machine level |\n| p-value \u003C 0.05 | Significant interaction exists |\n| Large coefficient | Strong interaction effect |\n\n---\n\n---\n\n## Technical Reference\n\nVariScout's implementation:\n\n```typescript\n// From @variscout/core\nimport { calculateRegression, calculateMultipleRegression } from '@variscout/core';\n\n// Simple regression\nconst result = calculateRegression(data, 'X', 'Y');\n\n// Multiple regression with interactions\nconst multiResult = calculateMultipleRegression(data, ['X1', 'X2'], 'Y', {\n includeInteractions: true,\n});\n```\n\n**Test coverage:** See `packages/core/src/__tests__/stats.test.ts` for regression tests.\n\n---\n\n## See Also\n\n- [Glossary: R²](../../glossary.md#r2)\n- [Glossary: VIF](../../glossary.md#vif)\n- [Chart Design](../../06-design-system/charts/scatter.md)\n- [Drill-Down: When to Check for Interactions](../navigation/drill-down.md#when-to-check-for-interactions)\n- [Boxplot](boxplot.md) - Factor comparison with ANOVA\n- [Case: Avocado](../../04-cases/avocado/index.md) - Regression use case", + "src/content/docs/archive/regression.md", + "76e9dc8997557688", + { "html": 3905, "metadata": 3906 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"regression-analysis\">Regression Analysis\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#regression-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Regression Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Regression is VariScout’s tool for exploring relationships between continuous variables.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Is there a relationship between X and Y?”\u003C/em>\u003C/p>\n\u003Cp>Regression answers:\u003C/p>\n\u003Cul>\n\u003Cli>Does X predict Y?\u003C/li>\n\u003Cli>How strong is the relationship?\u003C/li>\n\u003Cli>What’s the direction (positive/negative)?\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-metrics\">Key Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>R²\u003C/td>\u003Ctd>Proportion of variance explained (0-1)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Adjusted R²\u003C/td>\u003Ctd>R² adjusted for number of predictors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Slope\u003C/td>\u003Ctd>Change in Y per unit X\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Intercept\u003C/td>\u003Ctd>Y value when X = 0\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>p-value\u003C/td>\u003Ctd>Significance of relationship\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interpretation-guide\">Interpretation Guide\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interpretation-guide\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpretation Guide”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>R² Value\u003C/th>\u003Cth>Interpretation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>0.90-1.00\u003C/td>\u003Ctd>Very strong\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>0.70-0.89\u003C/td>\u003Ctd>Strong\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>0.50-0.69\u003C/td>\u003Ctd>Moderate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>0.30-0.49\u003C/td>\u003Ctd>Weak\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd><0.30\u003C/td>\u003Ctd>Very weak\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"use-in-variscout\">Use in VariScout\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#use-in-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use in VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Caside aria-label=\"Note\" class=\"starlight-aside starlight-aside--note\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath d=\"M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z\">\u003C/path>\u003C/svg>Note\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>Regression in VariScout serves as a \u003Cstrong>first step\u003C/strong> to visually check if correlation exists. It answers “is there a relationship?” before investing in deeper predictive modeling.\u003C/p>\u003Cp>For most variation analysis, the Four Lenses (I-Chart, Boxplot, Pareto, Capability) are sufficient.\u003C/p>\u003C/div>\u003C/aside>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"multiple-regression\">Multiple Regression\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#multiple-regression\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Multiple Regression”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When using multiple predictors:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Adjusted R²\u003C/td>\u003Ctd>Compare models with different predictors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>VIF\u003C/td>\u003Ctd>Check for multicollinearity\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>p-values\u003C/td>\u003Ctd>Significance of each predictor\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Design principle — Adjusted R², not R²\u003C/strong>: In multi-predictor models, always evaluate model quality using Adjusted R². Raw R² increases mechanically with every added predictor, even noise. Adjusted R² penalizes unnecessary complexity and only increases when a new factor genuinely improves the model. Simple (single-predictor) regression shows raw R² since both metrics are equivalent with one predictor.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"when-to-use-multiple-regression\">When to Use Multiple Regression\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-use-multiple-regression\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Use Multiple Regression”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use multiple regression when:\u003C/p>\n\u003Cul>\n\u003Cli>You have \u003Cstrong>multiple potential predictors\u003C/strong> (X variables)\u003C/li>\n\u003Cli>You want to understand \u003Cstrong>which factors matter most\u003C/strong>\u003C/li>\n\u003Cli>You need to \u003Cstrong>control for confounding variables\u003C/strong>\u003C/li>\n\u003Cli>You’re building a \u003Cstrong>predictive model\u003C/strong>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"vif-variance-inflation-factor\">VIF (Variance Inflation Factor)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#vif-variance-inflation-factor\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VIF (Variance Inflation Factor)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VIF detects \u003Cstrong>multicollinearity\u003C/strong> - when predictors are correlated with each other.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>VIF Value\u003C/th>\u003Cth>Interpretation\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>No correlation\u003C/td>\u003Ctd>Ideal\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1-5\u003C/td>\u003Ctd>Moderate\u003C/td>\u003Ctd>Usually acceptable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5-10\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Investigate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>>10\u003C/td>\u003Ctd>Severe\u003C/td>\u003Ctd>Remove predictor or combine\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Why multicollinearity matters:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Inflates coefficient standard errors\u003C/li>\n\u003Cli>Makes individual predictor effects unreliable\u003C/li>\n\u003Cli>Model still predicts well, but interpretation is compromised\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interpreting-coefficients\">Interpreting Coefficients\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interpreting-coefficients\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpreting Coefficients”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Coefficient\u003C/td>\u003Ctd>Change in Y per unit change in X (holding others constant)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Standard Error\u003C/td>\u003Ctd>Uncertainty in coefficient estimate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>t-statistic\u003C/td>\u003Ctd>Coefficient / Standard Error\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>p-value\u003C/td>\u003Ctd>Probability of seeing this t if true effect is zero\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"model-selection-tips\">Model Selection Tips\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#model-selection-tips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Model Selection Tips”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Start simple\u003C/strong> - Add predictors one at a time\u003C/li>\n\u003Cli>\u003Cstrong>Check Adjusted R²\u003C/strong> - Does adding a predictor improve it?\u003C/li>\n\u003Cli>\u003Cstrong>Monitor VIF\u003C/strong> - Remove highly correlated predictors\u003C/li>\n\u003Cli>\u003Cstrong>Validate\u003C/strong> - Test on held-out data if possible\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interaction-effects\">Interaction Effects\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interaction-effects\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interaction Effects”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Interactions occur when one factor’s effect \u003Cstrong>depends on another factor’s level\u003C/strong>.\u003C/p>\n\u003Cp>\u003Cem>Example: “Machine C is only problematic on Night shift”\u003C/em>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-check-for-interactions\">Why Check for Interactions?\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-check-for-interactions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Check for Interactions?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Sequential drill-down (ANOVA) captures \u003Cstrong>main effects\u003C/strong> only. If factors interact:\u003C/p>\n\u003Cul>\n\u003Cli>Main effects may underestimate total explained variation\u003C/li>\n\u003Cli>The combination matters more than individual factors\u003C/li>\n\u003Cli>Action should target the specific combination, not factors separately\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"enabling-interactions-in-variscout\">Enabling Interactions in VariScout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#enabling-interactions-in-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Enabling Interactions in VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Switch to \u003Cstrong>Advanced (GLM)\u003C/strong> mode in Regression Panel\u003C/li>\n\u003Cli>Select categorical predictors (factors from drill-down)\u003C/li>\n\u003Cli>Toggle \u003Cstrong>“Include interactions”\u003C/strong> checkbox\u003C/li>\n\u003Cli>Review the ANOVA table for significant interaction terms\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"coming-from-investigation-mindmap\">Coming from Investigation Mindmap\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#coming-from-investigation-mindmap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Coming from Investigation Mindmap”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Investigation Mindmap provides two direct bridges to the Regression Panel:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>ConclusionPanel\u003C/strong> (bottom of mindmap): When 2+ factors are drilled, the “Refine in Regression” button navigates to the Regression Panel with all investigated factors pre-populated as predictors.\u003C/li>\n\u003Cli>\u003Cstrong>EdgeTooltip\u003C/strong> (Interaction mode): Clicking an interaction edge shows delta-R², p-value, and standardized beta. The “Model in Regression” button navigates to the Regression Panel with that specific factor pair pre-populated.\u003C/li>\n\u003C/ul>\n\u003Cp>Both buttons pre-fill the Regression Panel’s predictor selection, so the analyst can immediately run the model without manual configuration.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"project-in-what-if\">Project in What-If\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#project-in-what-if\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Project in What-If”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When working in Advanced (GLM) mode, a \u003Cstrong>“Project in What-If →”\u003C/strong> button bridges the regression model to the What-If Simulator for process improvement projections.\u003C/p>\n\u003Cp>\u003Cstrong>When it appears:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Model State\u003C/th>\u003Cth>Button\u003C/th>\u003Cth>Message\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>All terms significant (p < 0.05)\u003C/td>\u003Ctd>Green button\u003C/td>\u003Ctd>”Model is well-specified”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Some terms non-significant, Adj. R² ≥ 0.30\u003C/td>\u003Ctd>Amber button\u003C/td>\u003Ctd>”Model available but some terms not significant”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Adj. R² < 0.30\u003C/td>\u003Ctd>No button\u003C/td>\u003Ctd>Model too weak for reliable projections\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>What it does:\u003C/strong> Passes the complete regression model (coefficients, terms, intercept) to the What-If page, where the Model-Driven Simulator lets you adjust factor levels and see projected mean shifts, Cpk changes, and yield impact.\u003C/p>\n\u003Cp>\u003Cstrong>Low-fit warning:\u003C/strong> When Adj. R² < 0.50, the Model-Driven Simulator header displays an amber warning: “Low model fit — projections are approximate”.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interpreting-interaction-terms\">Interpreting Interaction Terms\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interpreting-interaction-terms\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpreting Interaction Terms”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Term\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Shift*Machine\u003C/code>\u003C/td>\u003Ctd>Effect of Shift depends on Machine level\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>p-value < 0.05\u003C/td>\u003Ctd>Significant interaction exists\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Large coefficient\u003C/td>\u003Ctd>Strong interaction effect\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-reference\">Technical Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s implementation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// From @variscout/core\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateRegression, calculateMultipleRegression } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Simple regression\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">result\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateRegression\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">X\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Y\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Multiple regression with interactions\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">multiResult\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateMultipleRegression\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">X1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">X2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Y\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">includeInteractions: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// From @variscout/coreimport { calculateRegression, calculateMultipleRegression } from '@variscout/core';// Simple regressionconst result = calculateRegression(data, 'X', 'Y');// Multiple regression with interactionsconst multiResult = calculateMultipleRegression(data, ['X1', 'X2'], 'Y', { includeInteractions: true,});\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Test coverage:\u003C/strong> See \u003Ccode dir=\"auto\">packages/core/src/__tests__/stats.test.ts\u003C/code> for regression tests.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../glossary.md#r2\">Glossary: R²\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md#vif\">Glossary: VIF\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/charts/scatter.md\">Chart Design\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../navigation/drill-down.md#when-to-check-for-interactions\">Drill-Down: When to Check for Interactions\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"boxplot.md\">Boxplot\u003C/a> - Factor comparison with ANOVA\u003C/li>\n\u003Cli>\u003Ca href=\"../../04-cases/avocado/index.md\">Case: Avocado\u003C/a> - Regression use case\u003C/li>\n\u003C/ul>", + { + "headings": 3907, + "localImagePaths": 3959, + "remoteImagePaths": 3960, + "frontmatter": 3961, + "imagePaths": 3962 + }, + [ + 3908, 3910, 3913, 3916, 3919, 3922, 3925, 3928, 3931, 3934, 3937, 3940, 3943, 3946, 3949, 3952, + 3955, 3958 + ], + { "depth": 30, "slug": 3909, "text": 3897 }, + "regression-analysis", + { "depth": 33, "slug": 3911, "text": 3912 }, + "purpose", + "Purpose", + { "depth": 33, "slug": 3914, "text": 3915 }, + "key-metrics", + "Key Metrics", + { "depth": 33, "slug": 3917, "text": 3918 }, + "interpretation-guide", + "Interpretation Guide", + { "depth": 33, "slug": 3920, "text": 3921 }, + "use-in-variscout", + "Use in VariScout", + { "depth": 33, "slug": 3923, "text": 3924 }, + "multiple-regression", + "Multiple Regression", + { "depth": 79, "slug": 3926, "text": 3927 }, + "when-to-use-multiple-regression", + "When to Use Multiple Regression", + { "depth": 79, "slug": 3929, "text": 3930 }, + "vif-variance-inflation-factor", + "VIF (Variance Inflation Factor)", + { "depth": 79, "slug": 3932, "text": 3933 }, + "interpreting-coefficients", + "Interpreting Coefficients", + { "depth": 79, "slug": 3935, "text": 3936 }, + "model-selection-tips", + "Model Selection Tips", + { "depth": 33, "slug": 3938, "text": 3939 }, + "interaction-effects", + "Interaction Effects", + { "depth": 79, "slug": 3941, "text": 3942 }, + "why-check-for-interactions", + "Why Check for Interactions?", + { "depth": 79, "slug": 3944, "text": 3945 }, + "enabling-interactions-in-variscout", + "Enabling Interactions in VariScout", + { "depth": 79, "slug": 3947, "text": 3948 }, + "coming-from-investigation-mindmap", + "Coming from Investigation Mindmap", + { "depth": 79, "slug": 3950, "text": 3951 }, + "project-in-what-if", + "Project in What-If", + { "depth": 79, "slug": 3953, "text": 3954 }, + "interpreting-interaction-terms", + "Interpreting Interaction Terms", + { "depth": 33, "slug": 3956, "text": 3957 }, + "technical-reference", + "Technical Reference", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 3897 }, + [], + "archive/special-cause-education-phase2", + { "id": 3963, "data": 3965, "body": 3970, "filePath": 3971, "digest": 3972, "rendered": 3973 }, + { + "title": 3966, + "editUrl": 16, + "head": 3967, + "template": 18, + "sidebar": 3968, + "pagefind": 16, + "draft": 20 + }, + "Special Cause Education System - Phase 2 Implementation", + [], + { "hidden": 20, "attrs": 3969 }, + {}, + "> **ARCHIVED**: This document describes historical implementation details. Do not reference for current work.\n\n# Special Cause Education System - Phase 2 Implementation\n\n**Status**: ✅ COMPLETED\n**Date**: 2026-02-04\n**Implementation**: Website content enhancements\n\n---\n\n## Overview\n\nPhase 2 adds comprehensive website learning content for the Special Cause education system implemented in Phase 1. This includes:\n\n- New learn page: `/learn/control-charts`\n- Extended glossary content for 4 new terms\n- Cross-linking between tools, glossary, and learn pages\n\n## Implementation Summary\n\n### 1. New Learn Page: Control Charts & Special Cause Detection\n\n**File**: `apps/website/src/data/learnData.ts`\n\n**URL**: `https://variscout.com/en/learn/control-charts`\n\n**Content Structure** (8 sections):\n\n1. **What Are Control Charts?** - Introduction with embedded I-Chart example\n2. **Voice of Process vs Voice of Customer** - Control limits vs spec limits comparison\n3. **Special Cause vs Common Cause Variation** - The fundamental SPC distinction\n4. **What Do Point Colors Mean?** - 🔵 Blue (common), 🔴 Red (special), 🟠 Orange (out-of-spec)\n5. **Nelson Rule 2: Detecting Process Shifts** - 9 consecutive points pattern\n6. **How Control Limits Are Calculated** - UCL = X̄ + 3σ, LCL = X̄ - 3σ\n7. **The Power of Control Charts** - Preventing tampering and under-reaction\n8. **Applying Control Charts** - 4-step practical guide\n\n**Related Links**:\n\n- Tools: i-chart, boxplot, capability\n- Topics: two-voices, four-pillars, eda-philosophy, staged-analysis\n\n---\n\n### 2. Extended Glossary Terms\n\n**File**: `apps/website/src/data/glossaryData.ts`\n\nFour new terms added to `GLOSSARY_EXTENSIONS`:\n\n#### A. Special Cause Variation\n\n**URL**: `https://variscout.com/en/glossary/special-cause`\n\n**Rich Content**:\n\n- **Detection Methods** section:\n - Point Above UCL\n - Point Below LCL\n - Nelson Rule 2 (9+ consecutive points)\n- **Real-World Example**: Coffee roasting with Nelson Rule 2 detection\n- **Examples** (5 items):\n - Machine malfunction\n - Operator error\n - Material batch change\n - Environmental change\n - Measurement drift\n- **Practical Tip**: \"When you see red dots, investigate the timeline: What was different? (5Ms)\"\n\n**Related**:\n\n- Tools: i-chart, boxplot\n- Learn: control-charts, two-voices, four-pillars\n\n---\n\n#### B. Common Cause Variation\n\n**URL**: `https://variscout.com/en/glossary/common-cause`\n\n**Rich Content**:\n\n- **Characteristics** section:\n - Random Fluctuation\n - Predictable Range\n - Multiple Small Sources\n- **Real-World Example**: Packaging line with inherent variation\n- **Examples** (5 items):\n - Natural material variation\n - Normal machine vibration\n - Ambient temperature\n - Measurement precision\n - Operator technique (within training)\n- **Practical Tip**: \"⚠️ Do NOT react to individual blue dots. Reacting to common cause is called tampering.\"\n\n**Related**:\n\n- Tools: i-chart, capability\n- Learn: control-charts, two-voices\n\n---\n\n#### C. Nelson Rule 2\n\n**URL**: `https://variscout.com/en/glossary/nelson-rule-2`\n\n**Rich Content**:\n\n- **Rule Definition** section:\n - 9+ Points Consecutive\n - Direction Matters (9 above OR 9 below)\n - Indicates Shift (systematic, not random)\n- **Visual Pattern**: Description of VariScout's connector lines and markers\n- **Real-World Example**: Pharmaceutical tablet press with 11 consecutive points\n- **Examples** (5 items):\n - Settings adjusted mid-production\n - New material batch\n - Process drift over time\n - Operator change\n - Measurement bias shift\n- **Practical Tip**: \"Check timeline: What changed when sequence started? (batch numbers, shifts, material lots)\"\n\n**Related**:\n\n- Tools: i-chart\n- Learn: control-charts, two-voices\n\n---\n\n#### D. In-Control Process\n\n**URL**: `https://variscout.com/en/glossary/in-control`\n\n**Rich Content**:\n\n- **In-Control Criteria** section:\n - All Points Inside UCL/LCL\n - Random Variation Only (no patterns)\n - Predictable Performance\n- **CRITICAL Example**: In-Control ≠ Capable\n - Bolt diameter stable (UCL=10.5mm, LCL=9.5mm)\n - But customer spec (USL=10.2mm, LSL=9.8mm)\n - Process predictably makes defects\n- **Examples** (4 items):\n - Packaging line steady\n - Stable but off-target\n - In-control with high variation\n - Capable AND in-control (ideal)\n- **Practical Tip**: \"First achieve in-control (eliminate special cause), THEN assess capability.\"\n\n**Related**:\n\n- Tools: i-chart, capability\n- Learn: control-charts, two-voices, four-pillars\n\n---\n\n## Verification Results\n\n### Build Status\n\n✅ Website builds successfully without errors:\n\n```bash\npnpm build\n# Output: 364 page(s) built in 6.18s\n```\n\n### Generated Pages\n\n✅ All pages generated correctly:\n\n**Learn Page**:\n\n- `/en/learn/control-charts/index.html` ✅\n- Also generated for: de, es, fr, pt ✅\n\n**Glossary Pages**:\n\n- `/en/glossary/specialCause/index.html` ✅\n- `/en/glossary/commonCause/index.html` ✅\n- `/en/glossary/nelsonRule2/index.html` ✅\n- `/en/glossary/inControl/index.html` ✅\n- All translated versions ✅\n\n### Content Verification\n\n✅ Rich content sections render correctly:\n\n- Detection Methods with 3 items\n- Real-World Example in blue callout\n- Examples list (5 items each)\n- Practical Tip in amber callout\n- Related terms, tools, and learn pages with proper links\n\n---\n\n## Cross-Linking Architecture\n\n### HelpTooltip Integration\n\nAll new glossary terms are accessible via HelpTooltip components in PWA/Azure/Excel:\n\n```typescript\nimport { useGlossary } from '@variscout/ui';\n\nconst { getTermDefinition } = useGlossary();\nconst specialCauseDef = getTermDefinition('specialCause');\n// \"Learn more\" link → https://variscout.com/en/glossary/special-cause\n```\n\n### Website Navigation Flow\n\n**User Journey Examples**:\n\n1. **From I-Chart Tool Page**:\n - Tool description mentions \"special cause detection\"\n - Link → `/learn/control-charts`\n - Section 3 explains Special Cause vs Common Cause\n - Link → `/glossary/special-cause` for deep dive\n\n2. **From Glossary Index**:\n - Methodology category shows new terms\n - Click \"Special Cause\" → Rich content page\n - Related terms → Common Cause, Nelson Rule 2, In-Control, UCL, LCL\n - Related learn → Control Charts page\n\n3. **From Learn Index**:\n - See \"Control Charts & Special Cause Detection\" 🎯\n - Read 8 sections with examples\n - Related tools → I-Chart, Boxplot, Capability\n - Related topics → Two Voices, Four Pillars\n\n---\n\n## Educational Strategy Alignment\n\n### Philosophy Compliance\n\n✅ **Factual language** (not prescriptive):\n\n- \"Special Cause: Above UCL\" (states signal)\n- NOT \"Investigate root cause\" (prescriptive action)\n- VariScout identifies WHERE to focus; user determines WHY\n\n✅ **Special Cause emphasis**:\n\n- Red dots = Special Cause (Voice of Process instability)\n- Blue dots = Common Cause (random, inherent)\n- Orange dots = Out-of-Spec (Voice of Customer defects)\n\n✅ **Educational progression**:\n\n- Learn page teaches concepts\n- Glossary provides definitions\n- Tools apply concepts to real data\n- Case studies show examples\n\n---\n\n## Next Steps (Future Enhancements)\n\n### Optional Improvements\n\n1. **Interactive Examples**:\n - Embed live I-Chart with special cause violations\n - Users can click points to see violation tooltips\n - Implement in React Island component\n\n2. **Nelson Rules Expansion**:\n - Add pages for Nelson Rules 1, 3-8\n - Show visual patterns for each rule\n - Link from control-charts learn page\n\n3. **Video Content**:\n - Short explainer video for Special vs Common Cause\n - Screen recording showing VariScout's Nelson Rule 2 visualization\n - Embed in learn page or glossary\n\n4. **Quiz/Assessment**:\n - Interactive quiz: \"Is this Special or Common Cause?\"\n - Show chart patterns, user selects answer\n - Immediate feedback with explanation\n\n---\n\n## Technical Details\n\n### File Changes\n\n1. **Learn Data** (`apps/website/src/data/learnData.ts`):\n - Added control-charts topic to LEARN_TOPICS array\n - 8 sections with visual types: chart, comparison, list, diagram, quote\n - +155 lines\n\n2. **Glossary Data** (`apps/website/src/data/glossaryData.ts`):\n - Extended GLOSSARY_EXTENSIONS with 4 new entries\n - Each with sections, examples, practical tips\n - +176 lines\n\n### Content Size\n\n- **Control Charts Learn Page**: ~2,500 words\n- **Special Cause Glossary**: ~500 words + examples\n- **Common Cause Glossary**: ~500 words + examples\n- **Nelson Rule 2 Glossary**: ~400 words + examples\n- **In-Control Glossary**: ~400 words + examples\n\n**Total**: ~4,300 words of educational content\n\n---\n\n## Success Metrics\n\n### Immediate Impact\n\n✅ **Phase 1 + Phase 2** complete:\n\n1. Enhanced tooltips ✅\n2. Data window annotations ✅\n3. Nelson Rule 2 visualization ✅\n4. Chart legend ✅\n5. Glossary terms (core package) ✅\n6. **Website learn page** ✅ (this phase)\n7. **Glossary extensions** ✅ (this phase)\n\n### User Experience Goals\n\n1. **Understanding**: Users can explain why points are red\n2. **SPC Knowledge**: Users understand Special vs Common Cause\n3. **Audit Trail**: Data window shows persistent violations\n4. **Pattern Recognition**: Nelson Rule 2 is visually obvious\n5. **Deep Learning**: Glossary + learn pages support exploration\n6. **Discoverability**: Cross-links guide learning journey\n\n---\n\n## Deployment Checklist\n\n- [x] TypeScript builds without errors\n- [x] All 4 glossary pages generated\n- [x] Control-charts learn page generated\n- [x] Rich content sections render correctly\n- [x] Cross-links work (related terms, tools, learn)\n- [x] Content follows philosophy (factual, not prescriptive)\n- [x] Multi-language support (en, de, es, fr, pt)\n- [ ] Publish to production (separate step)\n- [ ] Update CHANGELOG.md\n- [ ] Update documentation index\n\n---\n\n## Summary\n\nPhase 2 successfully extends the Special Cause education system to the website with:\n\n- **1 new learn page** (control-charts) with 8 sections\n- **4 extended glossary terms** with rich content\n- **Full cross-linking** between tools, glossary, and learn pages\n- **~4,300 words** of educational content\n- **Philosophy-compliant** language (factual, not prescriptive)\n- **Multi-language support** (5 languages)\n\nUsers can now:\n\n1. Hover over red dots in charts → See factual violation explanation\n2. View data window → See persistent violation markers\n3. Click HelpTooltip → Read glossary definition\n4. Click \"Learn more\" → Deep dive into control-charts page\n5. Explore related terms → Build comprehensive SPC knowledge\n\nThe Special Cause education system is now complete across PWA, Azure, Excel, and Website.", + "src/content/docs/archive/special-cause-education-phase2.md", + "3e26feaa92f2a354", + { "html": 3974, "metadata": 3975 }, + "\u003Cblockquote>\n\u003Cp>\u003Cstrong>ARCHIVED\u003C/strong>: This document describes historical implementation details. Do not reference for current work.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"special-cause-education-system---phase-2-implementation\">Special Cause Education System - Phase 2 Implementation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#special-cause-education-system---phase-2-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Special Cause Education System - Phase 2 Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: ✅ COMPLETED\n\u003Cstrong>Date\u003C/strong>: 2026-02-04\n\u003Cstrong>Implementation\u003C/strong>: Website content enhancements\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Phase 2 adds comprehensive website learning content for the Special Cause education system implemented in Phase 1. This includes:\u003C/p>\n\u003Cul>\n\u003Cli>New learn page: \u003Ccode dir=\"auto\">/learn/control-charts\u003C/code>\u003C/li>\n\u003Cli>Extended glossary content for 4 new terms\u003C/li>\n\u003Cli>Cross-linking between tools, glossary, and learn pages\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation-summary\">Implementation Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-new-learn-page-control-charts--special-cause-detection\">1. New Learn Page: Control Charts & Special Cause Detection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-new-learn-page-control-charts--special-cause-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. New Learn Page: Control Charts & Special Cause Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>File\u003C/strong>: \u003Ccode dir=\"auto\">apps/website/src/data/learnData.ts\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>URL\u003C/strong>: \u003Ccode dir=\"auto\">https://variscout.com/en/learn/control-charts\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>Content Structure\u003C/strong> (8 sections):\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>What Are Control Charts?\u003C/strong> - Introduction with embedded I-Chart example\u003C/li>\n\u003Cli>\u003Cstrong>Voice of Process vs Voice of Customer\u003C/strong> - Control limits vs spec limits comparison\u003C/li>\n\u003Cli>\u003Cstrong>Special Cause vs Common Cause Variation\u003C/strong> - The fundamental SPC distinction\u003C/li>\n\u003Cli>\u003Cstrong>What Do Point Colors Mean?\u003C/strong> - 🔵 Blue (common), 🔴 Red (special), 🟠 Orange (out-of-spec)\u003C/li>\n\u003Cli>\u003Cstrong>Nelson Rule 2: Detecting Process Shifts\u003C/strong> - 9 consecutive points pattern\u003C/li>\n\u003Cli>\u003Cstrong>How Control Limits Are Calculated\u003C/strong> - UCL = X̄ + 3σ, LCL = X̄ - 3σ\u003C/li>\n\u003Cli>\u003Cstrong>The Power of Control Charts\u003C/strong> - Preventing tampering and under-reaction\u003C/li>\n\u003Cli>\u003Cstrong>Applying Control Charts\u003C/strong> - 4-step practical guide\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Related Links\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Tools: i-chart, boxplot, capability\u003C/li>\n\u003Cli>Topics: two-voices, four-pillars, eda-philosophy, staged-analysis\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-extended-glossary-terms\">2. Extended Glossary Terms\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-extended-glossary-terms\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Extended Glossary Terms”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>File\u003C/strong>: \u003Ccode dir=\"auto\">apps/website/src/data/glossaryData.ts\u003C/code>\u003C/p>\n\u003Cp>Four new terms added to \u003Ccode dir=\"auto\">GLOSSARY_EXTENSIONS\u003C/code>:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"a-special-cause-variation\">A. Special Cause Variation\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#a-special-cause-variation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “A. Special Cause Variation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>URL\u003C/strong>: \u003Ccode dir=\"auto\">https://variscout.com/en/glossary/special-cause\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>Rich Content\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Detection Methods\u003C/strong> section:\n\u003Cul>\n\u003Cli>Point Above UCL\u003C/li>\n\u003Cli>Point Below LCL\u003C/li>\n\u003Cli>Nelson Rule 2 (9+ consecutive points)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Real-World Example\u003C/strong>: Coffee roasting with Nelson Rule 2 detection\u003C/li>\n\u003Cli>\u003Cstrong>Examples\u003C/strong> (5 items):\n\u003Cul>\n\u003Cli>Machine malfunction\u003C/li>\n\u003Cli>Operator error\u003C/li>\n\u003Cli>Material batch change\u003C/li>\n\u003Cli>Environmental change\u003C/li>\n\u003Cli>Measurement drift\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Practical Tip\u003C/strong>: “When you see red dots, investigate the timeline: What was different? (5Ms)”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Tools: i-chart, boxplot\u003C/li>\n\u003Cli>Learn: control-charts, two-voices, four-pillars\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"b-common-cause-variation\">B. Common Cause Variation\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#b-common-cause-variation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “B. Common Cause Variation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>URL\u003C/strong>: \u003Ccode dir=\"auto\">https://variscout.com/en/glossary/common-cause\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>Rich Content\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Characteristics\u003C/strong> section:\n\u003Cul>\n\u003Cli>Random Fluctuation\u003C/li>\n\u003Cli>Predictable Range\u003C/li>\n\u003Cli>Multiple Small Sources\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Real-World Example\u003C/strong>: Packaging line with inherent variation\u003C/li>\n\u003Cli>\u003Cstrong>Examples\u003C/strong> (5 items):\n\u003Cul>\n\u003Cli>Natural material variation\u003C/li>\n\u003Cli>Normal machine vibration\u003C/li>\n\u003Cli>Ambient temperature\u003C/li>\n\u003Cli>Measurement precision\u003C/li>\n\u003Cli>Operator technique (within training)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Practical Tip\u003C/strong>: “⚠️ Do NOT react to individual blue dots. Reacting to common cause is called tampering.”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Tools: i-chart, capability\u003C/li>\n\u003Cli>Learn: control-charts, two-voices\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"c-nelson-rule-2\">C. Nelson Rule 2\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#c-nelson-rule-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “C. Nelson Rule 2”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>URL\u003C/strong>: \u003Ccode dir=\"auto\">https://variscout.com/en/glossary/nelson-rule-2\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>Rich Content\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Rule Definition\u003C/strong> section:\n\u003Cul>\n\u003Cli>9+ Points Consecutive\u003C/li>\n\u003Cli>Direction Matters (9 above OR 9 below)\u003C/li>\n\u003Cli>Indicates Shift (systematic, not random)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Visual Pattern\u003C/strong>: Description of VariScout’s connector lines and markers\u003C/li>\n\u003Cli>\u003Cstrong>Real-World Example\u003C/strong>: Pharmaceutical tablet press with 11 consecutive points\u003C/li>\n\u003Cli>\u003Cstrong>Examples\u003C/strong> (5 items):\n\u003Cul>\n\u003Cli>Settings adjusted mid-production\u003C/li>\n\u003Cli>New material batch\u003C/li>\n\u003Cli>Process drift over time\u003C/li>\n\u003Cli>Operator change\u003C/li>\n\u003Cli>Measurement bias shift\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Practical Tip\u003C/strong>: “Check timeline: What changed when sequence started? (batch numbers, shifts, material lots)”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Tools: i-chart\u003C/li>\n\u003Cli>Learn: control-charts, two-voices\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"d-in-control-process\">D. In-Control Process\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#d-in-control-process\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “D. In-Control Process”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>URL\u003C/strong>: \u003Ccode dir=\"auto\">https://variscout.com/en/glossary/in-control\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>Rich Content\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>In-Control Criteria\u003C/strong> section:\n\u003Cul>\n\u003Cli>All Points Inside UCL/LCL\u003C/li>\n\u003Cli>Random Variation Only (no patterns)\u003C/li>\n\u003Cli>Predictable Performance\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>CRITICAL Example\u003C/strong>: In-Control ≠ Capable\n\u003Cul>\n\u003Cli>Bolt diameter stable (UCL=10.5mm, LCL=9.5mm)\u003C/li>\n\u003Cli>But customer spec (USL=10.2mm, LSL=9.8mm)\u003C/li>\n\u003Cli>Process predictably makes defects\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Examples\u003C/strong> (4 items):\n\u003Cul>\n\u003Cli>Packaging line steady\u003C/li>\n\u003Cli>Stable but off-target\u003C/li>\n\u003Cli>In-control with high variation\u003C/li>\n\u003Cli>Capable AND in-control (ideal)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Practical Tip\u003C/strong>: “First achieve in-control (eliminate special cause), THEN assess capability.”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Tools: i-chart, capability\u003C/li>\n\u003Cli>Learn: control-charts, two-voices, four-pillars\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"verification-results\">Verification Results\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#verification-results\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Verification Results”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"build-status\">Build Status\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#build-status\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Build Status”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>✅ Website builds successfully without errors:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Output: 364 page(s) built in 6.18s\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm build\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"generated-pages\">Generated Pages\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#generated-pages\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Generated Pages”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>✅ All pages generated correctly:\u003C/p>\n\u003Cp>\u003Cstrong>Learn Page\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">/en/learn/control-charts/index.html\u003C/code> ✅\u003C/li>\n\u003Cli>Also generated for: de, es, fr, pt ✅\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Glossary Pages\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">/en/glossary/specialCause/index.html\u003C/code> ✅\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">/en/glossary/commonCause/index.html\u003C/code> ✅\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">/en/glossary/nelsonRule2/index.html\u003C/code> ✅\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">/en/glossary/inControl/index.html\u003C/code> ✅\u003C/li>\n\u003Cli>All translated versions ✅\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"content-verification\">Content Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#content-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Content Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>✅ Rich content sections render correctly:\u003C/p>\n\u003Cul>\n\u003Cli>Detection Methods with 3 items\u003C/li>\n\u003Cli>Real-World Example in blue callout\u003C/li>\n\u003Cli>Examples list (5 items each)\u003C/li>\n\u003Cli>Practical Tip in amber callout\u003C/li>\n\u003Cli>Related terms, tools, and learn pages with proper links\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-linking-architecture\">Cross-Linking Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-linking-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Linking Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"helptooltip-integration\">HelpTooltip Integration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#helptooltip-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “HelpTooltip Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All new glossary terms are accessible via HelpTooltip components in PWA/Azure/Excel:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useGlossary } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getTermDefinition\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useGlossary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">specialCauseDef\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getTermDefinition\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">specialCause\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// \"Learn more\" link → https://variscout.com/en/glossary/special-cause\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useGlossary } from '@variscout/ui';const { getTermDefinition } = useGlossary();const specialCauseDef = getTermDefinition('specialCause');// "Learn more" link → https://variscout.com/en/glossary/special-cause\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"website-navigation-flow\">Website Navigation Flow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#website-navigation-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Navigation Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>User Journey Examples\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>From I-Chart Tool Page\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Tool description mentions “special cause detection”\u003C/li>\n\u003Cli>Link → \u003Ccode dir=\"auto\">/learn/control-charts\u003C/code>\u003C/li>\n\u003Cli>Section 3 explains Special Cause vs Common Cause\u003C/li>\n\u003Cli>Link → \u003Ccode dir=\"auto\">/glossary/special-cause\u003C/code> for deep dive\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>From Glossary Index\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Methodology category shows new terms\u003C/li>\n\u003Cli>Click “Special Cause” → Rich content page\u003C/li>\n\u003Cli>Related terms → Common Cause, Nelson Rule 2, In-Control, UCL, LCL\u003C/li>\n\u003Cli>Related learn → Control Charts page\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>From Learn Index\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>See “Control Charts & Special Cause Detection” 🎯\u003C/li>\n\u003Cli>Read 8 sections with examples\u003C/li>\n\u003Cli>Related tools → I-Chart, Boxplot, Capability\u003C/li>\n\u003Cli>Related topics → Two Voices, Four Pillars\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"educational-strategy-alignment\">Educational Strategy Alignment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#educational-strategy-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Educational Strategy Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"philosophy-compliance\">Philosophy Compliance\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy-compliance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy Compliance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>✅ \u003Cstrong>Factual language\u003C/strong> (not prescriptive):\u003C/p>\n\u003Cul>\n\u003Cli>“Special Cause: Above UCL” (states signal)\u003C/li>\n\u003Cli>NOT “Investigate root cause” (prescriptive action)\u003C/li>\n\u003Cli>VariScout identifies WHERE to focus; user determines WHY\u003C/li>\n\u003C/ul>\n\u003Cp>✅ \u003Cstrong>Special Cause emphasis\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Red dots = Special Cause (Voice of Process instability)\u003C/li>\n\u003Cli>Blue dots = Common Cause (random, inherent)\u003C/li>\n\u003Cli>Orange dots = Out-of-Spec (Voice of Customer defects)\u003C/li>\n\u003C/ul>\n\u003Cp>✅ \u003Cstrong>Educational progression\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Learn page teaches concepts\u003C/li>\n\u003Cli>Glossary provides definitions\u003C/li>\n\u003Cli>Tools apply concepts to real data\u003C/li>\n\u003Cli>Case studies show examples\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"next-steps-future-enhancements\">Next Steps (Future Enhancements)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#next-steps-future-enhancements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Next Steps (Future Enhancements)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"optional-improvements\">Optional Improvements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#optional-improvements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Optional Improvements”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Interactive Examples\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Embed live I-Chart with special cause violations\u003C/li>\n\u003Cli>Users can click points to see violation tooltips\u003C/li>\n\u003Cli>Implement in React Island component\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Nelson Rules Expansion\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Add pages for Nelson Rules 1, 3-8\u003C/li>\n\u003Cli>Show visual patterns for each rule\u003C/li>\n\u003Cli>Link from control-charts learn page\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Video Content\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Short explainer video for Special vs Common Cause\u003C/li>\n\u003Cli>Screen recording showing VariScout’s Nelson Rule 2 visualization\u003C/li>\n\u003Cli>Embed in learn page or glossary\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Quiz/Assessment\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Interactive quiz: “Is this Special or Common Cause?”\u003C/li>\n\u003Cli>Show chart patterns, user selects answer\u003C/li>\n\u003Cli>Immediate feedback with explanation\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-details\">Technical Details\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-details\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Details”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"file-changes\">File Changes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#file-changes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “File Changes”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Learn Data\u003C/strong> (\u003Ccode dir=\"auto\">apps/website/src/data/learnData.ts\u003C/code>):\u003C/p>\n\u003Cul>\n\u003Cli>Added control-charts topic to LEARN_TOPICS array\u003C/li>\n\u003Cli>8 sections with visual types: chart, comparison, list, diagram, quote\u003C/li>\n\u003Cli>+155 lines\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Glossary Data\u003C/strong> (\u003Ccode dir=\"auto\">apps/website/src/data/glossaryData.ts\u003C/code>):\u003C/p>\n\u003Cul>\n\u003Cli>Extended GLOSSARY_EXTENSIONS with 4 new entries\u003C/li>\n\u003Cli>Each with sections, examples, practical tips\u003C/li>\n\u003Cli>+176 lines\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"content-size\">Content Size\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#content-size\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Content Size”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Control Charts Learn Page\u003C/strong>: ~2,500 words\u003C/li>\n\u003Cli>\u003Cstrong>Special Cause Glossary\u003C/strong>: ~500 words + examples\u003C/li>\n\u003Cli>\u003Cstrong>Common Cause Glossary\u003C/strong>: ~500 words + examples\u003C/li>\n\u003Cli>\u003Cstrong>Nelson Rule 2 Glossary\u003C/strong>: ~400 words + examples\u003C/li>\n\u003Cli>\u003Cstrong>In-Control Glossary\u003C/strong>: ~400 words + examples\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Total\u003C/strong>: ~4,300 words of educational content\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"immediate-impact\">Immediate Impact\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#immediate-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Immediate Impact”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>✅ \u003Cstrong>Phase 1 + Phase 2\u003C/strong> complete:\u003C/p>\n\u003Col>\n\u003Cli>Enhanced tooltips ✅\u003C/li>\n\u003Cli>Data window annotations ✅\u003C/li>\n\u003Cli>Nelson Rule 2 visualization ✅\u003C/li>\n\u003Cli>Chart legend ✅\u003C/li>\n\u003Cli>Glossary terms (core package) ✅\u003C/li>\n\u003Cli>\u003Cstrong>Website learn page\u003C/strong> ✅ (this phase)\u003C/li>\n\u003Cli>\u003Cstrong>Glossary extensions\u003C/strong> ✅ (this phase)\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-experience-goals\">User Experience Goals\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-experience-goals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Experience Goals”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Understanding\u003C/strong>: Users can explain why points are red\u003C/li>\n\u003Cli>\u003Cstrong>SPC Knowledge\u003C/strong>: Users understand Special vs Common Cause\u003C/li>\n\u003Cli>\u003Cstrong>Audit Trail\u003C/strong>: Data window shows persistent violations\u003C/li>\n\u003Cli>\u003Cstrong>Pattern Recognition\u003C/strong>: Nelson Rule 2 is visually obvious\u003C/li>\n\u003Cli>\u003Cstrong>Deep Learning\u003C/strong>: Glossary + learn pages support exploration\u003C/li>\n\u003Cli>\u003Cstrong>Discoverability\u003C/strong>: Cross-links guide learning journey\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"deployment-checklist\">Deployment Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#deployment-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> TypeScript builds without errors\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> All 4 glossary pages generated\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Control-charts learn page generated\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Rich content sections render correctly\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Cross-links work (related terms, tools, learn)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Content follows philosophy (factual, not prescriptive)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" checked disabled> Multi-language support (en, de, es, fr, pt)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Publish to production (separate step)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Update CHANGELOG.md\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Update documentation index\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"summary\">Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Phase 2 successfully extends the Special Cause education system to the website with:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>1 new learn page\u003C/strong> (control-charts) with 8 sections\u003C/li>\n\u003Cli>\u003Cstrong>4 extended glossary terms\u003C/strong> with rich content\u003C/li>\n\u003Cli>\u003Cstrong>Full cross-linking\u003C/strong> between tools, glossary, and learn pages\u003C/li>\n\u003Cli>\u003Cstrong>~4,300 words\u003C/strong> of educational content\u003C/li>\n\u003Cli>\u003Cstrong>Philosophy-compliant\u003C/strong> language (factual, not prescriptive)\u003C/li>\n\u003Cli>\u003Cstrong>Multi-language support\u003C/strong> (5 languages)\u003C/li>\n\u003C/ul>\n\u003Cp>Users can now:\u003C/p>\n\u003Col>\n\u003Cli>Hover over red dots in charts → See factual violation explanation\u003C/li>\n\u003Cli>View data window → See persistent violation markers\u003C/li>\n\u003Cli>Click HelpTooltip → Read glossary definition\u003C/li>\n\u003Cli>Click “Learn more” → Deep dive into control-charts page\u003C/li>\n\u003Cli>Explore related terms → Build comprehensive SPC knowledge\u003C/li>\n\u003C/ol>\n\u003Cp>The Special Cause education system is now complete across PWA, Azure, Excel, and Website.\u003C/p>", + { + "headings": 3976, + "localImagePaths": 4048, + "remoteImagePaths": 4049, + "frontmatter": 4050, + "imagePaths": 4051 + }, + [ + 3977, 3979, 3980, 3983, 3986, 3989, 3992, 3995, 3998, 4001, 4002, 4003, 4006, 4009, 4012, 4015, + 4018, 4021, 4024, 4027, 4030, 4031, 4034, 4037, 4038, 4041, 4044, 4047 + ], + { "depth": 30, "slug": 3978, "text": 3966 }, + "special-cause-education-system---phase-2-implementation", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 3981, "text": 3982 }, + "implementation-summary", + "Implementation Summary", + { "depth": 79, "slug": 3984, "text": 3985 }, + "1-new-learn-page-control-charts--special-cause-detection", + "1. New Learn Page: Control Charts & Special Cause Detection", + { "depth": 79, "slug": 3987, "text": 3988 }, + "2-extended-glossary-terms", + "2. Extended Glossary Terms", + { "depth": 621, "slug": 3990, "text": 3991 }, + "a-special-cause-variation", + "A. Special Cause Variation", + { "depth": 621, "slug": 3993, "text": 3994 }, + "b-common-cause-variation", + "B. Common Cause Variation", + { "depth": 621, "slug": 3996, "text": 3997 }, + "c-nelson-rule-2", + "C. Nelson Rule 2", + { "depth": 621, "slug": 3999, "text": 4000 }, + "d-in-control-process", + "D. In-Control Process", + { "depth": 33, "slug": 3805, "text": 3806 }, + { "depth": 79, "slug": 3631, "text": 3632 }, + { "depth": 79, "slug": 4004, "text": 4005 }, + "generated-pages", + "Generated Pages", + { "depth": 79, "slug": 4007, "text": 4008 }, + "content-verification", + "Content Verification", + { "depth": 33, "slug": 4010, "text": 4011 }, + "cross-linking-architecture", + "Cross-Linking Architecture", + { "depth": 79, "slug": 4013, "text": 4014 }, + "helptooltip-integration", + "HelpTooltip Integration", + { "depth": 79, "slug": 4016, "text": 4017 }, + "website-navigation-flow", + "Website Navigation Flow", + { "depth": 33, "slug": 4019, "text": 4020 }, + "educational-strategy-alignment", + "Educational Strategy Alignment", + { "depth": 79, "slug": 4022, "text": 4023 }, + "philosophy-compliance", + "Philosophy Compliance", + { "depth": 33, "slug": 4025, "text": 4026 }, + "next-steps-future-enhancements", + "Next Steps (Future Enhancements)", + { "depth": 79, "slug": 4028, "text": 4029 }, + "optional-improvements", + "Optional Improvements", + { "depth": 33, "slug": 3815, "text": 3816 }, + { "depth": 79, "slug": 4032, "text": 4033 }, + "file-changes", + "File Changes", + { "depth": 79, "slug": 4035, "text": 4036 }, + "content-size", + "Content Size", + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 79, "slug": 4039, "text": 4040 }, + "immediate-impact", + "Immediate Impact", + { "depth": 79, "slug": 4042, "text": 4043 }, + "user-experience-goals", + "User Experience Goals", + { "depth": 33, "slug": 4045, "text": 4046 }, + "deployment-checklist", + "Deployment Checklist", + { "depth": 33, "slug": 1450, "text": 1451 }, + [], + [], + { "title": 3966 }, + [], + "02-journeys/flows/azure-daily-use", + { "id": 4052, "data": 4054, "body": 4059, "filePath": 4060, "digest": 4061, "rendered": 4062 }, + { + "title": 4055, + "editUrl": 16, + "head": 4056, + "template": 18, + "sidebar": 4057, + "pagefind": 16, + "draft": 20 + }, + "Flow 7: Azure App — Daily Use", + [], + { "hidden": 20, "attrs": 4058 }, + {}, + "# Flow 7: Azure App — Daily Use\n\n> Green Belt Gary's daily workflow: repeat analysis, Performance Mode, exports\n>\n> **Priority:** High - retention (ongoing value delivery)\n>\n> See also: [Journeys Overview](../index.md) | [First Analysis](azure-first-analysis.md) | [Team Collaboration](azure-team-collaboration.md)\n\n---\n\n## Persona: Green Belt Gary (Established User)\n\n| Attribute | Detail |\n| ----------------- | ------------------------------------------------------------ |\n| **Role** | Quality Engineer, daily VariScout user |\n| **Goal** | Analyze new production batches, track trends, share findings |\n| **Knowledge** | Knows the app, comfortable with drill-down |\n| **Pain points** | Needs fast data turnaround, multiple measurement channels |\n| **Entry point** | Bookmark, Teams tab, or browser history |\n| **Decision mode** | Efficient — wants to load data and get answers quickly |\n\n### What Gary is thinking:\n\n- \"New batch data came in — let me check stability\"\n- \"Which filling heads are drifting?\"\n- \"I need to export this chart for the morning meeting\"\n- \"Can I compare all channels at once?\"\n\n---\n\n## Journey Flow\n\n### Mermaid Flowchart\n\n```mermaid\nflowchart TD\n A[Open app via bookmark or Teams] --> B[SSO: session cookie auto-authenticates]\n B --> C{What to do?}\n C -->|Resume| D[Open saved analysis from list]\n C -->|New data| E[Create new analysis]\n D --> F[Dashboard loads from storage]\n E --> G{Data source}\n G -->|Upload| H[CSV/Excel file]\n G -->|Paste| I[Paste from spreadsheet]\n H --> J[Column mapping]\n I --> J\n J --> K[Dashboard]\n F --> K\n K --> L{Analysis workflow}\n L -->|Quick check| M[I-Chart stability + Stats review]\n L -->|Deep dive| N[Add factors, drill-down, Pareto]\n L -->|Multi-channel| O[Performance Mode]\n M --> P{Share or export?}\n N --> P\n O --> P\n P -->|Export CSV| Q[Download filtered data]\n P -->|Copy chart| R[Clipboard: chart as image]\n P -->|Edit title| S[Custom chart title for report]\n P -->|Done| T[Click Save — local + OneDrive sync on Team plan]\n```\n\n### Daily Use Journey\n\n```mermaid\njourney\n title Daily Analysis Workflow\n section Open\n Launch app: 5: User\n SSO auto-login: 5: User\n Open saved analysis or start new: 5: User\n section Analyze\n Quick check I-Chart: 5: User\n Review stats and ANOVA: 5: User\n Drill into problem area: 5: User\n section Performance Mode\n Switch to multi-channel view: 4: User\n Pareto ranking worst-first: 5: User\n Drill into worst channel: 5: User\n section Export\n Copy chart to clipboard: 5: User\n Download CSV export: 5: User\n Save analysis: 5: User\n```\n\n---\n\n## Daily Workflows\n\n### Quick Check (2–3 minutes)\n\nThe most common daily task: verify stability of a production process.\n\n1. Open the app — SSO authenticates automatically (EasyAuth session cookie)\n2. Open existing analysis from the saved list (loaded from IndexedDB; Team plan also syncs via OneDrive)\n3. Upload or paste today's data batch\n4. Check I-Chart: are points within control limits? Any Nelson rule violations?\n5. Review Stats panel: mean, sigma, Cp/Cpk\n6. Done — close or continue to deep dive\n\n### Deep Dive (5–15 minutes)\n\nWhen the quick check reveals issues:\n\n1. Add or change factors via the **\"Factors\" button** in the nav bar (reopens ColumnMapping, up to 6)\n2. Check ANOVA: is the factor significant? (p-value, eta-squared)\n3. Drill down: click Boxplot bars or Pareto categories to filter\n4. Follow the breadcrumb trail — each chip shows variation contribution (eta-squared %)\n5. Use the **Investigation Mindmap** to visualize the drill-down tree\n6. Identify the root cause factor/level combination\n\n### Performance Mode (Multi-Channel Analysis)\n\nFor processes with many measurement points (filling heads, cavities, test stations):\n\n1. Upload data with multiple numeric columns (channels)\n2. App detects wide format and suggests Performance Mode\n3. **Performance I-Chart** — Cpk scatter plot by channel\n4. **Performance Pareto** — channels ranked worst-first (up to 20)\n5. **Performance Boxplot** — distribution comparison (top 5)\n6. Click a channel to drill into its individual analysis\n7. **Performance Capability** — histogram for the selected channel\n\n---\n\n## Export and Sharing\n\n| Action | How | Output |\n| ---------------- | ------------------------------------------------- | ---------------------------- |\n| CSV export | Editor header button | Filtered data as CSV |\n| Copy chart | Chart card menu → \"Copy to clipboard\" | PNG image on clipboard |\n| Edit chart title | Click chart title → type custom text | Appears in copied image |\n| Download chart | Chart card menu → \"Download\" | PNG file |\n| Share analysis | Share the `.vrs` file from OneDrive _(Team plan)_ | Colleague opens in their app |\n\n---\n\n## Settings\n\nAccessible from the settings panel:\n\n| Setting | Options | Effect |\n| ---------------- | --------------------- | ----------------------- |\n| Theme | Light / Dark / System | Switches all UI colors |\n| Company accent | Color picker | Brand color on headers |\n| Chart font scale | Slider | Adjusts chart text size |\n\n---\n\n## Platform Capabilities (Established User)\n\n| Capability | Detail |\n| ------------------- | ----------------------------------------------------------------------- |\n| Saved analyses | Listed on open; synced via OneDrive on Team plan (Standard: local-only) |\n| Factor management | Add/remove/change up to 6 factors during analysis |\n| Row capacity | 100,000 rows |\n| Performance Mode | Multi-channel Cpk analysis (hundreds of channels) |\n| Offline work | Full functionality, queues sync for reconnection |\n| Chart branding | No VariScout branding (enterprise tier) |\n| Capability analysis | Histogram + probability plot with Cp/Cpk |\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ----------------------------------- | ------ |\n| Sessions per week (active user) | > 3 |\n| Time to first chart (returning) | \u003C 30s |\n| Drill-down depth (avg) | > 2 |\n| Performance Mode adoption | > 20% |\n| Chart export per session | Track |\n| Analyses saved (per user per month) | Track |\n\n---\n\n## See Also\n\n- [First Analysis](azure-first-analysis.md) — onboarding journey\n- [Team Collaboration](azure-team-collaboration.md) — sharing and admin setup\n- [Performance Mode](../../03-features/analysis/performance-mode.md) — multi-channel analysis\n- [Drill-Down Workflow](../../03-features/workflows/drill-down-workflow.md) — investigation methodology\n- [Four Lenses Workflow](../../03-features/workflows/four-lenses-workflow.md) — analysis framework", + "src/content/docs/02-journeys/flows/azure-daily-use.md", + "178ffa655c4ee7cd", + { "html": 4063, "metadata": 4064 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"flow-7-azure-app--daily-use\">Flow 7: Azure App — Daily Use\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#flow-7-azure-app--daily-use\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 7: Azure App — Daily Use”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Green Belt Gary’s daily workflow: repeat analysis, Performance Mode, exports\u003C/p>\n\u003Cp>\u003Cstrong>Priority:\u003C/strong> High - retention (ongoing value delivery)\u003C/p>\n\u003Cp>See also: \u003Ca href=\"../index.md\">Journeys Overview\u003C/a> | \u003Ca href=\"azure-first-analysis.md\">First Analysis\u003C/a> | \u003Ca href=\"azure-team-collaboration.md\">Team Collaboration\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-green-belt-gary-established-user\">Persona: Green Belt Gary (Established User)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-green-belt-gary-established-user\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona: Green Belt Gary (Established User)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Quality Engineer, daily VariScout user\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Analyze new production batches, track trends, share findings\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Knows the app, comfortable with drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Needs fast data turnaround, multiple measurement channels\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Entry point\u003C/strong>\u003C/td>\u003Ctd>Bookmark, Teams tab, or browser history\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Efficient — wants to load data and get answers quickly\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-gary-is-thinking\">What Gary is thinking:\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-gary-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Gary is thinking:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“New batch data came in — let me check stability”\u003C/li>\n\u003Cli>“Which filling heads are drifting?”\u003C/li>\n\u003Cli>“I need to export this chart for the morning meeting”\u003C/li>\n\u003Cli>“Can I compare all channels at once?”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mermaid-flowchart\">Mermaid Flowchart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mermaid-flowchart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mermaid Flowchart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Open app via bookmark or Teams] --> B[SSO: session cookie auto-authenticates]\n B --> C{What to do?}\n C -->|Resume| D[Open saved analysis from list]\n C -->|New data| E[Create new analysis]\n D --> F[Dashboard loads from storage]\n E --> G{Data source}\n G -->|Upload| H[CSV/Excel file]\n G -->|Paste| I[Paste from spreadsheet]\n H --> J[Column mapping]\n I --> J\n J --> K[Dashboard]\n F --> K\n K --> L{Analysis workflow}\n L -->|Quick check| M[I-Chart stability + Stats review]\n L -->|Deep dive| N[Add factors, drill-down, Pareto]\n L -->|Multi-channel| O[Performance Mode]\n M --> P{Share or export?}\n N --> P\n O --> P\n P -->|Export CSV| Q[Download filtered data]\n P -->|Copy chart| R[Clipboard: chart as image]\n P -->|Edit title| S[Custom chart title for report]\n P -->|Done| T[Click Save — local + OneDrive sync on Team plan]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"daily-use-journey\">Daily Use Journey\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#daily-use-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Daily Use Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Daily Analysis Workflow\n section Open\n Launch app: 5: User\n SSO auto-login: 5: User\n Open saved analysis or start new: 5: User\n section Analyze\n Quick check I-Chart: 5: User\n Review stats and ANOVA: 5: User\n Drill into problem area: 5: User\n section Performance Mode\n Switch to multi-channel view: 4: User\n Pareto ranking worst-first: 5: User\n Drill into worst channel: 5: User\n section Export\n Copy chart to clipboard: 5: User\n Download CSV export: 5: User\n Save analysis: 5: User\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"daily-workflows\">Daily Workflows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#daily-workflows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Daily Workflows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"quick-check-23-minutes\">Quick Check (2–3 minutes)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#quick-check-23-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Check (2–3 minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The most common daily task: verify stability of a production process.\u003C/p>\n\u003Col>\n\u003Cli>Open the app — SSO authenticates automatically (EasyAuth session cookie)\u003C/li>\n\u003Cli>Open existing analysis from the saved list (loaded from IndexedDB; Team plan also syncs via OneDrive)\u003C/li>\n\u003Cli>Upload or paste today’s data batch\u003C/li>\n\u003Cli>Check I-Chart: are points within control limits? Any Nelson rule violations?\u003C/li>\n\u003Cli>Review Stats panel: mean, sigma, Cp/Cpk\u003C/li>\n\u003Cli>Done — close or continue to deep dive\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deep-dive-515-minutes\">Deep Dive (5–15 minutes)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deep-dive-515-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deep Dive (5–15 minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When the quick check reveals issues:\u003C/p>\n\u003Col>\n\u003Cli>Add or change factors via the \u003Cstrong>“Factors” button\u003C/strong> in the nav bar (reopens ColumnMapping, up to 6)\u003C/li>\n\u003Cli>Check ANOVA: is the factor significant? (p-value, eta-squared)\u003C/li>\n\u003Cli>Drill down: click Boxplot bars or Pareto categories to filter\u003C/li>\n\u003Cli>Follow the breadcrumb trail — each chip shows variation contribution (eta-squared %)\u003C/li>\n\u003Cli>Use the \u003Cstrong>Investigation Mindmap\u003C/strong> to visualize the drill-down tree\u003C/li>\n\u003Cli>Identify the root cause factor/level combination\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance-mode-multi-channel-analysis\">Performance Mode (Multi-Channel Analysis)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance-mode-multi-channel-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Mode (Multi-Channel Analysis)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For processes with many measurement points (filling heads, cavities, test stations):\u003C/p>\n\u003Col>\n\u003Cli>Upload data with multiple numeric columns (channels)\u003C/li>\n\u003Cli>App detects wide format and suggests Performance Mode\u003C/li>\n\u003Cli>\u003Cstrong>Performance I-Chart\u003C/strong> — Cpk scatter plot by channel\u003C/li>\n\u003Cli>\u003Cstrong>Performance Pareto\u003C/strong> — channels ranked worst-first (up to 20)\u003C/li>\n\u003Cli>\u003Cstrong>Performance Boxplot\u003C/strong> — distribution comparison (top 5)\u003C/li>\n\u003Cli>Click a channel to drill into its individual analysis\u003C/li>\n\u003Cli>\u003Cstrong>Performance Capability\u003C/strong> — histogram for the selected channel\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"export-and-sharing\">Export and Sharing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#export-and-sharing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Export and Sharing”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>How\u003C/th>\u003Cth>Output\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>CSV export\u003C/td>\u003Ctd>Editor header button\u003C/td>\u003Ctd>Filtered data as CSV\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Copy chart\u003C/td>\u003Ctd>Chart card menu → “Copy to clipboard”\u003C/td>\u003Ctd>PNG image on clipboard\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Edit chart title\u003C/td>\u003Ctd>Click chart title → type custom text\u003C/td>\u003Ctd>Appears in copied image\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Download chart\u003C/td>\u003Ctd>Chart card menu → “Download”\u003C/td>\u003Ctd>PNG file\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Share analysis\u003C/td>\u003Ctd>Share the \u003Ccode dir=\"auto\">.vrs\u003C/code> file from OneDrive \u003Cem>(Team plan)\u003C/em>\u003C/td>\u003Ctd>Colleague opens in their app\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"settings\">Settings\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#settings\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Settings”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Accessible from the settings panel:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Setting\u003C/th>\u003Cth>Options\u003C/th>\u003Cth>Effect\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Theme\u003C/td>\u003Ctd>Light / Dark / System\u003C/td>\u003Ctd>Switches all UI colors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Company accent\u003C/td>\u003Ctd>Color picker\u003C/td>\u003Ctd>Brand color on headers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Chart font scale\u003C/td>\u003Ctd>Slider\u003C/td>\u003Ctd>Adjusts chart text size\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-capabilities-established-user\">Platform Capabilities (Established User)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-capabilities-established-user\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Capabilities (Established User)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Saved analyses\u003C/td>\u003Ctd>Listed on open; synced via OneDrive on Team plan (Standard: local-only)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Factor management\u003C/td>\u003Ctd>Add/remove/change up to 6 factors during analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Row capacity\u003C/td>\u003Ctd>100,000 rows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>Multi-channel Cpk analysis (hundreds of channels)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Offline work\u003C/td>\u003Ctd>Full functionality, queues sync for reconnection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Chart branding\u003C/td>\u003Ctd>No VariScout branding (enterprise tier)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability analysis\u003C/td>\u003Ctd>Histogram + probability plot with Cp/Cpk\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Sessions per week (active user)\u003C/td>\u003Ctd>> 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Time to first chart (returning)\u003C/td>\u003Ctd>< 30s\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Drill-down depth (avg)\u003C/td>\u003Ctd>> 2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Mode adoption\u003C/td>\u003Ctd>> 20%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Chart export per session\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analyses saved (per user per month)\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"azure-first-analysis.md\">First Analysis\u003C/a> — onboarding journey\u003C/li>\n\u003Cli>\u003Ca href=\"azure-team-collaboration.md\">Team Collaboration\u003C/a> — sharing and admin setup\u003C/li>\n\u003Cli>\u003Ca href=\"../../03-features/analysis/performance-mode.md\">Performance Mode\u003C/a> — multi-channel analysis\u003C/li>\n\u003Cli>\u003Ca href=\"../../03-features/workflows/drill-down-workflow.md\">Drill-Down Workflow\u003C/a> — investigation methodology\u003C/li>\n\u003Cli>\u003Ca href=\"../../03-features/workflows/four-lenses-workflow.md\">Four Lenses Workflow\u003C/a> — analysis framework\u003C/li>\n\u003C/ul>", + { + "headings": 4065, + "localImagePaths": 4106, + "remoteImagePaths": 4107, + "frontmatter": 4108, + "imagePaths": 4109 + }, + [4066, 4068, 4071, 4074, 4077, 4080, 4083, 4086, 4089, 4092, 4095, 4098, 4101, 4104, 4105], + { "depth": 30, "slug": 4067, "text": 4055 }, + "flow-7-azure-app--daily-use", + { "depth": 33, "slug": 4069, "text": 4070 }, + "persona-green-belt-gary-established-user", + "Persona: Green Belt Gary (Established User)", + { "depth": 79, "slug": 4072, "text": 4073 }, + "what-gary-is-thinking", + "What Gary is thinking:", + { "depth": 33, "slug": 4075, "text": 4076 }, + "journey-flow", + "Journey Flow", + { "depth": 79, "slug": 4078, "text": 4079 }, + "mermaid-flowchart", + "Mermaid Flowchart", + { "depth": 79, "slug": 4081, "text": 4082 }, + "daily-use-journey", + "Daily Use Journey", + { "depth": 33, "slug": 4084, "text": 4085 }, + "daily-workflows", + "Daily Workflows", + { "depth": 79, "slug": 4087, "text": 4088 }, + "quick-check-23-minutes", + "Quick Check (2–3 minutes)", + { "depth": 79, "slug": 4090, "text": 4091 }, + "deep-dive-515-minutes", + "Deep Dive (5–15 minutes)", + { "depth": 79, "slug": 4093, "text": 4094 }, + "performance-mode-multi-channel-analysis", + "Performance Mode (Multi-Channel Analysis)", + { "depth": 33, "slug": 4096, "text": 4097 }, + "export-and-sharing", + "Export and Sharing", + { "depth": 33, "slug": 4099, "text": 4100 }, + "settings", + "Settings", + { "depth": 33, "slug": 4102, "text": 4103 }, + "platform-capabilities-established-user", + "Platform Capabilities (Established User)", + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 4055 }, + [], + "02-journeys/flows/azure-first-analysis", + { "id": 4110, "data": 4112, "body": 4117, "filePath": 4118, "digest": 4119, "rendered": 4120 }, + { + "title": 4113, + "editUrl": 16, + "head": 4114, + "template": 18, + "sidebar": 4115, + "pagefind": 16, + "draft": 20 + }, + "Flow 6: Azure App — First Analysis", + [], + { "hidden": 20, "attrs": 4116 }, + {}, + "# Flow 6: Azure App — First Analysis\n\n> Green Belt Gary runs his first analysis in the Azure App\n>\n> **Priority:** High - activation (first value moment)\n>\n> See also: [Journeys Overview](../index.md) | [Enterprise Evaluation](enterprise.md) | [How It Works](../../08-products/azure/how-it-works.md)\n\n---\n\n## Persona: Green Belt Gary\n\n| Attribute | Detail |\n| ----------------- | ---------------------------------------------------------- |\n| **Role** | Quality Engineer, Green Belt certified |\n| **Goal** | Analyze production data without Excel friction |\n| **Knowledge** | Knows SPC concepts, comfortable with data |\n| **Pain points** | Excel templates break, no drill-down, manual chart updates |\n| **Entry point** | Azure App URL (deployed by admin or self) |\n| **Decision mode** | Hands-on — needs to see value in first 5 minutes |\n\n### What Gary is thinking:\n\n- \"IT deployed this — let me see if it actually works\"\n- \"Can I just paste my data and get charts?\"\n- \"Does it understand my column structure?\"\n- \"Where does my analysis get saved?\"\n\n---\n\n## Entry Points\n\n| Source | Arrives Via | Lands On |\n| ------------------- | ------------------------------------ | ---------------- |\n| IT deployment email | App Service URL | EasyAuth sign-in |\n| Colleague link | Direct URL | EasyAuth sign-in |\n| Teams tab | Teams sideloaded app | App (SSO) |\n| Bookmark | Browser bookmark after first session | App (SSO) |\n\n---\n\n## Journey Flow\n\n### Mermaid Flowchart\n\n```mermaid\nflowchart TD\n A[Open App Service URL] --> B[EasyAuth redirects to Azure AD]\n B --> C[Sign in with work account]\n C --> D{First-time consent?}\n D -->|Yes| E[Consent to User.Read\u003Cbr/>+ Files.ReadWrite on Team plan]\n D -->|No| F[Session cookie set]\n E --> F\n F --> G[Empty state: Choose data source]\n G --> H{Data source}\n H -->|Sample| I[Load sample dataset]\n H -->|Paste| J[Paste from spreadsheet]\n H -->|Upload| K[Upload CSV or Excel file]\n H -->|Manual| K2[Enter data manually]\n I --> L[Dashboard renders immediately]\n J --> M[Column mapping auto-detected]\n K --> M\n K2 --> M\n M --> N[Select outcome + factors]\n N --> L\n L --> O[Explore: I-Chart, Boxplot, Stats, ANOVA]\n O --> P[First drill-down: click a filter]\n P --> Q[Charts recalculate, breadcrumbs appear]\n Q --> R[Click Save — persists to IndexedDB]\n R --> R2{Team plan?}\n R2 -->|Yes| S[Syncs to OneDrive — loads from cloud next day]\n R2 -->|No| S2[Standard plan: loads from local storage next day]\n```\n\n### First Analysis Journey\n\n```mermaid\njourney\n title First Analysis in Azure App\n section Login\n Open app URL: 4: User\n Azure AD sign-in: 4: User\n Consent to permissions: 3: User\n section Data\n See empty state: 4: User\n Choose sample or paste data: 5: User\n Column mapping auto-detected: 5: User\n section Analysis\n Dashboard renders: 5: User\n Read I-Chart and stats: 5: User\n First drill-down: 5: User\n section Save\n Click Save to persist: 5: User\n Return next day: 5: User\n```\n\n---\n\n## Step-by-Step\n\n### 1. First Login\n\nThe user opens the App Service URL (e.g., `https://variscout-contoso.azurewebsites.net`). EasyAuth intercepts the unauthenticated request and redirects to Azure AD sign-in.\n\n- User signs in with their work Microsoft account\n- First-time users consent to `User.Read` (display name); Team plan users also consent to `Files.ReadWrite` (OneDrive sync)\n- A platform-managed session cookie is set — no MSAL library, no token in browser storage\n- The app reads user info from `/.auth/me`\n\nSee [Authentication](../../08-products/azure/authentication.md) for technical details.\n\n### 2. Empty State\n\nAfter login, the app shows an empty editor with four options:\n\n| Option | Description |\n| -------------- | --------------------------------------------------- |\n| Sample dataset | Pre-loaded data (coffee, bottleneck, sachets, etc.) |\n| Paste data | Paste tab- or comma-separated text from clipboard |\n| Upload file | Upload CSV or Excel file (parsed in-browser) |\n| Manual entry | Type values directly into a spreadsheet-style grid |\n\nFor a first-time user, **sample datasets** are the fastest path to seeing value. Each sample includes pre-computed stats and meaningful variation patterns.\n\n### 3. Column Mapping\n\nIf pasting or uploading, the app:\n\n1. Parses the text/file with `parseText()` / `parseFile()` (in-browser, no server)\n2. Auto-detects column types via `detectColumns()` — numeric, categorical, date\n3. Presents the **ColumnMapping** screen: select one outcome (numeric) and up to 6 factors (categorical)\n4. Click \"Analyze\" to proceed\n\n### 4. Dashboard\n\nThe dashboard renders four views simultaneously:\n\n- **I-Chart** — individual values over time with control limits\n- **Boxplot** — distribution by factor levels (if factors selected)\n- **Stats panel** — mean, sigma, Cp, Cpk, sample count\n- **ANOVA** — F-statistic, p-value, eta-squared (if factors present)\n\nAll computation happens in-browser via `@variscout/core` stats engine.\n\n### 5. First Drill-Down\n\nGary clicks a bar in the Boxplot (e.g., \"Machine A\"). The dashboard:\n\n- Applies a filter (breadcrumb appears: `Machine A`)\n- Recalculates all charts for the filtered subset\n- Shows the variation contribution (eta-squared %) in the filter chip\n- Enables deeper drilling into sub-factors\n\nThis is the \"aha moment\" — seeing how variation hides inside aggregated data.\n\n### 6. Save and Return\n\nGary clicks **Save** in the editor header to persist his work:\n\n1. **IndexedDB** — immediate local save (offline-first, all plans)\n2. **OneDrive** _(Team plan only)_ — syncs to `OneDrive/VariScout/Projects/` as a `.vrs` file (when online)\n\nOn **Standard plan**, saves are local-only (IndexedDB). The analysis persists on the same device/browser but does not sync to the cloud.\n\nOn **Team plan**, the header shows sync status feedback (saved, syncing, offline). Next day, Gary opens the app and his analysis loads from OneDrive. No setup needed — EasyAuth session persists.\n\nSave is explicit on both plans — unsaved work is lost if the tab closes.\n\nSee [OneDrive Sync](../../08-products/azure/onedrive-sync.md) for Team plan sync details.\n\n---\n\n## Platform-Specific Notes\n\n| Aspect | Azure App behavior |\n| ---------------- | ------------------------------------------------------ |\n| Authentication | EasyAuth (platform-level, no library code) |\n| Data input | Upload, paste, or manual entry — all parsed in-browser |\n| Factor limit | Up to 6 factors, can add/change during analysis |\n| Row limit | 100,000 rows |\n| Persistence | IndexedDB (all plans) + OneDrive sync (Team plan only) |\n| Offline | Full functionality, queues changes for sync |\n| Performance Mode | Available (multi-channel Cpk analysis) |\n| Branding | No VariScout branding on charts (enterprise tier) |\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ----------------------------------- | ------- |\n| Login → first chart rendered | \u003C 3 min |\n| First drill-down in first session | > 60% |\n| Return within 7 days | > 50% |\n| Analysis saved to OneDrive (Team) | > 80% |\n| Sample dataset chosen (first visit) | Track |\n\n---\n\n## How Users Get Here\n\nThe Azure App first-analysis experience follows different acquisition flows:\n\n| Prior Journey | Transition | What the user already knows |\n| -------------------------------------- | ---------------------------------------------- | --------------------------------------------------- |\n| [Enterprise Evaluation](enterprise.md) | IT deploys via Marketplace → Gary gets app URL | Knows the product value prop, expects SSO |\n| [PWA (free tool)](return-visitor.md) | Outgrows PWA limits → team purchases Azure App | Knows drill-down, expects persistence + file upload |\n| Direct referral | Colleague shares app URL | May know nothing — empty state must onboard |\n\n### Coming from the PWA\n\nUsers who graduated from the free PWA will notice key differences:\n\n- **File upload** — CSV and Excel upload, not just paste and manual entry\n- **Save and sync** — analyses persist locally; Team plan adds OneDrive sync (PWA is session-only)\n- **Performance Mode** — multi-channel Cpk analysis (not available in PWA)\n- **6 factors** — up to 6 factors, manageable during analysis (PWA: 3, set at start only)\n- **No branding** — charts have no VariScout watermark\n\nThe analysis workflow (drill-down, ANOVA, mindmap) is identical — skills transfer directly.\n\n---\n\n## See Also\n\n- [Azure App Overview](../../08-products/azure/index.md)\n- [How It Works](../../08-products/azure/how-it-works.md) — end-to-end architecture\n- [Authentication](../../08-products/azure/authentication.md) — EasyAuth details\n- [OneDrive Sync](../../08-products/azure/onedrive-sync.md) — persistence flow\n- [Enterprise Evaluation](enterprise.md) — how Olivia evaluated before Gary got access\n- [Azure Daily Use](azure-daily-use.md) — Gary's workflow after first analysis\n- [Return Visitor](return-visitor.md) — PWA return experience and upgrade triggers", + "src/content/docs/02-journeys/flows/azure-first-analysis.md", + "e043213814d23301", + { "html": 4121, "metadata": 4122 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"flow-6-azure-app--first-analysis\">Flow 6: Azure App — First Analysis\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#flow-6-azure-app--first-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 6: Azure App — First Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Green Belt Gary runs his first analysis in the Azure App\u003C/p>\n\u003Cp>\u003Cstrong>Priority:\u003C/strong> High - activation (first value moment)\u003C/p>\n\u003Cp>See also: \u003Ca href=\"../index.md\">Journeys Overview\u003C/a> | \u003Ca href=\"enterprise.md\">Enterprise Evaluation\u003C/a> | \u003Ca href=\"../../08-products/azure/how-it-works.md\">How It Works\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-green-belt-gary\">Persona: Green Belt Gary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-green-belt-gary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona: Green Belt Gary”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Quality Engineer, Green Belt certified\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Analyze production data without Excel friction\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Knows SPC concepts, comfortable with data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Excel templates break, no drill-down, manual chart updates\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Entry point\u003C/strong>\u003C/td>\u003Ctd>Azure App URL (deployed by admin or self)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Hands-on — needs to see value in first 5 minutes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-gary-is-thinking\">What Gary is thinking:\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-gary-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Gary is thinking:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“IT deployed this — let me see if it actually works”\u003C/li>\n\u003Cli>“Can I just paste my data and get charts?”\u003C/li>\n\u003Cli>“Does it understand my column structure?”\u003C/li>\n\u003Cli>“Where does my analysis get saved?”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Source\u003C/th>\u003Cth>Arrives Via\u003C/th>\u003Cth>Lands On\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>IT deployment email\u003C/td>\u003Ctd>App Service URL\u003C/td>\u003Ctd>EasyAuth sign-in\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Colleague link\u003C/td>\u003Ctd>Direct URL\u003C/td>\u003Ctd>EasyAuth sign-in\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Teams tab\u003C/td>\u003Ctd>Teams sideloaded app\u003C/td>\u003Ctd>App (SSO)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Bookmark\u003C/td>\u003Ctd>Browser bookmark after first session\u003C/td>\u003Ctd>App (SSO)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mermaid-flowchart\">Mermaid Flowchart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mermaid-flowchart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mermaid Flowchart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Open App Service URL] --> B[EasyAuth redirects to Azure AD]\n B --> C[Sign in with work account]\n C --> D{First-time consent?}\n D -->|Yes| E[Consent to User.Read<br/>+ Files.ReadWrite on Team plan]\n D -->|No| F[Session cookie set]\n E --> F\n F --> G[Empty state: Choose data source]\n G --> H{Data source}\n H -->|Sample| I[Load sample dataset]\n H -->|Paste| J[Paste from spreadsheet]\n H -->|Upload| K[Upload CSV or Excel file]\n H -->|Manual| K2[Enter data manually]\n I --> L[Dashboard renders immediately]\n J --> M[Column mapping auto-detected]\n K --> M\n K2 --> M\n M --> N[Select outcome + factors]\n N --> L\n L --> O[Explore: I-Chart, Boxplot, Stats, ANOVA]\n O --> P[First drill-down: click a filter]\n P --> Q[Charts recalculate, breadcrumbs appear]\n Q --> R[Click Save — persists to IndexedDB]\n R --> R2{Team plan?}\n R2 -->|Yes| S[Syncs to OneDrive — loads from cloud next day]\n R2 -->|No| S2[Standard plan: loads from local storage next day]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"first-analysis-journey\">First Analysis Journey\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#first-analysis-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “First Analysis Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title First Analysis in Azure App\n section Login\n Open app URL: 4: User\n Azure AD sign-in: 4: User\n Consent to permissions: 3: User\n section Data\n See empty state: 4: User\n Choose sample or paste data: 5: User\n Column mapping auto-detected: 5: User\n section Analysis\n Dashboard renders: 5: User\n Read I-Chart and stats: 5: User\n First drill-down: 5: User\n section Save\n Click Save to persist: 5: User\n Return next day: 5: User\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-by-step\">Step-by-Step\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-by-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step-by-Step”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-first-login\">1. First Login\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-first-login\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. First Login”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The user opens the App Service URL (e.g., \u003Ccode dir=\"auto\">https://variscout-contoso.azurewebsites.net\u003C/code>). EasyAuth intercepts the unauthenticated request and redirects to Azure AD sign-in.\u003C/p>\n\u003Cul>\n\u003Cli>User signs in with their work Microsoft account\u003C/li>\n\u003Cli>First-time users consent to \u003Ccode dir=\"auto\">User.Read\u003C/code> (display name); Team plan users also consent to \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> (OneDrive sync)\u003C/li>\n\u003Cli>A platform-managed session cookie is set — no MSAL library, no token in browser storage\u003C/li>\n\u003Cli>The app reads user info from \u003Ccode dir=\"auto\">/.auth/me\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>See \u003Ca href=\"../../08-products/azure/authentication.md\">Authentication\u003C/a> for technical details.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-empty-state\">2. Empty State\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-empty-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Empty State”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After login, the app shows an empty editor with four options:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Option\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Sample dataset\u003C/td>\u003Ctd>Pre-loaded data (coffee, bottleneck, sachets, etc.)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Paste data\u003C/td>\u003Ctd>Paste tab- or comma-separated text from clipboard\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Upload file\u003C/td>\u003Ctd>Upload CSV or Excel file (parsed in-browser)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Manual entry\u003C/td>\u003Ctd>Type values directly into a spreadsheet-style grid\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>For a first-time user, \u003Cstrong>sample datasets\u003C/strong> are the fastest path to seeing value. Each sample includes pre-computed stats and meaningful variation patterns.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-column-mapping\">3. Column Mapping\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-column-mapping\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Column Mapping”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>If pasting or uploading, the app:\u003C/p>\n\u003Col>\n\u003Cli>Parses the text/file with \u003Ccode dir=\"auto\">parseText()\u003C/code> / \u003Ccode dir=\"auto\">parseFile()\u003C/code> (in-browser, no server)\u003C/li>\n\u003Cli>Auto-detects column types via \u003Ccode dir=\"auto\">detectColumns()\u003C/code> — numeric, categorical, date\u003C/li>\n\u003Cli>Presents the \u003Cstrong>ColumnMapping\u003C/strong> screen: select one outcome (numeric) and up to 6 factors (categorical)\u003C/li>\n\u003Cli>Click “Analyze” to proceed\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-dashboard\">4. Dashboard\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-dashboard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Dashboard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The dashboard renders four views simultaneously:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — individual values over time with control limits\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong> — distribution by factor levels (if factors selected)\u003C/li>\n\u003Cli>\u003Cstrong>Stats panel\u003C/strong> — mean, sigma, Cp, Cpk, sample count\u003C/li>\n\u003Cli>\u003Cstrong>ANOVA\u003C/strong> — F-statistic, p-value, eta-squared (if factors present)\u003C/li>\n\u003C/ul>\n\u003Cp>All computation happens in-browser via \u003Ccode dir=\"auto\">@variscout/core\u003C/code> stats engine.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"5-first-drill-down\">5. First Drill-Down\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#5-first-drill-down\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. First Drill-Down”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Gary clicks a bar in the Boxplot (e.g., “Machine A”). The dashboard:\u003C/p>\n\u003Cul>\n\u003Cli>Applies a filter (breadcrumb appears: \u003Ccode dir=\"auto\">Machine A\u003C/code>)\u003C/li>\n\u003Cli>Recalculates all charts for the filtered subset\u003C/li>\n\u003Cli>Shows the variation contribution (eta-squared %) in the filter chip\u003C/li>\n\u003Cli>Enables deeper drilling into sub-factors\u003C/li>\n\u003C/ul>\n\u003Cp>This is the “aha moment” — seeing how variation hides inside aggregated data.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"6-save-and-return\">6. Save and Return\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#6-save-and-return\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Save and Return”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Gary clicks \u003Cstrong>Save\u003C/strong> in the editor header to persist his work:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>IndexedDB\u003C/strong> — immediate local save (offline-first, all plans)\u003C/li>\n\u003Cli>\u003Cstrong>OneDrive\u003C/strong> \u003Cem>(Team plan only)\u003C/em> — syncs to \u003Ccode dir=\"auto\">OneDrive/VariScout/Projects/\u003C/code> as a \u003Ccode dir=\"auto\">.vrs\u003C/code> file (when online)\u003C/li>\n\u003C/ol>\n\u003Cp>On \u003Cstrong>Standard plan\u003C/strong>, saves are local-only (IndexedDB). The analysis persists on the same device/browser but does not sync to the cloud.\u003C/p>\n\u003Cp>On \u003Cstrong>Team plan\u003C/strong>, the header shows sync status feedback (saved, syncing, offline). Next day, Gary opens the app and his analysis loads from OneDrive. No setup needed — EasyAuth session persists.\u003C/p>\n\u003Cp>Save is explicit on both plans — unsaved work is lost if the tab closes.\u003C/p>\n\u003Cp>See \u003Ca href=\"../../08-products/azure/onedrive-sync.md\">OneDrive Sync\u003C/a> for Team plan sync details.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-specific-notes\">Platform-Specific Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-specific-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform-Specific Notes”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Azure App behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Authentication\u003C/td>\u003Ctd>EasyAuth (platform-level, no library code)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data input\u003C/td>\u003Ctd>Upload, paste, or manual entry — all parsed in-browser\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Factor limit\u003C/td>\u003Ctd>Up to 6 factors, can add/change during analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Row limit\u003C/td>\u003Ctd>100,000 rows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Persistence\u003C/td>\u003Ctd>IndexedDB (all plans) + OneDrive sync (Team plan only)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Offline\u003C/td>\u003Ctd>Full functionality, queues changes for sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>Available (multi-channel Cpk analysis)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Branding\u003C/td>\u003Ctd>No VariScout branding on charts (enterprise tier)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Login → first chart rendered\u003C/td>\u003Ctd>< 3 min\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>First drill-down in first session\u003C/td>\u003Ctd>> 60%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Return within 7 days\u003C/td>\u003Ctd>> 50%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analysis saved to OneDrive (Team)\u003C/td>\u003Ctd>> 80%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sample dataset chosen (first visit)\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-users-get-here\">How Users Get Here\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-users-get-here\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How Users Get Here”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure App first-analysis experience follows different acquisition flows:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Prior Journey\u003C/th>\u003Cth>Transition\u003C/th>\u003Cth>What the user already knows\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"enterprise.md\">Enterprise Evaluation\u003C/a>\u003C/td>\u003Ctd>IT deploys via Marketplace → Gary gets app URL\u003C/td>\u003Ctd>Knows the product value prop, expects SSO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"return-visitor.md\">PWA (free tool)\u003C/a>\u003C/td>\u003Ctd>Outgrows PWA limits → team purchases Azure App\u003C/td>\u003Ctd>Knows drill-down, expects persistence + file upload\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Direct referral\u003C/td>\u003Ctd>Colleague shares app URL\u003C/td>\u003Ctd>May know nothing — empty state must onboard\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"coming-from-the-pwa\">Coming from the PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#coming-from-the-pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Coming from the PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Users who graduated from the free PWA will notice key differences:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>File upload\u003C/strong> — CSV and Excel upload, not just paste and manual entry\u003C/li>\n\u003Cli>\u003Cstrong>Save and sync\u003C/strong> — analyses persist locally; Team plan adds OneDrive sync (PWA is session-only)\u003C/li>\n\u003Cli>\u003Cstrong>Performance Mode\u003C/strong> — multi-channel Cpk analysis (not available in PWA)\u003C/li>\n\u003Cli>\u003Cstrong>6 factors\u003C/strong> — up to 6 factors, manageable during analysis (PWA: 3, set at start only)\u003C/li>\n\u003Cli>\u003Cstrong>No branding\u003C/strong> — charts have no VariScout watermark\u003C/li>\n\u003C/ul>\n\u003Cp>The analysis workflow (drill-down, ANOVA, mindmap) is identical — skills transfer directly.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../08-products/azure/index.md\">Azure App Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/how-it-works.md\">How It Works\u003C/a> — end-to-end architecture\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/authentication.md\">Authentication\u003C/a> — EasyAuth details\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/onedrive-sync.md\">OneDrive Sync\u003C/a> — persistence flow\u003C/li>\n\u003Cli>\u003Ca href=\"enterprise.md\">Enterprise Evaluation\u003C/a> — how Olivia evaluated before Gary got access\u003C/li>\n\u003Cli>\u003Ca href=\"azure-daily-use.md\">Azure Daily Use\u003C/a> — Gary’s workflow after first analysis\u003C/li>\n\u003Cli>\u003Ca href=\"return-visitor.md\">Return Visitor\u003C/a> — PWA return experience and upgrade triggers\u003C/li>\n\u003C/ul>", + { + "headings": 4123, + "localImagePaths": 4168, + "remoteImagePaths": 4169, + "frontmatter": 4170, + "imagePaths": 4171 + }, + [ + 4124, 4126, 4129, 4130, 4131, 4132, 4133, 4136, 4139, 4142, 4145, 4148, 4151, 4154, 4157, 4160, + 4161, 4164, 4167 + ], + { "depth": 30, "slug": 4125, "text": 4113 }, + "flow-6-azure-app--first-analysis", + { "depth": 33, "slug": 4127, "text": 4128 }, + "persona-green-belt-gary", + "Persona: Green Belt Gary", + { "depth": 79, "slug": 4072, "text": 4073 }, + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 79, "slug": 4078, "text": 4079 }, + { "depth": 79, "slug": 4134, "text": 4135 }, + "first-analysis-journey", + "First Analysis Journey", + { "depth": 33, "slug": 4137, "text": 4138 }, + "step-by-step", + "Step-by-Step", + { "depth": 79, "slug": 4140, "text": 4141 }, + "1-first-login", + "1. First Login", + { "depth": 79, "slug": 4143, "text": 4144 }, + "2-empty-state", + "2. Empty State", + { "depth": 79, "slug": 4146, "text": 4147 }, + "3-column-mapping", + "3. Column Mapping", + { "depth": 79, "slug": 4149, "text": 4150 }, + "4-dashboard", + "4. Dashboard", + { "depth": 79, "slug": 4152, "text": 4153 }, + "5-first-drill-down", + "5. First Drill-Down", + { "depth": 79, "slug": 4155, "text": 4156 }, + "6-save-and-return", + "6. Save and Return", + { "depth": 33, "slug": 4158, "text": 4159 }, + "platform-specific-notes", + "Platform-Specific Notes", + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4162, "text": 4163 }, + "how-users-get-here", + "How Users Get Here", + { "depth": 79, "slug": 4165, "text": 4166 }, + "coming-from-the-pwa", + "Coming from the PWA", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 4113 }, + [], + "02-journeys/flows/azure-team-collaboration", + { "id": 4172, "data": 4174, "body": 4179, "filePath": 4180, "digest": 4181, "rendered": 4182 }, + { + "title": 4175, + "editUrl": 16, + "head": 4176, + "template": 18, + "sidebar": 4177, + "pagefind": 16, + "draft": 20 + }, + "Flow 8: Azure App — Team Collaboration", + [], + { "hidden": 20, "attrs": 4178 }, + {}, + "# Flow 8: Azure App — Team Collaboration\n\n> OpEx Olivia deploys VariScout for her team and sets up sharing\n>\n> **Priority:** Medium - expansion (team adoption after initial deployment)\n>\n> See also: [Journeys Overview](../index.md) | [Enterprise Evaluation](enterprise.md) | [First Analysis](azure-first-analysis.md)\n\n---\n\n## Persona: OpEx Olivia (Admin)\n\n| Attribute | Detail |\n| ----------------- | ------------------------------------------------------- |\n| **Role** | OpEx Manager, VariScout deployment owner |\n| **Goal** | Get the team using VariScout, enable collaboration |\n| **Knowledge** | Strategic, manages deployment and team access |\n| **Pain points** | Onboarding friction, IT coordination, Teams integration |\n| **Entry point** | Azure Marketplace or ARM template deployment |\n| **Decision mode** | Admin — configures once, team uses daily |\n\n### What Olivia is thinking:\n\n- \"How do I get this deployed for my team?\"\n- \"Can everyone use their existing Microsoft login?\"\n- \"How do team members share analyses?\"\n- \"Can we put this in Teams so people actually use it?\"\n\n---\n\n## Journey Flow\n\n### Mermaid Flowchart\n\n```mermaid\nflowchart TD\n A[Decision to deploy] --> B[Create App Registration in Azure AD]\n B --> C[Deploy via Azure Marketplace]\n C --> D[ARM template creates App Service + EasyAuth]\n D --> E[App live at custom URL]\n E --> F[Share URL with team]\n F --> G[Team members sign in via SSO]\n G --> H[Each user gets local storage or cloud sync]\n H --> I{Collaboration}\n I -->|Standard| J[Share via file export or chart copy]\n I -->|Team plan| J2[Channel tabs + deep links + OneDrive]\n I -->|Teams tab| K[Admin generates Teams manifest]\n K --> L[Sideload manifest to Teams]\n L --> M[VariScout appears as Teams tab]\n I -->|Settings| N[Company accent, theme defaults]\n```\n\n### Team Adoption Journey\n\n```mermaid\njourney\n title Team Collaboration Setup\n section Deploy\n Create App Registration: 3: Admin\n Deploy from Marketplace: 4: Admin\n Verify app loads: 5: Admin\n section Onboard\n Share URL with team: 5: Admin\n First team member logs in: 5: User\n Consent to permissions: 3: User\n section Collaborate\n Standard: local file storage: 5: User\n Team: cloud sync + channel sharing: 4: User\n Set up Teams tab: 4: Admin\n section Establish\n Team uses daily: 5: User\n Admin reviews adoption: 4: Admin\n```\n\n---\n\n## Step-by-Step\n\n### 1. Deployment (Admin — One-Time)\n\nThe admin (Olivia or IT) deploys VariScout to the organization's Azure tenant.\n\n**Pre-requisite**: Create an App Registration in Azure AD:\n\n| Step | Action |\n| ---- | ------------------------------------------------------------------------------------------------------------ |\n| 1 | Go to Azure AD → App Registrations → New |\n| 2 | Name: \"VariScout\" (or any name) |\n| 3 | Add redirect URI (configured during deployment) |\n| 4 | API permissions: `User.Read` (Standard plan). Team plan adds `Files.ReadWrite.All` + `Channel.ReadBasic.All` |\n| 5 | Create a client secret |\n| 6 | Note the Client ID and Client Secret |\n\n**Deploy from Azure Marketplace:**\n\n1. Find VariScout on Azure Marketplace\n2. Click \"Create\"\n3. Enter: app name, region, Client ID, Client Secret\n4. Deploy — ARM template creates App Service Plan + App Service + EasyAuth config\n5. App is live at `https://\u003Capp-name>.azurewebsites.net` (~2 minutes)\n\nSee [ARM Template](../../08-products/azure/arm-template.md) and [Marketplace Guide](../../08-products/azure/marketplace.md) for details.\n\n### 2. Team Onboarding (Zero Friction)\n\nThere is no user provisioning. Anyone in the Azure AD tenant can access the app:\n\n1. Admin shares the App Service URL (email, Teams message, intranet)\n2. Team member opens the URL\n3. EasyAuth redirects to Azure AD sign-in (existing work account)\n4. First-time consent: `User.Read` (Standard). Team plan: admin pre-consents cloud permissions\n5. App loads — ready to use\n\n**No separate accounts, no invitations, no license assignment.** The Managed Application covers unlimited users in the tenant.\n\n### 3. Data Storage\n\nStorage depends on the plan:\n\n**Standard plan** — local files only:\n\n- Projects saved to IndexedDB + local files via File System Access API\n- No cloud sync, no OneDrive\n- Offline-first: full functionality without internet\n\n**Team plan** — local files + cloud sync:\n\n```\nUser's OneDrive/\n└── VariScout/\n └── Projects/\n ├── analysis-001.vrs\n └── ...\n\nChannel Files/VariScout/ ← channel tab storage (SharePoint)\n├── Projects/\n│ └── shared-analysis.vrs\n└── Photos/\n └── ...\n```\n\n- Personal OneDrive sync for personal tabs and browser access\n- SharePoint channel storage for channel tabs (shared with team)\n- Sync via Graph API with `Files.ReadWrite.All` permission\n- Offline-first: works without internet, syncs when reconnected\n\n### 4. Sharing Analyses\n\n| Sharing method | Plan | How |\n| ------------------------- | ---- | ----------------------------------------------------------- |\n| Channel tab (shared .vrs) | Team | Analyses stored in channel SharePoint — team sees same data |\n| Teams deep links | Team | Share chart/finding URLs via Teams native dialog |\n| Share OneDrive file | Team | Right-click `.vrs` file in OneDrive → Share with colleague |\n| Export and send | Both | CSV export → email/Teams attachment |\n| Copy chart | Both | Copy chart as PNG → paste into email/presentation |\n\n**Standard plan**: Sharing via file export or chart copy. No cloud-based sharing.\n\n**Team plan**: Channel tabs provide built-in team collaboration — all channel members access the same analysis. Deep links allow sharing specific charts or findings via Teams chat.\n\n### 5. Teams Integration\n\nThe admin can add VariScout as a Teams tab:\n\n1. Open the **Admin Settings** panel in the app\n2. Click **Teams Setup** (AdminTeamsSetup component)\n3. The app generates a Teams manifest (`manifest.json`) with the correct App Service URL\n4. Download the `.zip` package (generated client-side with JSZip)\n5. In Teams Admin Center: Upload → Sideload the `.zip`\n6. VariScout appears as a Teams tab option\n\nTeam members can then add VariScout to any Teams channel as a tab — SSO flows through seamlessly.\n\n### 6. Settings and Branding\n\nAdmin or any user can customize via the Settings panel:\n\n| Setting | Purpose |\n| ---------------- | ----------------------------------------- |\n| Theme | Light / Dark / System (per user) |\n| Company accent | Brand color applied to headers (per user) |\n| Chart font scale | Adjust chart text size (per user) |\n\nSettings are stored in browser `localStorage` (per device, not synced).\n\n---\n\n## Data Ownership\n\nAll data stays within the customer's Azure tenant:\n\n```\nCUSTOMER TENANT VARISCOUT (Publisher)\n┌──────────────────────┐ ┌────────────────────┐\n│ │ │ │\n│ App Service │ │ Marketplace │\n│ (hosts the app) │ ── NO ────▶ │ listing only │\n│ │ connection │ │\n│ Azure AD │ │ No access to: │\n│ (authenticates) │ │ - Customer data │\n│ │ │ - User identities │\n│ OneDrive │ │ - App resources │\n│ (stores analyses) │ │ - Usage telemetry │\n│ │ │ │\n└──────────────────────┘ └────────────────────┘\n```\n\n- Publisher management is disabled — zero access to customer deployment\n- No telemetry or outbound calls to publisher systems\n- Data survives subscription cancellation (analyses remain on device or in OneDrive/SharePoint)\n\n---\n\n## Permissions Summary\n\n| Permission | Type | Plan | Who consents | Purpose |\n| ----------------------- | --------- | ---- | ------------ | --------------------------------- |\n| `User.Read` | Delegated | Both | Each user | Display user name & email |\n| `Files.ReadWrite.All` | Delegated | Team | Tenant admin | OneDrive + SharePoint file sync |\n| `Channel.ReadBasic.All` | Delegated | Team | Tenant admin | Resolve channel SharePoint drives |\n\n**Standard plan**: No admin consent required — users consent to `User.Read` on first login.\n\n**Team plan**: Requires one-time tenant admin consent for `Files.ReadWrite.All` and `Channel.ReadBasic.All`. No `Sites.ReadWrite.All`, no mail access.\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ------------------------------------- | ------- |\n| Deployment → first team login | \u003C 1 day |\n| Team members active (month 1) | > 50% |\n| Analyses saved per user (month 1) | > 3 |\n| Teams tab adoption (if set up) | Track |\n| OneDrive sharing between team members | Track |\n| Return rate (week 2) | > 60% |\n\n---\n\n## See Also\n\n- [Azure App Overview](../../08-products/azure/index.md) — product positioning and pricing\n- [How It Works](../../08-products/azure/how-it-works.md) — end-to-end architecture\n- [ARM Template](../../08-products/azure/arm-template.md) — deployment resources\n- [Authentication](../../08-products/azure/authentication.md) — EasyAuth details\n- [OneDrive Sync](../../08-products/azure/onedrive-sync.md) — sync and offline behavior\n- [Enterprise Evaluation](enterprise.md) — how Olivia evaluated before deploying\n- [First Analysis](azure-first-analysis.md) — what team members experience on day one\n- [Daily Use](azure-daily-use.md) — ongoing workflow", + "src/content/docs/02-journeys/flows/azure-team-collaboration.md", + "ba99d71bc089cdec", + { "html": 4183, "metadata": 4184 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"flow-8-azure-app--team-collaboration\">Flow 8: Azure App — Team Collaboration\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#flow-8-azure-app--team-collaboration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 8: Azure App — Team Collaboration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>OpEx Olivia deploys VariScout for her team and sets up sharing\u003C/p>\n\u003Cp>\u003Cstrong>Priority:\u003C/strong> Medium - expansion (team adoption after initial deployment)\u003C/p>\n\u003Cp>See also: \u003Ca href=\"../index.md\">Journeys Overview\u003C/a> | \u003Ca href=\"enterprise.md\">Enterprise Evaluation\u003C/a> | \u003Ca href=\"azure-first-analysis.md\">First Analysis\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-opex-olivia-admin\">Persona: OpEx Olivia (Admin)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-opex-olivia-admin\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona: OpEx Olivia (Admin)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>OpEx Manager, VariScout deployment owner\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Get the team using VariScout, enable collaboration\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Strategic, manages deployment and team access\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Onboarding friction, IT coordination, Teams integration\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Entry point\u003C/strong>\u003C/td>\u003Ctd>Azure Marketplace or ARM template deployment\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Admin — configures once, team uses daily\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-olivia-is-thinking\">What Olivia is thinking:\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-olivia-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Olivia is thinking:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“How do I get this deployed for my team?”\u003C/li>\n\u003Cli>“Can everyone use their existing Microsoft login?”\u003C/li>\n\u003Cli>“How do team members share analyses?”\u003C/li>\n\u003Cli>“Can we put this in Teams so people actually use it?”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mermaid-flowchart\">Mermaid Flowchart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mermaid-flowchart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mermaid Flowchart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Decision to deploy] --> B[Create App Registration in Azure AD]\n B --> C[Deploy via Azure Marketplace]\n C --> D[ARM template creates App Service + EasyAuth]\n D --> E[App live at custom URL]\n E --> F[Share URL with team]\n F --> G[Team members sign in via SSO]\n G --> H[Each user gets local storage or cloud sync]\n H --> I{Collaboration}\n I -->|Standard| J[Share via file export or chart copy]\n I -->|Team plan| J2[Channel tabs + deep links + OneDrive]\n I -->|Teams tab| K[Admin generates Teams manifest]\n K --> L[Sideload manifest to Teams]\n L --> M[VariScout appears as Teams tab]\n I -->|Settings| N[Company accent, theme defaults]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"team-adoption-journey\">Team Adoption Journey\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#team-adoption-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Team Adoption Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Team Collaboration Setup\n section Deploy\n Create App Registration: 3: Admin\n Deploy from Marketplace: 4: Admin\n Verify app loads: 5: Admin\n section Onboard\n Share URL with team: 5: Admin\n First team member logs in: 5: User\n Consent to permissions: 3: User\n section Collaborate\n Standard: local file storage: 5: User\n Team: cloud sync + channel sharing: 4: User\n Set up Teams tab: 4: Admin\n section Establish\n Team uses daily: 5: User\n Admin reviews adoption: 4: Admin\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-by-step\">Step-by-Step\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-by-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step-by-Step”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-deployment-admin--one-time\">1. Deployment (Admin — One-Time)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-deployment-admin--one-time\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Deployment (Admin — One-Time)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The admin (Olivia or IT) deploys VariScout to the organization’s Azure tenant.\u003C/p>\n\u003Cp>\u003Cstrong>Pre-requisite\u003C/strong>: Create an App Registration in Azure AD:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Step\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Go to Azure AD → App Registrations → New\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Name: “VariScout” (or any name)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Add redirect URI (configured during deployment)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>API permissions: \u003Ccode dir=\"auto\">User.Read\u003C/code> (Standard plan). Team plan adds \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> + \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Create a client secret\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Note the Client ID and Client Secret\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Deploy from Azure Marketplace:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Find VariScout on Azure Marketplace\u003C/li>\n\u003Cli>Click “Create”\u003C/li>\n\u003Cli>Enter: app name, region, Client ID, Client Secret\u003C/li>\n\u003Cli>Deploy — ARM template creates App Service Plan + App Service + EasyAuth config\u003C/li>\n\u003Cli>App is live at \u003Ccode dir=\"auto\">https://<app-name>.azurewebsites.net\u003C/code> (~2 minutes)\u003C/li>\n\u003C/ol>\n\u003Cp>See \u003Ca href=\"../../08-products/azure/arm-template.md\">ARM Template\u003C/a> and \u003Ca href=\"../../08-products/azure/marketplace.md\">Marketplace Guide\u003C/a> for details.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-team-onboarding-zero-friction\">2. Team Onboarding (Zero Friction)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-team-onboarding-zero-friction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Team Onboarding (Zero Friction)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>There is no user provisioning. Anyone in the Azure AD tenant can access the app:\u003C/p>\n\u003Col>\n\u003Cli>Admin shares the App Service URL (email, Teams message, intranet)\u003C/li>\n\u003Cli>Team member opens the URL\u003C/li>\n\u003Cli>EasyAuth redirects to Azure AD sign-in (existing work account)\u003C/li>\n\u003Cli>First-time consent: \u003Ccode dir=\"auto\">User.Read\u003C/code> (Standard). Team plan: admin pre-consents cloud permissions\u003C/li>\n\u003Cli>App loads — ready to use\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>No separate accounts, no invitations, no license assignment.\u003C/strong> The Managed Application covers unlimited users in the tenant.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-data-storage\">3. Data Storage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-data-storage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Data Storage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Storage depends on the plan:\u003C/p>\n\u003Cp>\u003Cstrong>Standard plan\u003C/strong> — local files only:\u003C/p>\n\u003Cul>\n\u003Cli>Projects saved to IndexedDB + local files via File System Access API\u003C/li>\n\u003Cli>No cloud sync, no OneDrive\u003C/li>\n\u003Cli>Offline-first: full functionality without internet\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Team plan\u003C/strong> — local files + cloud sync:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User's OneDrive/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── VariScout/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Projects/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── analysis-001.vrs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── ...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Channel Files/VariScout/ ← channel tab storage (SharePoint)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Projects/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── shared-analysis.vrs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Photos/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── ...\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"User's OneDrive/└── VariScout/ └── Projects/ ├── analysis-001.vrs └── ...Channel Files/VariScout/ ← channel tab storage (SharePoint)├── Projects/│ └── shared-analysis.vrs└── Photos/ └── ...\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cul>\n\u003Cli>Personal OneDrive sync for personal tabs and browser access\u003C/li>\n\u003Cli>SharePoint channel storage for channel tabs (shared with team)\u003C/li>\n\u003Cli>Sync via Graph API with \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> permission\u003C/li>\n\u003Cli>Offline-first: works without internet, syncs when reconnected\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-sharing-analyses\">4. Sharing Analyses\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-sharing-analyses\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Sharing Analyses”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Sharing method\u003C/th>\u003Cth>Plan\u003C/th>\u003Cth>How\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Channel tab (shared .vrs)\u003C/td>\u003Ctd>Team\u003C/td>\u003Ctd>Analyses stored in channel SharePoint — team sees same data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Teams deep links\u003C/td>\u003Ctd>Team\u003C/td>\u003Ctd>Share chart/finding URLs via Teams native dialog\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Share OneDrive file\u003C/td>\u003Ctd>Team\u003C/td>\u003Ctd>Right-click \u003Ccode dir=\"auto\">.vrs\u003C/code> file in OneDrive → Share with colleague\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Export and send\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>CSV export → email/Teams attachment\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Copy chart\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Copy chart as PNG → paste into email/presentation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Standard plan\u003C/strong>: Sharing via file export or chart copy. No cloud-based sharing.\u003C/p>\n\u003Cp>\u003Cstrong>Team plan\u003C/strong>: Channel tabs provide built-in team collaboration — all channel members access the same analysis. Deep links allow sharing specific charts or findings via Teams chat.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"5-teams-integration\">5. Teams Integration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#5-teams-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Teams Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The admin can add VariScout as a Teams tab:\u003C/p>\n\u003Col>\n\u003Cli>Open the \u003Cstrong>Admin Settings\u003C/strong> panel in the app\u003C/li>\n\u003Cli>Click \u003Cstrong>Teams Setup\u003C/strong> (AdminTeamsSetup component)\u003C/li>\n\u003Cli>The app generates a Teams manifest (\u003Ccode dir=\"auto\">manifest.json\u003C/code>) with the correct App Service URL\u003C/li>\n\u003Cli>Download the \u003Ccode dir=\"auto\">.zip\u003C/code> package (generated client-side with JSZip)\u003C/li>\n\u003Cli>In Teams Admin Center: Upload → Sideload the \u003Ccode dir=\"auto\">.zip\u003C/code>\u003C/li>\n\u003Cli>VariScout appears as a Teams tab option\u003C/li>\n\u003C/ol>\n\u003Cp>Team members can then add VariScout to any Teams channel as a tab — SSO flows through seamlessly.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"6-settings-and-branding\">6. Settings and Branding\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#6-settings-and-branding\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Settings and Branding”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Admin or any user can customize via the Settings panel:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Setting\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Theme\u003C/td>\u003Ctd>Light / Dark / System (per user)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Company accent\u003C/td>\u003Ctd>Brand color applied to headers (per user)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Chart font scale\u003C/td>\u003Ctd>Adjust chart text size (per user)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Settings are stored in browser \u003Ccode dir=\"auto\">localStorage\u003C/code> (per device, not synced).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-ownership\">Data Ownership\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-ownership\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Ownership”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All data stays within the customer’s Azure tenant:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CUSTOMER TENANT VARISCOUT (Publisher)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌──────────────────────┐ ┌────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ App Service │ │ Marketplace │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (hosts the app) │ ── NO ────▶ │ listing only │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ connection │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Azure AD │ │ No access to: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (authenticates) │ │ - Customer data │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ - User identities │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ OneDrive │ │ - App resources │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (stores analyses) │ │ - Usage telemetry │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────────────────────┘ └────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"CUSTOMER TENANT VARISCOUT (Publisher)┌──────────────────────┐ ┌────────────────────┐│ │ │ ││ App Service │ │ Marketplace ││ (hosts the app) │ ── NO ────▶ │ listing only ││ │ connection │ ││ Azure AD │ │ No access to: ││ (authenticates) │ │ - Customer data ││ │ │ - User identities ││ OneDrive │ │ - App resources ││ (stores analyses) │ │ - Usage telemetry ││ │ │ │└──────────────────────┘ └────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cul>\n\u003Cli>Publisher management is disabled — zero access to customer deployment\u003C/li>\n\u003Cli>No telemetry or outbound calls to publisher systems\u003C/li>\n\u003Cli>Data survives subscription cancellation (analyses remain on device or in OneDrive/SharePoint)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"permissions-summary\">Permissions Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#permissions-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Permissions Summary”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Permission\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Plan\u003C/th>\u003Cth>Who consents\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">User.Read\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Each user\u003C/td>\u003Ctd>Display user name & email\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Team\u003C/td>\u003Ctd>Tenant admin\u003C/td>\u003Ctd>OneDrive + SharePoint file sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Team\u003C/td>\u003Ctd>Tenant admin\u003C/td>\u003Ctd>Resolve channel SharePoint drives\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Standard plan\u003C/strong>: No admin consent required — users consent to \u003Ccode dir=\"auto\">User.Read\u003C/code> on first login.\u003C/p>\n\u003Cp>\u003Cstrong>Team plan\u003C/strong>: Requires one-time tenant admin consent for \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> and \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>. No \u003Ccode dir=\"auto\">Sites.ReadWrite.All\u003C/code>, no mail access.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Deployment → first team login\u003C/td>\u003Ctd>< 1 day\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Team members active (month 1)\u003C/td>\u003Ctd>> 50%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analyses saved per user (month 1)\u003C/td>\u003Ctd>> 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Teams tab adoption (if set up)\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OneDrive sharing between team members\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Return rate (week 2)\u003C/td>\u003Ctd>> 60%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../08-products/azure/index.md\">Azure App Overview\u003C/a> — product positioning and pricing\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/how-it-works.md\">How It Works\u003C/a> — end-to-end architecture\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/arm-template.md\">ARM Template\u003C/a> — deployment resources\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/authentication.md\">Authentication\u003C/a> — EasyAuth details\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/onedrive-sync.md\">OneDrive Sync\u003C/a> — sync and offline behavior\u003C/li>\n\u003Cli>\u003Ca href=\"enterprise.md\">Enterprise Evaluation\u003C/a> — how Olivia evaluated before deploying\u003C/li>\n\u003Cli>\u003Ca href=\"azure-first-analysis.md\">First Analysis\u003C/a> — what team members experience on day one\u003C/li>\n\u003Cli>\u003Ca href=\"azure-daily-use.md\">Daily Use\u003C/a> — ongoing workflow\u003C/li>\n\u003C/ul>", + { + "headings": 4185, + "localImagePaths": 4226, + "remoteImagePaths": 4227, + "frontmatter": 4228, + "imagePaths": 4229 + }, + [ + 4186, 4188, 4191, 4194, 4195, 4196, 4199, 4200, 4203, 4206, 4209, 4212, 4215, 4218, 4221, 4224, + 4225 + ], + { "depth": 30, "slug": 4187, "text": 4175 }, + "flow-8-azure-app--team-collaboration", + { "depth": 33, "slug": 4189, "text": 4190 }, + "persona-opex-olivia-admin", + "Persona: OpEx Olivia (Admin)", + { "depth": 79, "slug": 4192, "text": 4193 }, + "what-olivia-is-thinking", + "What Olivia is thinking:", + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 79, "slug": 4078, "text": 4079 }, + { "depth": 79, "slug": 4197, "text": 4198 }, + "team-adoption-journey", + "Team Adoption Journey", + { "depth": 33, "slug": 4137, "text": 4138 }, + { "depth": 79, "slug": 4201, "text": 4202 }, + "1-deployment-admin--one-time", + "1. Deployment (Admin — One-Time)", + { "depth": 79, "slug": 4204, "text": 4205 }, + "2-team-onboarding-zero-friction", + "2. Team Onboarding (Zero Friction)", + { "depth": 79, "slug": 4207, "text": 4208 }, + "3-data-storage", + "3. Data Storage", + { "depth": 79, "slug": 4210, "text": 4211 }, + "4-sharing-analyses", + "4. Sharing Analyses", + { "depth": 79, "slug": 4213, "text": 4214 }, + "5-teams-integration", + "5. Teams Integration", + { "depth": 79, "slug": 4216, "text": 4217 }, + "6-settings-and-branding", + "6. Settings and Branding", + { "depth": 33, "slug": 4219, "text": 4220 }, + "data-ownership", + "Data Ownership", + { "depth": 33, "slug": 4222, "text": 4223 }, + "permissions-summary", + "Permissions Summary", + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 4175 }, + [], + "02-journeys/flows/azure-teams-mobile", + { "id": 4230, "data": 4232, "body": 4237, "filePath": 4238, "digest": 4239, "rendered": 4240 }, + { + "title": 4233, + "editUrl": 16, + "head": 4234, + "template": 18, + "sidebar": 4235, + "pagefind": 16, + "draft": 20 + }, + "Azure Teams Mobile Flow", + [], + { "hidden": 20, "attrs": 4236 }, + {}, + "# Azure Teams Mobile Flow\n\nHow quality engineers use VariScout on their phones via the Teams mobile app.\n\n---\n\n## Persona\n\n[Field Fiona](../personas/field-fiona.md) — Field Quality Engineer who reviews charts during morning meetings and on the shop floor.\n\n---\n\n## Flow Diagram\n\n```mermaid\nflowchart TD\n A[Open Teams Mobile] --> B[Tap VariScout Tab]\n B --> C{Phone or Tablet?}\n C -->|Phone \u003C 640px| D[Carousel View]\n C -->|Tablet 640px+| E[Grid View]\n\n D --> F[Swipe Between Charts]\n F --> G[I-Chart → Boxplot → Pareto → Stats]\n G --> H{Need to Drill?}\n H -->|Yes| I[Tap Category on Boxplot/Pareto]\n I --> J[Filter Applied, Next Factor Auto-Selected]\n H -->|No| K{Need Actions?}\n\n K -->|Yes| L[Tap ⋮ Overflow Menu]\n L --> M[Findings / What-If / Export / Data Table]\n K -->|No| N[Done - Close Teams]\n\n E --> O[Full Desktop Layout]\n O --> P[All Charts Visible, Full Toolbar]\n```\n\n---\n\n## Breakpoints\n\n| Viewport | Layout | Navigation | Toolbar | FindingsPanel |\n| ------------------- | --------------------------------- | ------------------------------- | ------------------- | ------------------- |\n| \u003C 640px (phone) | Carousel: 1 chart at a time | Swipe + pill buttons + chevrons | Save + ⋮ overflow | Full-screen overlay |\n| 640–1024px (tablet) | Grid: charts stacked/side-by-side | Click | Full inline toolbar | Resizable sidebar |\n| > 1024px (desktop) | Grid: optimal layout | Click + keyboard | Full inline toolbar | Resizable sidebar |\n\n---\n\n## Phone Carousel UX\n\n### Navigation\n\n- **Swipe left/right**: Move between 4 views (I-Chart, Boxplot, Pareto, Stats)\n- **Pill buttons**: Direct navigation with icons (labels hidden \u003C 400px)\n- **Chevron arrows**: Previous/next with 44px touch targets\n- **Dot indicators**: Show current position\n\n### What's Shown\n\n- Current chart (full width, maximized)\n- Factor selector (Boxplot/Pareto views only)\n- Filter breadcrumbs (when filters active, horizontal scroll)\n- ANOVA results (below Boxplot)\n\n### What's Hidden on Phone\n\n- Editable chart titles\n- Chart export buttons (copy, download, SVG)\n- Maximize button (carousel IS full-view)\n- Draggable text annotations (replaced by bottom-sheet action menu for highlights + findings)\n- FilterContextBar per-card\n- Stage column selector\n- Selection panel (brush selection is desktop-only)\n\n---\n\n## Toolbar Adaptation\n\n### Phone Header\n\n```\n[←] [Project name (truncated)] [💾] [⋮]\n```\n\nThe ⋮ overflow menu contains:\n\n- Add Data\n- Edit Data\n- Export CSV\n- What-If\n- Presentation\n- Findings (with count badge)\n- Data Table\n\n### Desktop Header\n\n```\n[← Back] [Project name] [Sync status] [+ Add Data ▾] [✏️] [⬇️] [🧪 What-If] [🖥️] [📋 Findings] [📊] [💾 Save]\n```\n\n---\n\n## Findings on Phone\n\nOn phone, the FindingsPanel renders as a **fixed full-screen overlay** instead of a resizable sidebar:\n\n- Triggered from overflow menu or pin button\n- Close button (44px touch target) in header\n- Same FindingsLog content as desktop\n- Popout button hidden (no multi-window on mobile)\n\n---\n\n## Data Panel on Phone\n\nThe inline DataPanel is hidden on phone. Instead:\n\n- \"Data Table\" in overflow menu opens DataTableModal (full-screen modal)\n- Point-click → row-highlight sync is disabled (no room for side panel)\n\n---\n\n## Key Design Principles\n\n1. **One thing at a time**: Phone shows a single chart, not a miniaturized dashboard\n2. **Native feel**: Swipe gesture matches iOS/Android navigation patterns\n3. **Desktop unchanged**: All responsive changes gated by `useIsMobile(640)`\n4. **Touch targets**: All interactive elements ≥ 44px (Apple HIG / Material Design)\n5. **Progressive disclosure**: Overflow menu keeps actions accessible without cluttering the header", + "src/content/docs/02-journeys/flows/azure-teams-mobile.md", + "6608a8ee62582789", + { "html": 4241, "metadata": 4242 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"azure-teams-mobile-flow\">Azure Teams Mobile Flow\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#azure-teams-mobile-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Teams Mobile Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How quality engineers use VariScout on their phones via the Teams mobile app.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona\">Persona\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ca href=\"../personas/field-fiona.md\">Field Fiona\u003C/a> — Field Quality Engineer who reviews charts during morning meetings and on the shop floor.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"flow-diagram\">Flow Diagram\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#flow-diagram\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow Diagram”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Open Teams Mobile] --> B[Tap VariScout Tab]\n B --> C{Phone or Tablet?}\n C -->|Phone < 640px| D[Carousel View]\n C -->|Tablet 640px+| E[Grid View]\n\n D --> F[Swipe Between Charts]\n F --> G[I-Chart → Boxplot → Pareto → Stats]\n G --> H{Need to Drill?}\n H -->|Yes| I[Tap Category on Boxplot/Pareto]\n I --> J[Filter Applied, Next Factor Auto-Selected]\n H -->|No| K{Need Actions?}\n\n K -->|Yes| L[Tap ⋮ Overflow Menu]\n L --> M[Findings / What-If / Export / Data Table]\n K -->|No| N[Done - Close Teams]\n\n E --> O[Full Desktop Layout]\n O --> P[All Charts Visible, Full Toolbar]\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"breakpoints\">Breakpoints\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#breakpoints\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Breakpoints”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Viewport\u003C/th>\u003Cth>Layout\u003C/th>\u003Cth>Navigation\u003C/th>\u003Cth>Toolbar\u003C/th>\u003Cth>FindingsPanel\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>< 640px (phone)\u003C/td>\u003Ctd>Carousel: 1 chart at a time\u003C/td>\u003Ctd>Swipe + pill buttons + chevrons\u003C/td>\u003Ctd>Save + ⋮ overflow\u003C/td>\u003Ctd>Full-screen overlay\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>640–1024px (tablet)\u003C/td>\u003Ctd>Grid: charts stacked/side-by-side\u003C/td>\u003Ctd>Click\u003C/td>\u003Ctd>Full inline toolbar\u003C/td>\u003Ctd>Resizable sidebar\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>> 1024px (desktop)\u003C/td>\u003Ctd>Grid: optimal layout\u003C/td>\u003Ctd>Click + keyboard\u003C/td>\u003Ctd>Full inline toolbar\u003C/td>\u003Ctd>Resizable sidebar\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phone-carousel-ux\">Phone Carousel UX\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phone-carousel-ux\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phone Carousel UX”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"navigation\">Navigation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Navigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Swipe left/right\u003C/strong>: Move between 4 views (I-Chart, Boxplot, Pareto, Stats)\u003C/li>\n\u003Cli>\u003Cstrong>Pill buttons\u003C/strong>: Direct navigation with icons (labels hidden < 400px)\u003C/li>\n\u003Cli>\u003Cstrong>Chevron arrows\u003C/strong>: Previous/next with 44px touch targets\u003C/li>\n\u003Cli>\u003Cstrong>Dot indicators\u003C/strong>: Show current position\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"whats-shown\">What’s Shown\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#whats-shown\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What’s Shown”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Current chart (full width, maximized)\u003C/li>\n\u003Cli>Factor selector (Boxplot/Pareto views only)\u003C/li>\n\u003Cli>Filter breadcrumbs (when filters active, horizontal scroll)\u003C/li>\n\u003Cli>ANOVA results (below Boxplot)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"whats-hidden-on-phone\">What’s Hidden on Phone\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#whats-hidden-on-phone\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What’s Hidden on Phone”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Editable chart titles\u003C/li>\n\u003Cli>Chart export buttons (copy, download, SVG)\u003C/li>\n\u003Cli>Maximize button (carousel IS full-view)\u003C/li>\n\u003Cli>Draggable text annotations (replaced by bottom-sheet action menu for highlights + findings)\u003C/li>\n\u003Cli>FilterContextBar per-card\u003C/li>\n\u003Cli>Stage column selector\u003C/li>\n\u003Cli>Selection panel (brush selection is desktop-only)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"toolbar-adaptation\">Toolbar Adaptation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#toolbar-adaptation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Toolbar Adaptation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phone-header\">Phone Header\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phone-header\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phone Header”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[←] [Project name (truncated)] [💾] [⋮]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[←] [Project name (truncated)] [💾] [⋮]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The ⋮ overflow menu contains:\u003C/p>\n\u003Cul>\n\u003Cli>Add Data\u003C/li>\n\u003Cli>Edit Data\u003C/li>\n\u003Cli>Export CSV\u003C/li>\n\u003Cli>What-If\u003C/li>\n\u003Cli>Presentation\u003C/li>\n\u003Cli>Findings (with count badge)\u003C/li>\n\u003Cli>Data Table\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"desktop-header\">Desktop Header\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#desktop-header\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Desktop Header”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[← Back] [Project name] [Sync status] [+ Add Data ▾] [✏️] [⬇️] [🧪 What-If] [🖥️] [📋 Findings] [📊] [💾 Save]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[← Back] [Project name] [Sync status] [+ Add Data ▾] [✏️] [⬇️] [🧪 What-If] [🖥️] [📋 Findings] [📊] [💾 Save]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"findings-on-phone\">Findings on Phone\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#findings-on-phone\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Findings on Phone”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>On phone, the FindingsPanel renders as a \u003Cstrong>fixed full-screen overlay\u003C/strong> instead of a resizable sidebar:\u003C/p>\n\u003Cul>\n\u003Cli>Triggered from overflow menu or pin button\u003C/li>\n\u003Cli>Close button (44px touch target) in header\u003C/li>\n\u003Cli>Same FindingsLog content as desktop\u003C/li>\n\u003Cli>Popout button hidden (no multi-window on mobile)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-panel-on-phone\">Data Panel on Phone\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-panel-on-phone\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Panel on Phone”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The inline DataPanel is hidden on phone. Instead:\u003C/p>\n\u003Cul>\n\u003Cli>“Data Table” in overflow menu opens DataTableModal (full-screen modal)\u003C/li>\n\u003Cli>Point-click → row-highlight sync is disabled (no room for side panel)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-design-principles\">Key Design Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-design-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Design Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>One thing at a time\u003C/strong>: Phone shows a single chart, not a miniaturized dashboard\u003C/li>\n\u003Cli>\u003Cstrong>Native feel\u003C/strong>: Swipe gesture matches iOS/Android navigation patterns\u003C/li>\n\u003Cli>\u003Cstrong>Desktop unchanged\u003C/strong>: All responsive changes gated by \u003Ccode dir=\"auto\">useIsMobile(640)\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Touch targets\u003C/strong>: All interactive elements ≥ 44px (Apple HIG / Material Design)\u003C/li>\n\u003Cli>\u003Cstrong>Progressive disclosure\u003C/strong>: Overflow menu keeps actions accessible without cluttering the header\u003C/li>\n\u003C/ol>", + { + "headings": 4243, + "localImagePaths": 4283, + "remoteImagePaths": 4284, + "frontmatter": 4285, + "imagePaths": 4286 + }, + [4244, 4246, 4249, 4252, 4255, 4258, 4259, 4262, 4265, 4268, 4271, 4274, 4277, 4280], + { "depth": 30, "slug": 4245, "text": 4233 }, + "azure-teams-mobile-flow", + { "depth": 33, "slug": 4247, "text": 4248 }, + "persona", + "Persona", + { "depth": 33, "slug": 4250, "text": 4251 }, + "flow-diagram", + "Flow Diagram", + { "depth": 33, "slug": 4253, "text": 4254 }, + "breakpoints", + "Breakpoints", + { "depth": 33, "slug": 4256, "text": 4257 }, + "phone-carousel-ux", + "Phone Carousel UX", + { "depth": 79, "slug": 1099, "text": 1100 }, + { "depth": 79, "slug": 4260, "text": 4261 }, + "whats-shown", + "What’s Shown", + { "depth": 79, "slug": 4263, "text": 4264 }, + "whats-hidden-on-phone", + "What’s Hidden on Phone", + { "depth": 33, "slug": 4266, "text": 4267 }, + "toolbar-adaptation", + "Toolbar Adaptation", + { "depth": 79, "slug": 4269, "text": 4270 }, + "phone-header", + "Phone Header", + { "depth": 79, "slug": 4272, "text": 4273 }, + "desktop-header", + "Desktop Header", + { "depth": 33, "slug": 4275, "text": 4276 }, + "findings-on-phone", + "Findings on Phone", + { "depth": 33, "slug": 4278, "text": 4279 }, + "data-panel-on-phone", + "Data Panel on Phone", + { "depth": 33, "slug": 4281, "text": 4282 }, + "key-design-principles", + "Key Design Principles", + [], + [], + { "title": 4233 }, + [], + "02-journeys/flows/content-youtube", + { "id": 4287, "data": 4289, "body": 4294, "filePath": 4295, "digest": 4296, "rendered": 4297 }, + { + "title": 4290, + "editUrl": 16, + "head": 4291, + "template": 18, + "sidebar": 4292, + "pagefind": 16, + "draft": 20 + }, + "Flow 3: YouTube/Content → Website → Product", + [], + { "hidden": 20, "attrs": 4293 }, + {}, + "# Flow 3: YouTube/Content → Website → Product\n\n> Curious Carlos discovers VaRiScout through content, builds trust, converts\n>\n> **Priority:** High - authority building + warm leads\n>\n> See also: [Journeys Overview](../index.md)\n\n---\n\n## Persona: Curious Carlos (Content Path)\n\n| Attribute | Detail |\n| ------------------ | ------------------------------------------------- |\n| **Role** | Operations Supervisor |\n| **Goal** | Understand variation better |\n| **Knowledge** | Interested but not formally trained |\n| **Content need** | Visual explanations, real examples |\n| **Entry points** | YouTube search, TikTok For You, Instagram Explore |\n| **Trust building** | Needs multiple touchpoints before converting |\n\n### What Carlos is thinking:\n\n- \"This guy explains it in a way I can understand\"\n- \"I've seen a few of his videos now\"\n- \"Maybe I should try that tool he uses\"\n\n---\n\n## The Content Engine\n\n```\n1 VIDEO (Jukkis talking, 5-10 min)\n │\n ├── YouTube (full video)\n ├── Blog post (transcript + expansion)\n ├── LinkedIn posts (2-3 per week)\n ├── TikTok clips (3-5 per video)\n └── Instagram reels + carousel\n```\n\nEvery piece of content leads back to the website.\n\n---\n\n## Entry Points\n\n| Platform | Content Type | Lands On |\n| ----------------- | ----------------------- | ------------------- |\n| YouTube search | \"how to read I-chart\" | /tools/i-chart |\n| YouTube suggested | VaRiScout tutorial | /blog/X or / |\n| TikTok clip | \"AI vs I-Chart\" hook | / or /tools/i-chart |\n| Instagram reel | Quick chart explanation | /tools/X |\n| LinkedIn post | Thought leadership | /blog/X or /cases/X |\n\n---\n\n## Journey Flow\n\n### Mermaid Flowchart\n\n```mermaid\nflowchart TD\n A[YouTube Search OR\u003Cbr/>TikTok/IG Algorithm] --> B[VaRiScout Content\u003Cbr/>Educational video with demo]\n B --> C[Video CTA\u003Cbr/>'Try VaRiScout']\n C --> D{Landing Page}\n D -->|Blog| E[/blog post]\n D -->|Tool| F[/tools/X]\n E --> G{Explore}\n F --> G\n G -->|Try demo| H[Interactive exploration]\n G -->|Read more| I[Deeper content]\n H --> J[/pricing]\n I --> J\n J --> K{Outcome}\n K --> L[CONVERSION]\n K --> M[TRAINING INQUIRY]\n```\n\n### User Satisfaction Journey\n\n```mermaid\njourney\n title Content/YouTube Journey\n section Discovery\n YouTube/TikTok algorithm: 3: User\n Watch educational video: 4: User\n section Trust Building\n Content resonates: 5: User\n See more videos: 4: User\n section Exploration\n Click link in bio: 4: User\n Explore website: 5: User\n section Warm Lead\n Try interactive demo: 5: User\n Understand methodology: 5: User\n section Conversion\n Purchase Azure App: 5: User\n Or training inquiry: 4: User\n```\n\n### The Content Flywheel\n\n```mermaid\nflowchart LR\n A[Free tool user] --> B[Sees value]\n B --> C[Training participant]\n C --> D[Uses in project]\n D --> E[Coaching client]\n E --> F[Recommends to colleagues]\n F --> A\n```\n\n### ASCII Reference\n\n```\n┌─────────────────┐\n│ YouTube Search │\n│ \"how to read │\n│ control chart\" │\n│ OR │\n│ TikTok/IG clip │\n│ \"AI vs I-Chart\" │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ VaRiScout │\n│ Content │\n│ │\n│ Educational │\n│ video/clip │\n│ with demo │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ Video CTA: │\n│ \"Try VaRiScout\" │\n│ Link in bio/ │\n│ description │\n└────────┬────────┘\n │\n ┌────┴────┐\n │ │\n ▼ ▼\n┌────────┐ ┌────────────┐\n│ /blog │ │ /tools/X │\n│ (post) │ │ │\n└────┬───┘ └─────┬──────┘\n │ │\n │ ┌──────┴──────┐\n │ │ │\n │ ▼ ▼\n │ ┌────────┐ ┌────────────┐\n │ │Try demo│ │ Deeper │\n │ │ │ │ content │\n │ └────┬───┘ └─────┬──────┘\n │ │ │\n └──────┼───────────┘\n │\n ▼\n ┌─────────────────┐\n │ /pricing │\n │ │\n │ Warm from video │\n │ Ready to try │\n └────────┬────────┘\n │\n ▼\n ┌─────────────────┐\n │ CONVERSION │\n │ OR │\n │ TRAINING │\n │ INQUIRY │\n └─────────────────┘\n```\n\n---\n\n## Weekly Content Cycle\n\n| Day | Content |\n| ------------- | ------------------------------------------------- |\n| **Monday** | YouTube video + Blog post + LinkedIn announcement |\n| **Tuesday** | LinkedIn post #1 + TikTok clip #1 |\n| **Wednesday** | Instagram carousel + TikTok clip #2 |\n| **Thursday** | LinkedIn post #2 + TikTok clip #3 |\n| **Friday** | LinkedIn post #3 (engagement/discussion) |\n\n---\n\n## The Flywheel\n\n```\nFree tool user\n ↓\nSees value, wants to learn more\n ↓\nTraining participant (GB course)\n ↓\nUses tool in real project (at gemba)\n ↓\nNeeds coaching support\n ↓\nCoaching client (explore data together)\n ↓\nRecommends to colleagues → New free tool users\n```\n\nContent → Tool → Training → Coaching → Referral → Content\n\n---\n\n## CTAs in Content\n\n| Platform | CTA | Destination |\n| --------- | ----------------------------- | --------------------- |\n| YouTube | \"Try VaRiScout\" (description) | variscout.com/app |\n| YouTube | \"Read more\" (description) | variscout.com/blog/X |\n| TikTok | \"Link in bio\" | variscout.com |\n| Instagram | \"Link in bio\" | variscout.com |\n| LinkedIn | Direct link in post | variscout.com/cases/X |\n| Blog post | \"Try it yourself\" | /app |\n| Blog post | \"Get the full course\" | RDMAIC training link |\n\n---\n\n## Content to Website Links\n\n| Content Topic | Website Page | Reason |\n| ------------------------ | ------------------ | --------------------- |\n| \"How to read I-Chart\" | /tools/i-chart | Deep dive + demo |\n| \"Boxplot interpretation\" | /tools/boxplot | Interactive learning |\n| \"The 46% story\" | /cases/bottleneck | Full case study |\n| \"Four Lenses method\" | /learn/four-lenses | Methodology deep dive |\n| \"AI vs EDA\" | /blog/ai-vs-eda | Thought leadership |\n| General awareness | / | Full journey |\n\n---\n\n## Mobile Considerations\n\n- Most TikTok/Instagram traffic is mobile\n- Landing pages must load fast (\u003C3s)\n- Demo must work on phone\n- Single prominent CTA\n- No friction to /app\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ---------------------------------- | ------ |\n| YouTube → Website (UTM) | >5% |\n| TikTok/IG → Website (UTM) | >2% |\n| Content viewers → Product page | >10% |\n| Content viewers → Training inquiry | Track |\n| Blog post → Email capture | >3% |\n\n---\n\n## UTM Tracking\n\nStandard UTM structure:\n\n```\n?utm_source=youtube&utm_medium=video&utm_campaign=ichart-tutorial\n?utm_source=tiktok&utm_medium=clip&utm_campaign=ai-vs-eda\n?utm_source=linkedin&utm_medium=post&utm_campaign=weekly-content\n```\n\nTrack:\n\n- Source platform\n- Content type\n- Specific campaign/topic\n\n---\n\n## Related Documents\n\n- [Social Discovery Flow](./social-discovery.md) - Social case discovery flow", + "src/content/docs/02-journeys/flows/content-youtube.md", + "bb9f84b591beb8a2", + { "html": 4298, "metadata": 4299 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"flow-3-youtubecontent--website--product\">Flow 3: YouTube/Content → Website → Product\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#flow-3-youtubecontent--website--product\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 3: YouTube/Content → Website → Product”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Curious Carlos discovers VaRiScout through content, builds trust, converts\u003C/p>\n\u003Cp>\u003Cstrong>Priority:\u003C/strong> High - authority building + warm leads\u003C/p>\n\u003Cp>See also: \u003Ca href=\"../index.md\">Journeys Overview\u003C/a>\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-curious-carlos-content-path\">Persona: Curious Carlos (Content Path)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-curious-carlos-content-path\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona: Curious Carlos (Content Path)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Operations Supervisor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Understand variation better\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Interested but not formally trained\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Content need\u003C/strong>\u003C/td>\u003Ctd>Visual explanations, real examples\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Entry points\u003C/strong>\u003C/td>\u003Ctd>YouTube search, TikTok For You, Instagram Explore\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Trust building\u003C/strong>\u003C/td>\u003Ctd>Needs multiple touchpoints before converting\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-carlos-is-thinking\">What Carlos is thinking:\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-carlos-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Carlos is thinking:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“This guy explains it in a way I can understand”\u003C/li>\n\u003Cli>“I’ve seen a few of his videos now”\u003C/li>\n\u003Cli>“Maybe I should try that tool he uses”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-content-engine\">The Content Engine\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-content-engine\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Content Engine”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">1 VIDEO (Jukkis talking, 5-10 min)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── YouTube (full video)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Blog post (transcript + expansion)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── LinkedIn posts (2-3 per week)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── TikTok clips (3-5 per video)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Instagram reels + carousel\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"1 VIDEO (Jukkis talking, 5-10 min) │ ├── YouTube (full video) ├── Blog post (transcript + expansion) ├── LinkedIn posts (2-3 per week) ├── TikTok clips (3-5 per video) └── Instagram reels + carousel\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Every piece of content leads back to the website.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Content Type\u003C/th>\u003Cth>Lands On\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>YouTube search\u003C/td>\u003Ctd>”how to read I-chart”\u003C/td>\u003Ctd>/tools/i-chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>YouTube suggested\u003C/td>\u003Ctd>VaRiScout tutorial\u003C/td>\u003Ctd>/blog/X or /\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>TikTok clip\u003C/td>\u003Ctd>”AI vs I-Chart” hook\u003C/td>\u003Ctd>/ or /tools/i-chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Instagram reel\u003C/td>\u003Ctd>Quick chart explanation\u003C/td>\u003Ctd>/tools/X\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LinkedIn post\u003C/td>\u003Ctd>Thought leadership\u003C/td>\u003Ctd>/blog/X or /cases/X\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mermaid-flowchart\">Mermaid Flowchart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mermaid-flowchart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mermaid Flowchart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[YouTube Search OR<br/>TikTok/IG Algorithm] --> B[VaRiScout Content<br/>Educational video with demo]\n B --> C[Video CTA<br/>'Try VaRiScout']\n C --> D{Landing Page}\n D -->|Blog| E[/blog post]\n D -->|Tool| F[/tools/X]\n E --> G{Explore}\n F --> G\n G -->|Try demo| H[Interactive exploration]\n G -->|Read more| I[Deeper content]\n H --> J[/pricing]\n I --> J\n J --> K{Outcome}\n K --> L[CONVERSION]\n K --> M[TRAINING INQUIRY]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-satisfaction-journey\">User Satisfaction Journey\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-satisfaction-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Satisfaction Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Content/YouTube Journey\n section Discovery\n YouTube/TikTok algorithm: 3: User\n Watch educational video: 4: User\n section Trust Building\n Content resonates: 5: User\n See more videos: 4: User\n section Exploration\n Click link in bio: 4: User\n Explore website: 5: User\n section Warm Lead\n Try interactive demo: 5: User\n Understand methodology: 5: User\n section Conversion\n Purchase Azure App: 5: User\n Or training inquiry: 4: User\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-content-flywheel\">The Content Flywheel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-content-flywheel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Content Flywheel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n A[Free tool user] --> B[Sees value]\n B --> C[Training participant]\n C --> D[Uses in project]\n D --> E[Coaching client]\n E --> F[Recommends to colleagues]\n F --> A\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ascii-reference\">ASCII Reference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ascii-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ASCII Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ YouTube Search │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"how to read │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ control chart\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ OR │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ TikTok/IG clip │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"AI vs I-Chart\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ VaRiScout │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Content │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Educational │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ video/clip │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ with demo │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Video CTA: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Try VaRiScout\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Link in bio/ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ description │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────┐ ┌────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /blog │ │ /tools/X │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (post) │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────┬───┘ └─────┬──────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌──────┴──────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌────────┐ ┌────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │Try demo│ │ Deeper │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ content │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └────┬───┘ └─────┬──────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────┼───────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /pricing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Warm from video │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Ready to try │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CONVERSION │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ OR │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ TRAINING │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ INQUIRY │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ YouTube Search ││ "how to read ││ control chart" ││ OR ││ TikTok/IG clip ││ "AI vs I-Chart" │└────────┬────────┘ │ ▼┌─────────────────┐│ VaRiScout ││ Content ││ ││ Educational ││ video/clip ││ with demo │└────────┬────────┘ │ ▼┌─────────────────┐│ Video CTA: ││ "Try VaRiScout" ││ Link in bio/ ││ description │└────────┬────────┘ │ ┌────┴────┐ │ │ ▼ ▼┌────────┐ ┌────────────┐│ /blog │ │ /tools/X ││ (post) │ │ │└────┬───┘ └─────┬──────┘ │ │ │ ┌──────┴──────┐ │ │ │ │ ▼ ▼ │ ┌────────┐ ┌────────────┐ │ │Try demo│ │ Deeper │ │ │ │ │ content │ │ └────┬───┘ └─────┬──────┘ │ │ │ └──────┼───────────┘ │ ▼ ┌─────────────────┐ │ /pricing │ │ │ │ Warm from video │ │ Ready to try │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ CONVERSION │ │ OR │ │ TRAINING │ │ INQUIRY │ └─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"weekly-content-cycle\">Weekly Content Cycle\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#weekly-content-cycle\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Weekly Content Cycle”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Day\u003C/th>\u003Cth>Content\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Monday\u003C/strong>\u003C/td>\u003Ctd>YouTube video + Blog post + LinkedIn announcement\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Tuesday\u003C/strong>\u003C/td>\u003Ctd>LinkedIn post #1 + TikTok clip #1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Wednesday\u003C/strong>\u003C/td>\u003Ctd>Instagram carousel + TikTok clip #2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Thursday\u003C/strong>\u003C/td>\u003Ctd>LinkedIn post #2 + TikTok clip #3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Friday\u003C/strong>\u003C/td>\u003Ctd>LinkedIn post #3 (engagement/discussion)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-flywheel\">The Flywheel\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-flywheel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Flywheel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Free tool user\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Sees value, wants to learn more\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Training participant (GB course)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Uses tool in real project (at gemba)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Needs coaching support\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Coaching client (explore data together)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Recommends to colleagues → New free tool users\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Free tool user ↓Sees value, wants to learn more ↓Training participant (GB course) ↓Uses tool in real project (at gemba) ↓Needs coaching support ↓Coaching client (explore data together) ↓Recommends to colleagues → New free tool users\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Content → Tool → Training → Coaching → Referral → Content\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ctas-in-content\">CTAs in Content\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ctas-in-content\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CTAs in Content”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>CTA\u003C/th>\u003Cth>Destination\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>YouTube\u003C/td>\u003Ctd>”Try VaRiScout” (description)\u003C/td>\u003Ctd>variscout.com/app\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>YouTube\u003C/td>\u003Ctd>”Read more” (description)\u003C/td>\u003Ctd>variscout.com/blog/X\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>TikTok\u003C/td>\u003Ctd>”Link in bio”\u003C/td>\u003Ctd>variscout.com\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Instagram\u003C/td>\u003Ctd>”Link in bio”\u003C/td>\u003Ctd>variscout.com\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LinkedIn\u003C/td>\u003Ctd>Direct link in post\u003C/td>\u003Ctd>variscout.com/cases/X\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Blog post\u003C/td>\u003Ctd>”Try it yourself”\u003C/td>\u003Ctd>/app\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Blog post\u003C/td>\u003Ctd>”Get the full course”\u003C/td>\u003Ctd>RDMAIC training link\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"content-to-website-links\">Content to Website Links\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#content-to-website-links\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Content to Website Links”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Content Topic\u003C/th>\u003Cth>Website Page\u003C/th>\u003Cth>Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”How to read I-Chart”\u003C/td>\u003Ctd>/tools/i-chart\u003C/td>\u003Ctd>Deep dive + demo\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Boxplot interpretation”\u003C/td>\u003Ctd>/tools/boxplot\u003C/td>\u003Ctd>Interactive learning\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”The 46% story”\u003C/td>\u003Ctd>/cases/bottleneck\u003C/td>\u003Ctd>Full case study\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Four Lenses method”\u003C/td>\u003Ctd>/learn/four-lenses\u003C/td>\u003Ctd>Methodology deep dive\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”AI vs EDA”\u003C/td>\u003Ctd>/blog/ai-vs-eda\u003C/td>\u003Ctd>Thought leadership\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>General awareness\u003C/td>\u003Ctd>/\u003C/td>\u003Ctd>Full journey\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"mobile-considerations\">Mobile Considerations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Most TikTok/Instagram traffic is mobile\u003C/li>\n\u003Cli>Landing pages must load fast (<3s)\u003C/li>\n\u003Cli>Demo must work on phone\u003C/li>\n\u003Cli>Single prominent CTA\u003C/li>\n\u003Cli>No friction to /app\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>YouTube → Website (UTM)\u003C/td>\u003Ctd>>5%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>TikTok/IG → Website (UTM)\u003C/td>\u003Ctd>>2%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Content viewers → Product page\u003C/td>\u003Ctd>>10%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Content viewers → Training inquiry\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Blog post → Email capture\u003C/td>\u003Ctd>>3%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"utm-tracking\">UTM Tracking\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#utm-tracking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “UTM Tracking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standard UTM structure:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">?utm_source=youtube&utm_medium=video&utm_campaign=ichart-tutorial\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">?utm_source=tiktok&utm_medium=clip&utm_campaign=ai-vs-eda\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">?utm_source=linkedin&utm_medium=post&utm_campaign=weekly-content\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"?utm_source=youtube&utm_medium=video&utm_campaign=ichart-tutorial?utm_source=tiktok&utm_medium=clip&utm_campaign=ai-vs-eda?utm_source=linkedin&utm_medium=post&utm_campaign=weekly-content\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Track:\u003C/p>\n\u003Cul>\n\u003Cli>Source platform\u003C/li>\n\u003Cli>Content type\u003C/li>\n\u003Cli>Specific campaign/topic\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documents\">Related Documents\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documents\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documents”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./social-discovery.md\">Social Discovery Flow\u003C/a> - Social case discovery flow\u003C/li>\n\u003C/ul>", + { + "headings": 4300, + "localImagePaths": 4344, + "remoteImagePaths": 4345, + "frontmatter": 4346, + "imagePaths": 4347 + }, + [ + 4301, 4303, 4306, 4309, 4312, 4313, 4314, 4315, 4318, 4321, 4322, 4325, 4328, 4331, 4334, 4337, + 4338, 4341 + ], + { "depth": 30, "slug": 4302, "text": 4290 }, + "flow-3-youtubecontent--website--product", + { "depth": 33, "slug": 4304, "text": 4305 }, + "persona-curious-carlos-content-path", + "Persona: Curious Carlos (Content Path)", + { "depth": 79, "slug": 4307, "text": 4308 }, + "what-carlos-is-thinking", + "What Carlos is thinking:", + { "depth": 33, "slug": 4310, "text": 4311 }, + "the-content-engine", + "The Content Engine", + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 79, "slug": 4078, "text": 4079 }, + { "depth": 79, "slug": 4316, "text": 4317 }, + "user-satisfaction-journey", + "User Satisfaction Journey", + { "depth": 79, "slug": 4319, "text": 4320 }, + "the-content-flywheel", + "The Content Flywheel", + { "depth": 79, "slug": 919, "text": 920 }, + { "depth": 33, "slug": 4323, "text": 4324 }, + "weekly-content-cycle", + "Weekly Content Cycle", + { "depth": 33, "slug": 4326, "text": 4327 }, + "the-flywheel", + "The Flywheel", + { "depth": 33, "slug": 4329, "text": 4330 }, + "ctas-in-content", + "CTAs in Content", + { "depth": 33, "slug": 4332, "text": 4333 }, + "content-to-website-links", + "Content to Website Links", + { "depth": 33, "slug": 4335, "text": 4336 }, + "mobile-considerations", + "Mobile Considerations", + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4339, "text": 4340 }, + "utm-tracking", + "UTM Tracking", + { "depth": 33, "slug": 4342, "text": 4343 }, + "related-documents", + "Related Documents", + [], + [], + { "title": 4290 }, + [], + "02-journeys/flows/enterprise", + { "id": 4348, "data": 4350, "body": 4355, "filePath": 4356, "digest": 4357, "rendered": 4358 }, + { + "title": 4351, + "editUrl": 16, + "head": 4352, + "template": 18, + "sidebar": 4353, + "pagefind": 16, + "draft": 20 + }, + "Flow 4: Enterprise Evaluator", + [], + { "hidden": 20, "attrs": 4354 }, + {}, + "# Flow 4: Enterprise Evaluator\n\n> OpEx Olivia evaluates VaRiScout for her team via self-serve journey\n>\n> **Priority:** Medium - self-serve, documentation-first\n>\n> See also: [Journeys Overview](../index.md) for site architecture\n\n---\n\n## Persona: OpEx Olivia\n\n| Attribute | Detail |\n| ----------------- | -------------------------------------------------- |\n| **Role** | OpEx Manager |\n| **Goal** | Find tools for team |\n| **Knowledge** | Strategic, evaluates ROI |\n| **Pain points** | Budget constraints, IT approval, change management |\n| **Entry points** | Referral from colleague, LinkedIn, conference |\n| **Decision mode** | Needs security docs, deployment guide, pricing |\n\n### What Olivia is thinking:\n\n- \"My team needs better analysis tools\"\n- \"Can I justify the cost vs Minitab?\"\n- \"What's the IT/security story?\"\n- \"How hard is deployment?\"\n\n---\n\n## Entry Points\n\n| Source | Arrives Via | Lands On |\n| ------------------- | ------------------- | ------------- |\n| Colleague referral | Direct link | / or /pricing |\n| Conference | QR code / card | / |\n| LinkedIn | Company page / post | / or /pricing |\n| Team member request | \"Check this out\" | /pricing |\n\n---\n\n## Journey Flow\n\n### Mermaid Flowchart\n\n```mermaid\nflowchart TD\n A[Referral from colleague\u003Cbr/>or conference] --> B[Homepage\u003Cbr/>What is this? Who is it for?]\n B --> C{Path Choice}\n C -->|Learn more| D[/journey\u003Cbr/>See methodology]\n C -->|Direct| E[/pricing]\n D --> F[I get it - now eval for team]\n F --> E\n E --> G[/product/enterprise]\n G --> H{Evaluation Questions}\n H -->|SSO/Security?| I[Documentation]\n H -->|Data hosting?| J[Your Azure, your data]\n H -->|Deployment?| K[1-click ARM template]\n H -->|Need help?| L[Your consultants can assist]\n I --> M{Decision}\n J --> M\n K --> M\n L --> M\n M -->|Self-serve| N[Purchase online + Deploy]\n M -->|Assisted| O[Consultant deployment]\n```\n\n### Enterprise Evaluation Journey\n\n```mermaid\njourney\n title Enterprise Evaluator Journey\n section Awareness\n Colleague recommendation: 4: User\n Quick homepage scan: 4: User\n section Understanding\n Explore methodology: 4: User\n See value proposition: 5: User\n section Evaluation\n Check security docs: 4: User\n Review deployment: 4: User\n Compare pricing: 4: User\n section Decision\n IT/Procurement review: 3: User\n Budget approval: 3: User\n section Deployment\n Self-serve purchase: 5: User\n ARM template deploy: 5: User\n```\n\n### Self-Serve Model\n\n```mermaid\nflowchart LR\n A[Discover] --> B[Evaluate]\n B --> C[Purchase]\n C --> D[Deploy]\n D --> E[Use]\n\n A -.->|Website, referral| A\n B -.->|Free tier, docs| B\n C -.->|Azure Marketplace| C\n D -.->|ARM template| D\n E -.->|Docs + email| E\n```\n\n### ASCII Reference\n\n```\n┌─────────────────┐\n│ Referral from │\n│ colleague or │\n│ conference │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ / (Homepage) │\n│ │\n│ Quick scan: │\n│ \"What is this?\" │\n│ \"Who is it for?\"│\n└────────┬────────┘\n │\n ┌────┴────────────┐\n │ │\n ▼ ▼\n┌────────────┐ ┌────────────┐\n│ /journey │ │ /pricing │\n│ │ │ │\n│ See the │ │ Jump to │\n│ methodology│ │ enterprise │\n└─────┬──────┘ └─────┬──────┘\n │ │\n ▼ │\n┌────────────┐ │\n│ \"I get it\" │ │\n│ │ │\n│ Now eval │ │\n│ for team │────────┘\n└─────┬──────┘\n │\n ▼\n┌─────────────────┐\n│ /product/ │\n│ enterprise │\n│ │\n│ Features │\n│ Security docs │\n│ Deployment guide│\n│ Pricing │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ Questions: │\n│ │\n│ • SSO/Security? │ → Documentation\n│ • Data hosting? │ → \"Your Azure, your data\"\n│ • Deployment? │ → 1-click ARM template\n│ • Need help? │ → Your LSS/IT consultants can assist\n└────────┬────────┘\n │\n ┌────┴────────────────┐\n │ │\n ▼ ▼\n┌────────────┐ ┌─────────────────┐\n│ SELF-SERVE │ │ NEED HELP? │\n│ │ │ │\n│ Purchase │ │ Your existing │\n│ online │ │ consultants │\n│ Deploy │ │ can deploy it │\n└────────────┘ └─────────────────┘\n```\n\n---\n\n## Enterprise Page Requirements\n\nThe /product/enterprise page must answer:\n\n### 1. Security & Compliance\n\n- Where is data stored? → \"Your Azure tenant, your data\"\n- SSO support? → Azure AD / Microsoft Entra ID\n- Compliance? → SOC 2 considerations, GDPR\n- Audit logs? → Azure native logging\n\n### 2. Deployment\n\n- How to deploy? → Azure Marketplace Managed Application\n- Time to deploy? → Minutes (Managed Application)\n- Who deploys? → Azure Marketplace handles it\n- Updates? → Automatic via Azure\n\n### 3. Pricing\n\n- From €99/month (Standard) or €299/month (Team) — unlimited users in your tenant\n- No per-user fees, no hidden costs\n- Two plans: Standard (local analysis) or Team (+ Teams, OneDrive, mobile)\n\n### 4. Support\n\n- Documentation-first\n- Email support (support@rdmaic.com)\n- \"Your existing LSS/IT consultants can assist\"\n\n---\n\n## Self-Serve Enterprise Model\n\nKey principle: **No sales calls required**\n\n| Step | How It Works |\n| -------------- | --------------------------------------------------- |\n| Discover | Website, referral, content |\n| Evaluate | PWA (free), documentation, case studies |\n| Purchase | Azure Marketplace (from €99/month, unlimited users) |\n| Deploy | Managed Application (automatic) |\n| Support | Documentation + email (support@rdmaic.com) |\n| Implementation | Your existing consultants can help |\n\n---\n\n## CTAs on This Journey\n\n| Location | CTA Text | Destination |\n| --------------- | -------------------------------- | ------------------- |\n| Homepage | \"For Teams\" or \"Enterprise\" | /product/enterprise |\n| Journey page | \"Deploy for your team\" | /product/enterprise |\n| Pricing page | \"Enterprise details\" | /product/enterprise |\n| Enterprise page | \"Deploy Now\" (Marketplace link) | Azure Marketplace |\n| Enterprise page | \"Get Started\" (deployment guide) | /getting-started |\n\n---\n\n## Information Olivia Needs\n\n| Question | Answer Location |\n| --------------------------- | ------------------------ |\n| What does it do? | /journey, /tools |\n| Is it secure? | /product/enterprise |\n| Where's my data? | /product/enterprise |\n| How much does it cost? | /pricing |\n| How do I deploy? | /getting-started |\n| Who supports it? | support@rdmaic.com |\n| Can I try it first? | /app (free, permanently) |\n| What training is available? | Link to RDMAIC training |\n\n---\n\n## Evaluator Erik (Secondary)\n\nIT/Procurement evaluator may also be involved:\n\n| Erik's Questions | Answer |\n| -------------------------- | --------------------------------- |\n| Security architecture? | Azure-native, your tenant |\n| Data residency? | Your choice of Azure region |\n| Authentication? | Azure AD SSO |\n| Compliance certifications? | Azure compliance + our docs |\n| SLA? | Azure SLA |\n| Exit strategy? | Export all data, standard formats |\n\n---\n\n## Mobile Considerations\n\n- Enterprise page should work on mobile (conference scanning)\n- Key info visible without deep scrolling\n- Easy path to schedule demo or download docs\n- QR codes on printed materials\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ------------------------------ | ------ |\n| Homepage → Enterprise page | Track |\n| Enterprise page → Deployment | >5% |\n| Enterprise page → Contact | >2% |\n| ARM template downloads | Track |\n| Time to purchase (first visit) | Track |\n\n---\n\n## After Purchase: In-App Journeys\n\nOnce Olivia's team deploys via Azure Marketplace, the journey continues in-app:\n\n| Next Flow | Who | What happens |\n| ------------------------------------------------------- | ----------------- | -------------------------------------------------------- |\n| [Azure First Analysis](azure-first-analysis.md) | Gary (end user) | First login → SSO → empty state → first chart in \u003C 3 min |\n| [Azure Daily Use](azure-daily-use.md) | Gary (daily user) | Repeat analysis, Performance Mode, exports |\n| [Azure Team Collaboration](azure-team-collaboration.md) | Olivia (admin) | Teams setup, sharing, onboarding colleagues |\n\nUsers who tried the [PWA](return-visitor.md) before purchasing will find the same analysis workflow — skills transfer directly. The key differences are persistence (IndexedDB on Standard; + OneDrive sync on Team plan), file upload, Performance Mode, and 6-factor support.\n\n---\n\n## Gap: Enterprise Page Content Needed\n\n**Status:** Content pending — the `/product/enterprise` website page does not yet exist. Journey flows currently route to this page, but visitors will land on a generic product page.\n\nThe enterprise page needs:\n\n- Full security documentation (data residency, encryption, compliance)\n- Deployment guide with screenshots\n- Pricing calculator\n- FAQ for IT/Procurement\n- Customer logos / testimonials (when available)\n\nUntil this page is built, the [How It Works](../../08-products/azure/how-it-works.md) doc covers the technical architecture, and the [Marketplace Guide](../../08-products/azure/marketplace.md) covers deployment.", + "src/content/docs/02-journeys/flows/enterprise.md", + "7a3b390e3f197668", + { "html": 4359, "metadata": 4360 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"flow-4-enterprise-evaluator\">Flow 4: Enterprise Evaluator\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#flow-4-enterprise-evaluator\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 4: Enterprise Evaluator”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>OpEx Olivia evaluates VaRiScout for her team via self-serve journey\u003C/p>\n\u003Cp>\u003Cstrong>Priority:\u003C/strong> Medium - self-serve, documentation-first\u003C/p>\n\u003Cp>See also: \u003Ca href=\"../index.md\">Journeys Overview\u003C/a> for site architecture\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-opex-olivia\">Persona: OpEx Olivia\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-opex-olivia\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona: OpEx Olivia”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>OpEx Manager\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Find tools for team\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Strategic, evaluates ROI\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Budget constraints, IT approval, change management\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Entry points\u003C/strong>\u003C/td>\u003Ctd>Referral from colleague, LinkedIn, conference\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Needs security docs, deployment guide, pricing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-olivia-is-thinking\">What Olivia is thinking:\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-olivia-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Olivia is thinking:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“My team needs better analysis tools”\u003C/li>\n\u003Cli>“Can I justify the cost vs Minitab?”\u003C/li>\n\u003Cli>“What’s the IT/security story?”\u003C/li>\n\u003Cli>“How hard is deployment?”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Source\u003C/th>\u003Cth>Arrives Via\u003C/th>\u003Cth>Lands On\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Colleague referral\u003C/td>\u003Ctd>Direct link\u003C/td>\u003Ctd>/ or /pricing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Conference\u003C/td>\u003Ctd>QR code / card\u003C/td>\u003Ctd>/\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LinkedIn\u003C/td>\u003Ctd>Company page / post\u003C/td>\u003Ctd>/ or /pricing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Team member request\u003C/td>\u003Ctd>”Check this out”\u003C/td>\u003Ctd>/pricing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mermaid-flowchart\">Mermaid Flowchart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mermaid-flowchart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mermaid Flowchart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Referral from colleague<br/>or conference] --> B[Homepage<br/>What is this? Who is it for?]\n B --> C{Path Choice}\n C -->|Learn more| D[/journey<br/>See methodology]\n C -->|Direct| E[/pricing]\n D --> F[I get it - now eval for team]\n F --> E\n E --> G[/product/enterprise]\n G --> H{Evaluation Questions}\n H -->|SSO/Security?| I[Documentation]\n H -->|Data hosting?| J[Your Azure, your data]\n H -->|Deployment?| K[1-click ARM template]\n H -->|Need help?| L[Your consultants can assist]\n I --> M{Decision}\n J --> M\n K --> M\n L --> M\n M -->|Self-serve| N[Purchase online + Deploy]\n M -->|Assisted| O[Consultant deployment]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"enterprise-evaluation-journey\">Enterprise Evaluation Journey\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#enterprise-evaluation-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Enterprise Evaluation Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Enterprise Evaluator Journey\n section Awareness\n Colleague recommendation: 4: User\n Quick homepage scan: 4: User\n section Understanding\n Explore methodology: 4: User\n See value proposition: 5: User\n section Evaluation\n Check security docs: 4: User\n Review deployment: 4: User\n Compare pricing: 4: User\n section Decision\n IT/Procurement review: 3: User\n Budget approval: 3: User\n section Deployment\n Self-serve purchase: 5: User\n ARM template deploy: 5: User\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"self-serve-model\">Self-Serve Model\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#self-serve-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Self-Serve Model”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n A[Discover] --> B[Evaluate]\n B --> C[Purchase]\n C --> D[Deploy]\n D --> E[Use]\n\n A -.->|Website, referral| A\n B -.->|Free tier, docs| B\n C -.->|Azure Marketplace| C\n D -.->|ARM template| D\n E -.->|Docs + email| E\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ascii-reference\">ASCII Reference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ascii-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ASCII Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Referral from │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ colleague or │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ conference │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ / (Homepage) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Quick scan: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"What is this?\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Who is it for?\"│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────┐ ┌────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /journey │ │ /pricing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ See the │ │ Jump to │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ methodology│ │ enterprise │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────┬──────┘ └─────┬──────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"I get it\" │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Now eval │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ for team │────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────┬──────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /product/ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ enterprise │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Features │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Security docs │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Deployment guide│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Pricing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Questions: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • SSO/Security? │ → Documentation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • Data hosting? │ → \"Your Azure, your data\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • Deployment? │ → 1-click ARM template\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • Need help? │ → Your LSS/IT consultants can assist\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────┐ ┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ SELF-SERVE │ │ NEED HELP? │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Purchase │ │ Your existing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ online │ │ consultants │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Deploy │ │ can deploy it │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────┘ └─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ Referral from ││ colleague or ││ conference │└────────┬────────┘ │ ▼┌─────────────────┐│ / (Homepage) ││ ││ Quick scan: ││ "What is this?" ││ "Who is it for?"│└────────┬────────┘ │ ┌────┴────────────┐ │ │ ▼ ▼┌────────────┐ ┌────────────┐│ /journey │ │ /pricing ││ │ │ ││ See the │ │ Jump to ││ methodology│ │ enterprise │└─────┬──────┘ └─────┬──────┘ │ │ ▼ │┌────────────┐ ││ "I get it" │ ││ │ ││ Now eval │ ││ for team │────────┘└─────┬──────┘ │ ▼┌─────────────────┐│ /product/ ││ enterprise ││ ││ Features ││ Security docs ││ Deployment guide││ Pricing │└────────┬────────┘ │ ▼┌─────────────────┐│ Questions: ││ ││ • SSO/Security? │ → Documentation│ • Data hosting? │ → "Your Azure, your data"│ • Deployment? │ → 1-click ARM template│ • Need help? │ → Your LSS/IT consultants can assist└────────┬────────┘ │ ┌────┴────────────────┐ │ │ ▼ ▼┌────────────┐ ┌─────────────────┐│ SELF-SERVE │ │ NEED HELP? ││ │ │ ││ Purchase │ │ Your existing ││ online │ │ consultants ││ Deploy │ │ can deploy it │└────────────┘ └─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"enterprise-page-requirements\">Enterprise Page Requirements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#enterprise-page-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Enterprise Page Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The /product/enterprise page must answer:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-security--compliance\">1. Security & Compliance\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-security--compliance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Security & Compliance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Where is data stored? → “Your Azure tenant, your data”\u003C/li>\n\u003Cli>SSO support? → Azure AD / Microsoft Entra ID\u003C/li>\n\u003Cli>Compliance? → SOC 2 considerations, GDPR\u003C/li>\n\u003Cli>Audit logs? → Azure native logging\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-deployment\">2. Deployment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-deployment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Deployment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>How to deploy? → Azure Marketplace Managed Application\u003C/li>\n\u003Cli>Time to deploy? → Minutes (Managed Application)\u003C/li>\n\u003Cli>Who deploys? → Azure Marketplace handles it\u003C/li>\n\u003Cli>Updates? → Automatic via Azure\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-pricing\">3. Pricing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-pricing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Pricing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>From €99/month (Standard) or €299/month (Team) — unlimited users in your tenant\u003C/li>\n\u003Cli>No per-user fees, no hidden costs\u003C/li>\n\u003Cli>Two plans: Standard (local analysis) or Team (+ Teams, OneDrive, mobile)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-support\">4. Support\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Support”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Documentation-first\u003C/li>\n\u003Cli>Email support (\u003Ca href=\"mailto:support@rdmaic.com\">support@rdmaic.com\u003C/a>)\u003C/li>\n\u003Cli>“Your existing LSS/IT consultants can assist”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"self-serve-enterprise-model\">Self-Serve Enterprise Model\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#self-serve-enterprise-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Self-Serve Enterprise Model”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Key principle: \u003Cstrong>No sales calls required\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Step\u003C/th>\u003Cth>How It Works\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Discover\u003C/td>\u003Ctd>Website, referral, content\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluate\u003C/td>\u003Ctd>PWA (free), documentation, case studies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Purchase\u003C/td>\u003Ctd>Azure Marketplace (from €99/month, unlimited users)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Deploy\u003C/td>\u003Ctd>Managed Application (automatic)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Support\u003C/td>\u003Ctd>Documentation + email (\u003Ca href=\"mailto:support@rdmaic.com\">support@rdmaic.com\u003C/a>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Implementation\u003C/td>\u003Ctd>Your existing consultants can help\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ctas-on-this-journey\">CTAs on This Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ctas-on-this-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CTAs on This Journey”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Location\u003C/th>\u003Cth>CTA Text\u003C/th>\u003Cth>Destination\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Homepage\u003C/td>\u003Ctd>”For Teams” or “Enterprise”\u003C/td>\u003Ctd>/product/enterprise\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Journey page\u003C/td>\u003Ctd>”Deploy for your team”\u003C/td>\u003Ctd>/product/enterprise\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pricing page\u003C/td>\u003Ctd>”Enterprise details”\u003C/td>\u003Ctd>/product/enterprise\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Enterprise page\u003C/td>\u003Ctd>”Deploy Now” (Marketplace link)\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Enterprise page\u003C/td>\u003Ctd>”Get Started” (deployment guide)\u003C/td>\u003Ctd>/getting-started\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"information-olivia-needs\">Information Olivia Needs\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#information-olivia-needs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Information Olivia Needs”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Question\u003C/th>\u003Cth>Answer Location\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>What does it do?\u003C/td>\u003Ctd>/journey, /tools\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Is it secure?\u003C/td>\u003Ctd>/product/enterprise\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Where’s my data?\u003C/td>\u003Ctd>/product/enterprise\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>How much does it cost?\u003C/td>\u003Ctd>/pricing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>How do I deploy?\u003C/td>\u003Ctd>/getting-started\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Who supports it?\u003C/td>\u003Ctd>\u003Ca href=\"mailto:support@rdmaic.com\">support@rdmaic.com\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Can I try it first?\u003C/td>\u003Ctd>/app (free, permanently)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>What training is available?\u003C/td>\u003Ctd>Link to RDMAIC training\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"evaluator-erik-secondary\">Evaluator Erik (Secondary)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#evaluator-erik-secondary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Evaluator Erik (Secondary)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>IT/Procurement evaluator may also be involved:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Erik’s Questions\u003C/th>\u003Cth>Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Security architecture?\u003C/td>\u003Ctd>Azure-native, your tenant\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data residency?\u003C/td>\u003Ctd>Your choice of Azure region\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Authentication?\u003C/td>\u003Ctd>Azure AD SSO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Compliance certifications?\u003C/td>\u003Ctd>Azure compliance + our docs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SLA?\u003C/td>\u003Ctd>Azure SLA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Exit strategy?\u003C/td>\u003Ctd>Export all data, standard formats\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"mobile-considerations\">Mobile Considerations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Enterprise page should work on mobile (conference scanning)\u003C/li>\n\u003Cli>Key info visible without deep scrolling\u003C/li>\n\u003Cli>Easy path to schedule demo or download docs\u003C/li>\n\u003Cli>QR codes on printed materials\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Homepage → Enterprise page\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Enterprise page → Deployment\u003C/td>\u003Ctd>>5%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Enterprise page → Contact\u003C/td>\u003Ctd>>2%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ARM template downloads\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Time to purchase (first visit)\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"after-purchase-in-app-journeys\">After Purchase: In-App Journeys\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#after-purchase-in-app-journeys\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “After Purchase: In-App Journeys”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Once Olivia’s team deploys via Azure Marketplace, the journey continues in-app:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Next Flow\u003C/th>\u003Cth>Who\u003C/th>\u003Cth>What happens\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"azure-first-analysis.md\">Azure First Analysis\u003C/a>\u003C/td>\u003Ctd>Gary (end user)\u003C/td>\u003Ctd>First login → SSO → empty state → first chart in < 3 min\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"azure-daily-use.md\">Azure Daily Use\u003C/a>\u003C/td>\u003Ctd>Gary (daily user)\u003C/td>\u003Ctd>Repeat analysis, Performance Mode, exports\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"azure-team-collaboration.md\">Azure Team Collaboration\u003C/a>\u003C/td>\u003Ctd>Olivia (admin)\u003C/td>\u003Ctd>Teams setup, sharing, onboarding colleagues\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Users who tried the \u003Ca href=\"return-visitor.md\">PWA\u003C/a> before purchasing will find the same analysis workflow — skills transfer directly. The key differences are persistence (IndexedDB on Standard; + OneDrive sync on Team plan), file upload, Performance Mode, and 6-factor support.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"gap-enterprise-page-content-needed\">Gap: Enterprise Page Content Needed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#gap-enterprise-page-content-needed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Gap: Enterprise Page Content Needed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status:\u003C/strong> Content pending — the \u003Ccode dir=\"auto\">/product/enterprise\u003C/code> website page does not yet exist. Journey flows currently route to this page, but visitors will land on a generic product page.\u003C/p>\n\u003Cp>The enterprise page needs:\u003C/p>\n\u003Cul>\n\u003Cli>Full security documentation (data residency, encryption, compliance)\u003C/li>\n\u003Cli>Deployment guide with screenshots\u003C/li>\n\u003Cli>Pricing calculator\u003C/li>\n\u003Cli>FAQ for IT/Procurement\u003C/li>\n\u003Cli>Customer logos / testimonials (when available)\u003C/li>\n\u003C/ul>\n\u003Cp>Until this page is built, the \u003Ca href=\"../../08-products/azure/how-it-works.md\">How It Works\u003C/a> doc covers the technical architecture, and the \u003Ca href=\"../../08-products/azure/marketplace.md\">Marketplace Guide\u003C/a> covers deployment.\u003C/p>", + { + "headings": 4361, + "localImagePaths": 4413, + "remoteImagePaths": 4414, + "frontmatter": 4415, + "imagePaths": 4416 + }, + [ + 4362, 4364, 4367, 4368, 4369, 4370, 4371, 4374, 4377, 4378, 4381, 4384, 4387, 4390, 4393, 4396, + 4399, 4402, 4405, 4406, 4407, 4410 + ], + { "depth": 30, "slug": 4363, "text": 4351 }, + "flow-4-enterprise-evaluator", + { "depth": 33, "slug": 4365, "text": 4366 }, + "persona-opex-olivia", + "Persona: OpEx Olivia", + { "depth": 79, "slug": 4192, "text": 4193 }, + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 79, "slug": 4078, "text": 4079 }, + { "depth": 79, "slug": 4372, "text": 4373 }, + "enterprise-evaluation-journey", + "Enterprise Evaluation Journey", + { "depth": 79, "slug": 4375, "text": 4376 }, + "self-serve-model", + "Self-Serve Model", + { "depth": 79, "slug": 919, "text": 920 }, + { "depth": 33, "slug": 4379, "text": 4380 }, + "enterprise-page-requirements", + "Enterprise Page Requirements", + { "depth": 79, "slug": 4382, "text": 4383 }, + "1-security--compliance", + "1. Security & Compliance", + { "depth": 79, "slug": 4385, "text": 4386 }, + "2-deployment", + "2. Deployment", + { "depth": 79, "slug": 4388, "text": 4389 }, + "3-pricing", + "3. Pricing", + { "depth": 79, "slug": 4391, "text": 4392 }, + "4-support", + "4. Support", + { "depth": 33, "slug": 4394, "text": 4395 }, + "self-serve-enterprise-model", + "Self-Serve Enterprise Model", + { "depth": 33, "slug": 4397, "text": 4398 }, + "ctas-on-this-journey", + "CTAs on This Journey", + { "depth": 33, "slug": 4400, "text": 4401 }, + "information-olivia-needs", + "Information Olivia Needs", + { "depth": 33, "slug": 4403, "text": 4404 }, + "evaluator-erik-secondary", + "Evaluator Erik (Secondary)", + { "depth": 33, "slug": 4335, "text": 4336 }, + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4408, "text": 4409 }, + "after-purchase-in-app-journeys", + "After Purchase: In-App Journeys", + { "depth": 33, "slug": 4411, "text": 4412 }, + "gap-enterprise-page-content-needed", + "Gap: Enterprise Page Content Needed", + [], + [], + { "title": 4351 }, + [], + "02-journeys/flows/return-visitor", + { "id": 4417, "data": 4419, "body": 4424, "filePath": 4425, "digest": 4426, "rendered": 4427 }, + { + "title": 4420, + "editUrl": 16, + "head": 4421, + "template": 18, + "sidebar": 4422, + "pagefind": 16, + "draft": 20 + }, + "Flow 5: Return Visitor → App", + [], + { "hidden": 20, "attrs": 4423 }, + {}, + "# Flow 5: Return Visitor → App\n\n> Existing user returns to use VaRiScout\n>\n> **Priority:** Medium - retention/activation\n>\n> See also: [Journeys Overview](../index.md) for site architecture\n\n---\n\n## Persona: Return Visitor\n\n| Attribute | Detail |\n| --------------- | --------------------------------- |\n| **Role** | Any previous user |\n| **Goal** | Use VaRiScout with their data |\n| **Knowledge** | Already knows what VaRiScout is |\n| **Entry point** | Bookmark, direct URL, or homepage |\n| **Need** | Quick access, no friction |\n\n### What they're thinking:\n\n- \"I need to analyze this data\"\n- \"Where's the app again?\"\n- \"Did my previous work save?\"\n\n---\n\n## Entry Points\n\n| Source | URL | Intent |\n| ------------------- | --------- | --------------- |\n| Bookmark (ideal) | /app | Direct to PWA |\n| Bookmark (homepage) | / | Navigate to app |\n| Browser history | / or /app | Return to work |\n\n---\n\n## Journey Flow\n\n### Mermaid Flowchart\n\n```mermaid\nflowchart TD\n A[Direct URL or Bookmark] --> B{Entry Point}\n B -->|Direct| C[/app - PWA loads]\n B -->|Homepage| D[/ Homepage]\n D --> E[Clicks Try VaRiScout]\n E --> C\n C --> F{Platform?}\n F -->|Azure App| G[Previous analyses restored]\n F -->|PWA| H[Fresh start — paste or sample]\n G --> I[Continue working]\n H --> I\n```\n\n### Return Visitor Scenarios\n\n```mermaid\nflowchart LR\n subgraph Scenario A [Bookmarked /app]\n A1[Navigate to bookmark] --> A2[App loads]\n A2 --> A3{Platform?}\n A3 -->|Azure| A4[Previous work restored]\n A3 -->|PWA| A5[Fresh start]\n end\n\n subgraph Scenario B [Homepage First]\n B1[Go to variscout.com] --> B2[Click Try VaRiScout] --> B3[PWA loads]\n end\n\n subgraph Scenario C [New Device / Session]\n C1[New device or tab] --> C2{Platform?}\n C2 -->|Azure| C3[SSO → analyses from OneDrive]\n C2 -->|PWA| C4[Fresh start — paste or sample]\n end\n```\n\n### User Satisfaction Journey\n\n```mermaid\njourney\n title Return Visitor Journey\n section Return\n Navigate to bookmark: 5: User\n Or go to homepage: 4: User\n section Recognition\n Site looks familiar: 5: User\n Find Try VaRiScout: 5: User\n section Continuity\n Azure: previous work restored: 5: User\n PWA: paste data or load sample: 4: User\n section Work\n Analyze new data: 5: User\n Export results: 5: User\n```\n\n### ASCII Reference\n\n```\n┌─────────────────┐\n│ Direct URL or │\n│ Bookmark │\n└────────┬────────┘\n │\n ┌────┴────┐\n │ │\n ▼ ▼\n┌────────┐ ┌─────────────────┐\n│ /app │ │ / (Homepage) │\n│ │ │ │\n│ Direct │ │ \"I know what │\n│ to PWA │ │ this is\" │\n└────────┘ └────────┬────────┘\n │\n ▼\n ┌─────────────────┐\n │ Clicks: │\n │ │\n │ [Try VaRiScout] │\n └────────┬────────┘\n │\n ▼\n ┌─────────────────┐\n │ /app loads │\n │ │\n │ Azure: previous │\n │ work restored │\n │ PWA: fresh start│\n └─────────────────┘\n```\n\n---\n\n## Key Design Principles\n\n### 1. No Login Required\n\nVaRiScout is 100% client-side:\n\n- Auth state stored locally (EasyAuth for Azure App)\n- Data stored in IndexedDB\n- No server-side accounts\n- \"We don't have your data\" (GDPR simple)\n\n### 2. Fast Access from Homepage\n\nHeader CTA always visible:\n\n```\n[Logo: VaRiScout] Journey Cases Tools ▼ Learn ▼ Pricing [Try VaRiScout]\n```\n\nReturn visitors click [Try VaRiScout] → straight to /app\n\n---\n\n## Data Persistence\n\n### PWA (Session-Only)\n\nThe PWA does **not** persist data between sessions. Closing the browser tab loses all work. This is by design — the PWA is a free training tool, not a production environment.\n\n| What's Available | Where | Retention |\n| -------------------- | ----------------- | ----------------------------------- |\n| Current analysis | In-memory (React) | Current session only |\n| Theme preference | localStorage | Persists across sessions |\n| Service Worker cache | Cache API | App loads offline after first visit |\n\nUsers who need persistence should use the [Azure App](azure-daily-use.md).\n\n### Azure App\n\n| What's Saved | Where | Retention |\n| ----------------- | --------------- | ------------- |\n| Auth session | EasyAuth/cookie | Until cleared |\n| Saved analyses | IndexedDB | Until deleted |\n| Analysis settings | IndexedDB | Per dataset |\n| Cloud backup | OneDrive | User-managed |\n\nSee [Azure Daily Use](azure-daily-use.md) for the Azure return experience.\n\n---\n\n## Return User Scenarios\n\n### Scenario A: Bookmarked /app\n\n1. User navigates to bookmark\n2. App loads immediately\n3. **Azure App:** Previous analyses restored from IndexedDB\n4. **PWA:** Fresh start — paste data or load a sample\n5. Continue working\n\n### Scenario B: Homepage First\n\n1. User goes to variscout.com\n2. Sees familiar homepage\n3. Clicks [Try VaRiScout]\n4. **Azure App:** Previous work restored. **PWA:** Fresh start.\n\n### Scenario C: New Device / New Session\n\n1. User goes to variscout.com on new device (or returns after closing the tab)\n2. **Azure App:** Signs in via SSO — saved analyses load from OneDrive\n3. **PWA:** Fresh start — no previous data (session-only, no persistence)\n4. PWA users paste data or load a sample to begin again\n\n---\n\n## Navigation for Return Visitors\n\nThe header is the same for everyone:\n\n```\n[Logo] Journey Cases Tools ▼ Learn ▼ Pricing [Try VaRiScout]\n```\n\nBut return visitors:\n\n- Ignore most navigation\n- Go straight to [Try VaRiScout]\n- May check /cases for new content\n- May check /pricing for upgrade\n\n---\n\n## Upgrade Path\n\nFor free tier users returning:\n\n| Trigger | Prompt |\n| -------------------- | ---------------------------------------------- |\n| File upload attempt | \"Upload files with Azure App — from €99/month\" |\n| Save/project attempt | \"Save projects with Azure App\" |\n| Performance Mode | \"Performance Mode available in Azure App\" |\n\nUpgrade prompts should be helpful, not blocking.\n\n---\n\n## CTAs for Return Visitors\n\n| Location | CTA | Purpose |\n| ------------------ | ----------------- | ------------- |\n| Header (all pages) | [Try VaRiScout] | Direct to app |\n| PWA (free) | [Try Azure App] | Conversion |\n| Cases (new) | \"New case study!\" | Re-engagement |\n| Blog (new) | \"New content\" | Re-engagement |\n\n---\n\n## Mobile Considerations\n\n- Mobile bookmark works same as desktop\n- Data syncs locally only (no cloud)\n- Touch-optimized app experience\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ----------------------------- | ------ |\n| Return visitor → /app | >80% |\n| Session frequency (returners) | Track |\n| Free → Paid conversion | >5% |\n| Data retention (IndexedDB) | Verify |\n\n---\n\n## Azure App Return Experience\n\nAzure App return visitors have a fundamentally different experience from PWA users — SSO, saved analyses, and OneDrive sync.\n\nFor the full Azure return workflow, see [Azure Daily Use](azure-daily-use.md). Key differences:\n\n| Aspect | PWA Return | Azure App Return |\n| --------------- | ---------------------------- | ---------------------------------------- |\n| Authentication | None | SSO auto-login (EasyAuth session cookie) |\n| Previous work | Lost (session-only) | Loads from IndexedDB / OneDrive |\n| Data input | Paste, manual entry, samples | Upload, paste, manual entry, samples |\n| Upgrade prompts | Yes (at capability limits) | N/A (full features) |\n\n---\n\n## Free-to-Paid Upgrade Journey\n\nPWA users hit natural capability limits that signal readiness for the Azure App. The upgrade path should feel helpful, not blocking.\n\n### Upgrade Triggers\n\n| Trigger | What happens | Upgrade message |\n| ------------------------- | ------------------------------------ | -------------------------------------------- |\n| Performance Mode detected | Modal appears, dismisses immediately | \"Performance Mode is available in Azure App\" |\n| Factor limit (3) reached | ColumnMapping caps at 3 factors | \"Analyze up to 6 factors with Azure App\" |\n| File upload attempted | Not available in PWA | \"Upload files with Azure App\" |\n| Session data loss | User returns, data is gone | \"Save and sync with Azure App\" |\n\n### Conversion Path\n\n```\nPWA user hits limit → sees upgrade context → visits website /pricing → Azure Marketplace → deploys\n```\n\nThe `HomeScreen` (`apps/pwa/src/components/HomeScreen.tsx`) includes a subtle \"Need team features?\" link to the website, reinforcing that the Azure App exists without interrupting the free training experience.\n\n---\n\n## Technical Notes\n\n### Storage by Platform\n\n**PWA:** Session-only — all analysis data lives in React state. Closing the tab loses everything. Theme preference persists via localStorage.\n\n**Azure App:** IndexedDB for local persistence, OneDrive for cloud sync. Auth tokens managed by EasyAuth (platform-level). Clear browser data = lose local cache, but OneDrive backup remains.\n\n### No Account Migration Needed\n\nSince there are no accounts:\n\n- New device = fresh start (Azure App: sign in via SSO; PWA: paste data fresh)\n- No \"forgot password\" flow\n- No email verification\n- Privacy-friendly design", + "src/content/docs/02-journeys/flows/return-visitor.md", + "cf4a492584dbac6d", + { "html": 4428, "metadata": 4429 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"flow-5-return-visitor--app\">Flow 5: Return Visitor → App\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#flow-5-return-visitor--app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 5: Return Visitor → App”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Existing user returns to use VaRiScout\u003C/p>\n\u003Cp>\u003Cstrong>Priority:\u003C/strong> Medium - retention/activation\u003C/p>\n\u003Cp>See also: \u003Ca href=\"../index.md\">Journeys Overview\u003C/a> for site architecture\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-return-visitor\">Persona: Return Visitor\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-return-visitor\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona: Return Visitor”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Any previous user\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Use VaRiScout with their data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Already knows what VaRiScout is\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Entry point\u003C/strong>\u003C/td>\u003Ctd>Bookmark, direct URL, or homepage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Need\u003C/strong>\u003C/td>\u003Ctd>Quick access, no friction\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-theyre-thinking\">What they’re thinking:\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-theyre-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What they’re thinking:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“I need to analyze this data”\u003C/li>\n\u003Cli>“Where’s the app again?”\u003C/li>\n\u003Cli>“Did my previous work save?”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Source\u003C/th>\u003Cth>URL\u003C/th>\u003Cth>Intent\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Bookmark (ideal)\u003C/td>\u003Ctd>/app\u003C/td>\u003Ctd>Direct to PWA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Bookmark (homepage)\u003C/td>\u003Ctd>/\u003C/td>\u003Ctd>Navigate to app\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Browser history\u003C/td>\u003Ctd>/ or /app\u003C/td>\u003Ctd>Return to work\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mermaid-flowchart\">Mermaid Flowchart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mermaid-flowchart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mermaid Flowchart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Direct URL or Bookmark] --> B{Entry Point}\n B -->|Direct| C[/app - PWA loads]\n B -->|Homepage| D[/ Homepage]\n D --> E[Clicks Try VaRiScout]\n E --> C\n C --> F{Platform?}\n F -->|Azure App| G[Previous analyses restored]\n F -->|PWA| H[Fresh start — paste or sample]\n G --> I[Continue working]\n H --> I\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"return-visitor-scenarios\">Return Visitor Scenarios\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#return-visitor-scenarios\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Return Visitor Scenarios”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n subgraph Scenario A [Bookmarked /app]\n A1[Navigate to bookmark] --> A2[App loads]\n A2 --> A3{Platform?}\n A3 -->|Azure| A4[Previous work restored]\n A3 -->|PWA| A5[Fresh start]\n end\n\n subgraph Scenario B [Homepage First]\n B1[Go to variscout.com] --> B2[Click Try VaRiScout] --> B3[PWA loads]\n end\n\n subgraph Scenario C [New Device / Session]\n C1[New device or tab] --> C2{Platform?}\n C2 -->|Azure| C3[SSO → analyses from OneDrive]\n C2 -->|PWA| C4[Fresh start — paste or sample]\n end\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-satisfaction-journey\">User Satisfaction Journey\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-satisfaction-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Satisfaction Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Return Visitor Journey\n section Return\n Navigate to bookmark: 5: User\n Or go to homepage: 4: User\n section Recognition\n Site looks familiar: 5: User\n Find Try VaRiScout: 5: User\n section Continuity\n Azure: previous work restored: 5: User\n PWA: paste data or load sample: 4: User\n section Work\n Analyze new data: 5: User\n Export results: 5: User\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ascii-reference\">ASCII Reference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ascii-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ASCII Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Direct URL or │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Bookmark │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────┐ ┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /app │ │ / (Homepage) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Direct │ │ \"I know what │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ to PWA │ │ this is\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┘ └────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Clicks: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Try VaRiScout] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /app loads │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Azure: previous │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ work restored │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ PWA: fresh start│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ Direct URL or ││ Bookmark │└────────┬────────┘ │ ┌────┴────┐ │ │ ▼ ▼┌────────┐ ┌─────────────────┐│ /app │ │ / (Homepage) ││ │ │ ││ Direct │ │ "I know what ││ to PWA │ │ this is" │└────────┘ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Clicks: │ │ │ │ [Try VaRiScout] │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ /app loads │ │ │ │ Azure: previous │ │ work restored │ │ PWA: fresh start│ └─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-design-principles\">Key Design Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-design-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Design Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-no-login-required\">1. No Login Required\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-no-login-required\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. No Login Required”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VaRiScout is 100% client-side:\u003C/p>\n\u003Cul>\n\u003Cli>Auth state stored locally (EasyAuth for Azure App)\u003C/li>\n\u003Cli>Data stored in IndexedDB\u003C/li>\n\u003Cli>No server-side accounts\u003C/li>\n\u003Cli>“We don’t have your data” (GDPR simple)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-fast-access-from-homepage\">2. Fast Access from Homepage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-fast-access-from-homepage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Fast Access from Homepage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Header CTA always visible:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Logo: VaRiScout] Journey Cases Tools ▼ Learn ▼ Pricing [Try VaRiScout]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Logo: VaRiScout] Journey Cases Tools ▼ Learn ▼ Pricing [Try VaRiScout]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Return visitors click [Try VaRiScout] → straight to /app\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-persistence\">Data Persistence\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-persistence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Persistence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-session-only\">PWA (Session-Only)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-session-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA (Session-Only)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA does \u003Cstrong>not\u003C/strong> persist data between sessions. Closing the browser tab loses all work. This is by design — the PWA is a free training tool, not a production environment.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>What’s Available\u003C/th>\u003Cth>Where\u003C/th>\u003Cth>Retention\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Current analysis\u003C/td>\u003Ctd>In-memory (React)\u003C/td>\u003Ctd>Current session only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Theme preference\u003C/td>\u003Ctd>localStorage\u003C/td>\u003Ctd>Persists across sessions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Service Worker cache\u003C/td>\u003Ctd>Cache API\u003C/td>\u003Ctd>App loads offline after first visit\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Users who need persistence should use the \u003Ca href=\"azure-daily-use.md\">Azure App\u003C/a>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-app\">Azure App\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>What’s Saved\u003C/th>\u003Cth>Where\u003C/th>\u003Cth>Retention\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Auth session\u003C/td>\u003Ctd>EasyAuth/cookie\u003C/td>\u003Ctd>Until cleared\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Saved analyses\u003C/td>\u003Ctd>IndexedDB\u003C/td>\u003Ctd>Until deleted\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analysis settings\u003C/td>\u003Ctd>IndexedDB\u003C/td>\u003Ctd>Per dataset\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cloud backup\u003C/td>\u003Ctd>OneDrive\u003C/td>\u003Ctd>User-managed\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"azure-daily-use.md\">Azure Daily Use\u003C/a> for the Azure return experience.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"return-user-scenarios\">Return User Scenarios\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#return-user-scenarios\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Return User Scenarios”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"scenario-a-bookmarked-app\">Scenario A: Bookmarked /app\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#scenario-a-bookmarked-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario A: Bookmarked /app”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>User navigates to bookmark\u003C/li>\n\u003Cli>App loads immediately\u003C/li>\n\u003Cli>\u003Cstrong>Azure App:\u003C/strong> Previous analyses restored from IndexedDB\u003C/li>\n\u003Cli>\u003Cstrong>PWA:\u003C/strong> Fresh start — paste data or load a sample\u003C/li>\n\u003Cli>Continue working\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"scenario-b-homepage-first\">Scenario B: Homepage First\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#scenario-b-homepage-first\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario B: Homepage First”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>User goes to variscout.com\u003C/li>\n\u003Cli>Sees familiar homepage\u003C/li>\n\u003Cli>Clicks [Try VaRiScout]\u003C/li>\n\u003Cli>\u003Cstrong>Azure App:\u003C/strong> Previous work restored. \u003Cstrong>PWA:\u003C/strong> Fresh start.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"scenario-c-new-device--new-session\">Scenario C: New Device / New Session\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#scenario-c-new-device--new-session\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario C: New Device / New Session”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>User goes to variscout.com on new device (or returns after closing the tab)\u003C/li>\n\u003Cli>\u003Cstrong>Azure App:\u003C/strong> Signs in via SSO — saved analyses load from OneDrive\u003C/li>\n\u003Cli>\u003Cstrong>PWA:\u003C/strong> Fresh start — no previous data (session-only, no persistence)\u003C/li>\n\u003Cli>PWA users paste data or load a sample to begin again\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"navigation-for-return-visitors\">Navigation for Return Visitors\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#navigation-for-return-visitors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Navigation for Return Visitors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The header is the same for everyone:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Logo] Journey Cases Tools ▼ Learn ▼ Pricing [Try VaRiScout]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Logo] Journey Cases Tools ▼ Learn ▼ Pricing [Try VaRiScout]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>But return visitors:\u003C/p>\n\u003Cul>\n\u003Cli>Ignore most navigation\u003C/li>\n\u003Cli>Go straight to [Try VaRiScout]\u003C/li>\n\u003Cli>May check /cases for new content\u003C/li>\n\u003Cli>May check /pricing for upgrade\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"upgrade-path\">Upgrade Path\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#upgrade-path\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Upgrade Path”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For free tier users returning:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Trigger\u003C/th>\u003Cth>Prompt\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>File upload attempt\u003C/td>\u003Ctd>”Upload files with Azure App — from €99/month”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Save/project attempt\u003C/td>\u003Ctd>”Save projects with Azure App”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>”Performance Mode available in Azure App”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Upgrade prompts should be helpful, not blocking.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ctas-for-return-visitors\">CTAs for Return Visitors\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ctas-for-return-visitors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CTAs for Return Visitors”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Location\u003C/th>\u003Cth>CTA\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Header (all pages)\u003C/td>\u003Ctd>[Try VaRiScout]\u003C/td>\u003Ctd>Direct to app\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PWA (free)\u003C/td>\u003Ctd>[Try Azure App]\u003C/td>\u003Ctd>Conversion\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cases (new)\u003C/td>\u003Ctd>“New case study!”\u003C/td>\u003Ctd>Re-engagement\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Blog (new)\u003C/td>\u003Ctd>“New content”\u003C/td>\u003Ctd>Re-engagement\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"mobile-considerations\">Mobile Considerations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Mobile bookmark works same as desktop\u003C/li>\n\u003Cli>Data syncs locally only (no cloud)\u003C/li>\n\u003Cli>Touch-optimized app experience\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Return visitor → /app\u003C/td>\u003Ctd>>80%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Session frequency (returners)\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Free → Paid conversion\u003C/td>\u003Ctd>>5%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data retention (IndexedDB)\u003C/td>\u003Ctd>Verify\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"azure-app-return-experience\">Azure App Return Experience\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-return-experience\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App Return Experience”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Azure App return visitors have a fundamentally different experience from PWA users — SSO, saved analyses, and OneDrive sync.\u003C/p>\n\u003Cp>For the full Azure return workflow, see \u003Ca href=\"azure-daily-use.md\">Azure Daily Use\u003C/a>. Key differences:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>PWA Return\u003C/th>\u003Cth>Azure App Return\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Authentication\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>SSO auto-login (EasyAuth session cookie)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Previous work\u003C/td>\u003Ctd>Lost (session-only)\u003C/td>\u003Ctd>Loads from IndexedDB / OneDrive\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data input\u003C/td>\u003Ctd>Paste, manual entry, samples\u003C/td>\u003Ctd>Upload, paste, manual entry, samples\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Upgrade prompts\u003C/td>\u003Ctd>Yes (at capability limits)\u003C/td>\u003Ctd>N/A (full features)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"free-to-paid-upgrade-journey\">Free-to-Paid Upgrade Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#free-to-paid-upgrade-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Free-to-Paid Upgrade Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>PWA users hit natural capability limits that signal readiness for the Azure App. The upgrade path should feel helpful, not blocking.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"upgrade-triggers\">Upgrade Triggers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#upgrade-triggers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Upgrade Triggers”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Trigger\u003C/th>\u003Cth>What happens\u003C/th>\u003Cth>Upgrade message\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Performance Mode detected\u003C/td>\u003Ctd>Modal appears, dismisses immediately\u003C/td>\u003Ctd>”Performance Mode is available in Azure App”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Factor limit (3) reached\u003C/td>\u003Ctd>ColumnMapping caps at 3 factors\u003C/td>\u003Ctd>”Analyze up to 6 factors with Azure App”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>File upload attempted\u003C/td>\u003Ctd>Not available in PWA\u003C/td>\u003Ctd>”Upload files with Azure App”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Session data loss\u003C/td>\u003Ctd>User returns, data is gone\u003C/td>\u003Ctd>”Save and sync with Azure App”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"conversion-path\">Conversion Path\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#conversion-path\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Conversion Path”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PWA user hits limit → sees upgrade context → visits website /pricing → Azure Marketplace → deploys\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"PWA user hits limit → sees upgrade context → visits website /pricing → Azure Marketplace → deploys\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">HomeScreen\u003C/code> (\u003Ccode dir=\"auto\">apps/pwa/src/components/HomeScreen.tsx\u003C/code>) includes a subtle “Need team features?” link to the website, reinforcing that the Azure App exists without interrupting the free training experience.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-notes\">Technical Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"storage-by-platform\">Storage by Platform\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#storage-by-platform\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Storage by Platform”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>PWA:\u003C/strong> Session-only — all analysis data lives in React state. Closing the tab loses everything. Theme preference persists via localStorage.\u003C/p>\n\u003Cp>\u003Cstrong>Azure App:\u003C/strong> IndexedDB for local persistence, OneDrive for cloud sync. Auth tokens managed by EasyAuth (platform-level). Clear browser data = lose local cache, but OneDrive backup remains.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"no-account-migration-needed\">No Account Migration Needed\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#no-account-migration-needed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “No Account Migration Needed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Since there are no accounts:\u003C/p>\n\u003Cul>\n\u003Cli>New device = fresh start (Azure App: sign in via SSO; PWA: paste data fresh)\u003C/li>\n\u003Cli>No “forgot password” flow\u003C/li>\n\u003Cli>No email verification\u003C/li>\n\u003Cli>Privacy-friendly design\u003C/li>\n\u003C/ul>", + { + "headings": 4430, + "localImagePaths": 4503, + "remoteImagePaths": 4504, + "frontmatter": 4505, + "imagePaths": 4506 + }, + [ + 4431, 4433, 4436, 4439, 4440, 4441, 4442, 4445, 4446, 4447, 4448, 4451, 4454, 4457, 4460, 4461, + 4464, 4467, 4470, 4473, 4476, 4479, 4482, 4483, 4484, 4487, 4490, 4493, 4496, 4497, 4500 + ], + { "depth": 30, "slug": 4432, "text": 4420 }, + "flow-5-return-visitor--app", + { "depth": 33, "slug": 4434, "text": 4435 }, + "persona-return-visitor", + "Persona: Return Visitor", + { "depth": 79, "slug": 4437, "text": 4438 }, + "what-theyre-thinking", + "What they’re thinking:", + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 79, "slug": 4078, "text": 4079 }, + { "depth": 79, "slug": 4443, "text": 4444 }, + "return-visitor-scenarios", + "Return Visitor Scenarios", + { "depth": 79, "slug": 4316, "text": 4317 }, + { "depth": 79, "slug": 919, "text": 920 }, + { "depth": 33, "slug": 4281, "text": 4282 }, + { "depth": 79, "slug": 4449, "text": 4450 }, + "1-no-login-required", + "1. No Login Required", + { "depth": 79, "slug": 4452, "text": 4453 }, + "2-fast-access-from-homepage", + "2. Fast Access from Homepage", + { "depth": 33, "slug": 4455, "text": 4456 }, + "data-persistence", + "Data Persistence", + { "depth": 79, "slug": 4458, "text": 4459 }, + "pwa-session-only", + "PWA (Session-Only)", + { "depth": 79, "slug": 1517, "text": 1518 }, + { "depth": 33, "slug": 4462, "text": 4463 }, + "return-user-scenarios", + "Return User Scenarios", + { "depth": 79, "slug": 4465, "text": 4466 }, + "scenario-a-bookmarked-app", + "Scenario A: Bookmarked /app", + { "depth": 79, "slug": 4468, "text": 4469 }, + "scenario-b-homepage-first", + "Scenario B: Homepage First", + { "depth": 79, "slug": 4471, "text": 4472 }, + "scenario-c-new-device--new-session", + "Scenario C: New Device / New Session", + { "depth": 33, "slug": 4474, "text": 4475 }, + "navigation-for-return-visitors", + "Navigation for Return Visitors", + { "depth": 33, "slug": 4477, "text": 4478 }, + "upgrade-path", + "Upgrade Path", + { "depth": 33, "slug": 4480, "text": 4481 }, + "ctas-for-return-visitors", + "CTAs for Return Visitors", + { "depth": 33, "slug": 4335, "text": 4336 }, + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4485, "text": 4486 }, + "azure-app-return-experience", + "Azure App Return Experience", + { "depth": 33, "slug": 4488, "text": 4489 }, + "free-to-paid-upgrade-journey", + "Free-to-Paid Upgrade Journey", + { "depth": 79, "slug": 4491, "text": 4492 }, + "upgrade-triggers", + "Upgrade Triggers", + { "depth": 79, "slug": 4494, "text": 4495 }, + "conversion-path", + "Conversion Path", + { "depth": 33, "slug": 3312, "text": 3313 }, + { "depth": 79, "slug": 4498, "text": 4499 }, + "storage-by-platform", + "Storage by Platform", + { "depth": 79, "slug": 4501, "text": 4502 }, + "no-account-migration-needed", + "No Account Migration Needed", + [], + [], + { "title": 4420 }, + [], + "02-journeys/flows/seo-learner", + { "id": 4507, "data": 4509, "body": 4514, "filePath": 4515, "digest": 4516, "rendered": 4517 }, + { + "title": 4510, + "editUrl": 16, + "head": 4511, + "template": 18, + "sidebar": 4512, + "pagefind": 16, + "draft": 20 + }, + "Flow 1: SEO Learner → Product", + [], + { "hidden": 20, "attrs": 4513 }, + {}, + "# Flow 1: SEO Learner → Product\n\n> Green Belt Gary searches Google, finds a tool page, discovers VaRiScout\n>\n> **Priority:** Highest - largest volume potential\n>\n> See also: [Journeys Overview](../index.md) for site architecture\n\n---\n\n## Persona: Green Belt Gary\n\n| Attribute | Detail |\n| ----------------- | --------------------------------------------- |\n| **Role** | Quality Engineer, Green Belt certified |\n| **Goal** | Find better tools than Excel |\n| **Knowledge** | Knows basics, wants efficiency |\n| **Pain points** | Excel is tedious, Minitab is expensive |\n| **Entry points** | Google search, LinkedIn, YouTube |\n| **Decision mode** | Evaluates tool capability, ease of use, price |\n\n### What Gary is thinking:\n\n- \"I need to create a control chart but Excel is painful\"\n- \"Minitab costs too much for what I need\"\n- \"I just want something that works for basic SPC\"\n\n---\n\n## Entry Points\n\n| Search Query | Lands On | Intent |\n| ------------------------------ | ----------------- | ------------------------- |\n| \"how to read control chart\" | /tools/i-chart | Learning + tool discovery |\n| \"boxplot interpretation\" | /tools/boxplot | Specific tool help |\n| \"capability analysis tutorial\" | /tools/capability | Learning Cp/Cpk |\n| \"free control chart software\" | /tools/i-chart | Tool shopping |\n| \"Minitab alternative\" | / or /pricing | Direct comparison |\n\n---\n\n## Journey Flow\n\n### Mermaid Flowchart\n\n```mermaid\nflowchart TD\n A[Google Search\u003Cbr/>'how to read control chart'] --> B[/tools/i-chart]\n B --> C{User Action}\n C -->|Scrolls| D[Sees patterns section]\n C -->|Clicks demo| E[Try It Demo]\n D --> F[Two Mindsets\u003Cbr/>Resonates with EDA]\n E --> G[I like this!\u003Cbr/>Clicks CTA]\n F --> H[/pricing]\n G --> H\n H --> I[Evaluates options]\n I --> J[CONVERSION\u003Cbr/>PWA or Azure App]\n```\n\n### User Satisfaction Journey\n\n```mermaid\njourney\n title SEO Learner Journey\n section Discovery\n Google search: 4: User\n Find tool page: 5: User\n section Exploration\n Read explanation: 4: User\n Try interactive demo: 5: User\n section Understanding\n Two Mindsets resonates: 5: User\n See workflow possibilities: 4: User\n section Decision\n Check pricing: 4: User\n Compare to alternatives: 4: User\n section Adoption\n Start with PWA demo: 5: User\n Purchase Azure App: 5: User\n```\n\n### ASCII Reference\n\n```\n┌─────────────────┐\n│ Google Search │\n│ \"how to read │\n│ control chart\" │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ /tools/i-chart │\n│ │\n│ ✓ Answers query │\n│ ✓ Visual first │\n│ ✓ Data needed │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐ ┌─────────────────┐\n│ Scrolls down │────▶│ \"Try It\" Demo │\n│ │ │ │\n│ Sees patterns │ │ Interactive │\n│ section │ │ exploration │\n└────────┬────────┘ └────────┬────────┘\n │ │\n ▼ ▼\n┌─────────────────┐ ┌─────────────────┐\n│ \"Two Mindsets\" │ │ \"I like this!\" │\n│ │ │ │\n│ Resonates with │ │ Clicks CTA │\n│ EDA approach │ │ │\n└────────┬────────┘ └────────┬────────┘\n │ │\n └───────────┬───────────┘\n │\n ▼\n ┌─────────────────┐\n │ /pricing │\n │ │\n │ Evaluates │\n │ options │\n └────────┬────────┘\n │\n ▼\n ┌─────────────────┐\n │ CONVERSION │\n │ │\n │ Tries PWA (free)│\n │ or Azure App │\n └─────────────────┘\n```\n\n---\n\n## Page Sequence\n\n### 1. Tool Page (/tools/i-chart)\n\n**Must answer in 5 seconds:** \"Does this answer my question?\"\n\nPage structure:\n\n1. **Hero:** Interactive I-Chart with sample data\n2. **What it shows:** Clear explanation of control limits, patterns\n3. **Try it section:** Demo with pre-loaded data\n4. **Two Mindsets:** EDA vs traditional approach (resonance point)\n5. **Next steps:** Links to related tools\n\n**Key content:**\n\n- Visual explanation first, math second\n- Pattern recognition guide\n- \"Why VaRiScout is different\" section\n\n### 2. Demo Interaction\n\nGary clicks around, explores the demo:\n\n- Sees linked filtering in action\n- Notices ease of use vs Excel\n- Gets curious about other features\n\n### 3. Product/Pricing Page\n\nGary evaluates:\n\n- PWA (free) vs Azure App (from €99/month)\n- Comparison to Minitab\n\n---\n\n## CTAs on This Journey\n\n| Location | CTA Text | Destination | Note |\n| -------------- | -------------------------- | ------------------ | ------------------ |\n| Tool page hero | \"Try Demo\" | /app | Opens browser demo |\n| After demo | \"Paste Your Data\" | /app | Try with own data |\n| Two Mindsets | \"See the full methodology\" | /learn or /journey | |\n| End of page | \"Try Demo - No Signup\" | /app | Opens browser demo |\n| Related tools | \"Next: Boxplot\" | /tools/boxplot | |\n\n**Updated Journey:**\n\n1. Tool page → \"Try Demo\" → Explore with samples\n2. Like it? → \"Paste Your Data\" → Try with own data (free)\n3. Need team features? → Azure App (from €99/month)\n\n---\n\n## Cross-Links from Tool Pages\n\n| From | Links To | Reason |\n| -------------- | ----------------- | ---------------------------- |\n| /tools/i-chart | /tools/boxplot | \"Next: find which factor\" |\n| /tools/i-chart | /tools/capability | \"Check: does it meet specs?\" |\n| /tools/i-chart | /learn/two-voices | \"Deep dive: Two Voices\" |\n| /tools/i-chart | /cases/bottleneck | \"See it in action\" |\n\n---\n\n## Mobile Considerations\n\n- Tool demo must work on mobile (touch-optimized)\n- Sticky \"Try VaRiScout\" button at bottom\n- Simplified chart interactions\n- Key content visible without scrolling\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ---------------------------- | ------ |\n| Tool page → Demo interaction | >50% |\n| Demo → Product page | >15% |\n| Product page → Conversion | >10% |\n| Tool page bounce rate | \u003C60% |\n| Time on tool page | >90s |\n\n---\n\n## SEO Notes\n\nTarget keywords per tool page:\n\n- /tools/i-chart: \"control chart\", \"I-MR chart\", \"how to read control chart\"\n- /tools/boxplot: \"boxplot\", \"box and whisker\", \"boxplot interpretation\"\n- /tools/pareto: \"pareto chart\", \"80/20 analysis\", \"pareto diagram\"\n- /tools/capability: \"Cp Cpk\", \"capability analysis\", \"process capability\"\n\nContent structure for SEO:\n\n- H1 matches primary keyword\n- Clear answer in first paragraph\n- Visual content (charts) with alt text\n- Internal links to related content", + "src/content/docs/02-journeys/flows/seo-learner.md", + "61cf9afbd2cc83f5", + { "html": 4518, "metadata": 4519 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"flow-1-seo-learner--product\">Flow 1: SEO Learner → Product\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#flow-1-seo-learner--product\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 1: SEO Learner → Product”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Green Belt Gary searches Google, finds a tool page, discovers VaRiScout\u003C/p>\n\u003Cp>\u003Cstrong>Priority:\u003C/strong> Highest - largest volume potential\u003C/p>\n\u003Cp>See also: \u003Ca href=\"../index.md\">Journeys Overview\u003C/a> for site architecture\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-green-belt-gary\">Persona: Green Belt Gary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-green-belt-gary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona: Green Belt Gary”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Quality Engineer, Green Belt certified\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Find better tools than Excel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Knows basics, wants efficiency\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Excel is tedious, Minitab is expensive\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Entry points\u003C/strong>\u003C/td>\u003Ctd>Google search, LinkedIn, YouTube\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Evaluates tool capability, ease of use, price\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-gary-is-thinking\">What Gary is thinking:\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-gary-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Gary is thinking:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“I need to create a control chart but Excel is painful”\u003C/li>\n\u003Cli>“Minitab costs too much for what I need”\u003C/li>\n\u003Cli>“I just want something that works for basic SPC”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Search Query\u003C/th>\u003Cth>Lands On\u003C/th>\u003Cth>Intent\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”how to read control chart”\u003C/td>\u003Ctd>/tools/i-chart\u003C/td>\u003Ctd>Learning + tool discovery\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”boxplot interpretation”\u003C/td>\u003Ctd>/tools/boxplot\u003C/td>\u003Ctd>Specific tool help\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”capability analysis tutorial”\u003C/td>\u003Ctd>/tools/capability\u003C/td>\u003Ctd>Learning Cp/Cpk\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”free control chart software”\u003C/td>\u003Ctd>/tools/i-chart\u003C/td>\u003Ctd>Tool shopping\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Minitab alternative”\u003C/td>\u003Ctd>/ or /pricing\u003C/td>\u003Ctd>Direct comparison\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mermaid-flowchart\">Mermaid Flowchart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mermaid-flowchart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mermaid Flowchart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Google Search<br/>'how to read control chart'] --> B[/tools/i-chart]\n B --> C{User Action}\n C -->|Scrolls| D[Sees patterns section]\n C -->|Clicks demo| E[Try It Demo]\n D --> F[Two Mindsets<br/>Resonates with EDA]\n E --> G[I like this!<br/>Clicks CTA]\n F --> H[/pricing]\n G --> H\n H --> I[Evaluates options]\n I --> J[CONVERSION<br/>PWA or Azure App]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-satisfaction-journey\">User Satisfaction Journey\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-satisfaction-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Satisfaction Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title SEO Learner Journey\n section Discovery\n Google search: 4: User\n Find tool page: 5: User\n section Exploration\n Read explanation: 4: User\n Try interactive demo: 5: User\n section Understanding\n Two Mindsets resonates: 5: User\n See workflow possibilities: 4: User\n section Decision\n Check pricing: 4: User\n Compare to alternatives: 4: User\n section Adoption\n Start with PWA demo: 5: User\n Purchase Azure App: 5: User\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ascii-reference\">ASCII Reference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ascii-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ASCII Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Google Search │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"how to read │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ control chart\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /tools/i-chart │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ✓ Answers query │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ✓ Visual first │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ✓ Data needed │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐ ┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Scrolls down │────▶│ \"Try It\" Demo │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Sees patterns │ │ Interactive │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ section │ │ exploration │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘ └────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐ ┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Two Mindsets\" │ │ \"I like this!\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Resonates with │ │ Clicks CTA │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ EDA approach │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘ └────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───────────┬───────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /pricing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Evaluates │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ options │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CONVERSION │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Tries PWA (free)│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ or Azure App │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ Google Search ││ "how to read ││ control chart" │└────────┬────────┘ │ ▼┌─────────────────┐│ /tools/i-chart ││ ││ ✓ Answers query ││ ✓ Visual first ││ ✓ Data needed │└────────┬────────┘ │ ▼┌─────────────────┐ ┌─────────────────┐│ Scrolls down │────▶│ "Try It" Demo ││ │ │ ││ Sees patterns │ │ Interactive ││ section │ │ exploration │└────────┬────────┘ └────────┬────────┘ │ │ ▼ ▼┌─────────────────┐ ┌─────────────────┐│ "Two Mindsets" │ │ "I like this!" ││ │ │ ││ Resonates with │ │ Clicks CTA ││ EDA approach │ │ │└────────┬────────┘ └────────┬────────┘ │ │ └───────────┬───────────┘ │ ▼ ┌─────────────────┐ │ /pricing │ │ │ │ Evaluates │ │ options │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ CONVERSION │ │ │ │ Tries PWA (free)│ │ or Azure App │ └─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"page-sequence\">Page Sequence\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#page-sequence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Page Sequence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-tool-page-toolsi-chart\">1. Tool Page (/tools/i-chart)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-tool-page-toolsi-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Tool Page (/tools/i-chart)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Must answer in 5 seconds:\u003C/strong> “Does this answer my question?”\u003C/p>\n\u003Cp>Page structure:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Hero:\u003C/strong> Interactive I-Chart with sample data\u003C/li>\n\u003Cli>\u003Cstrong>What it shows:\u003C/strong> Clear explanation of control limits, patterns\u003C/li>\n\u003Cli>\u003Cstrong>Try it section:\u003C/strong> Demo with pre-loaded data\u003C/li>\n\u003Cli>\u003Cstrong>Two Mindsets:\u003C/strong> EDA vs traditional approach (resonance point)\u003C/li>\n\u003Cli>\u003Cstrong>Next steps:\u003C/strong> Links to related tools\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Key content:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Visual explanation first, math second\u003C/li>\n\u003Cli>Pattern recognition guide\u003C/li>\n\u003Cli>“Why VaRiScout is different” section\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-demo-interaction\">2. Demo Interaction\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-demo-interaction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Demo Interaction”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Gary clicks around, explores the demo:\u003C/p>\n\u003Cul>\n\u003Cli>Sees linked filtering in action\u003C/li>\n\u003Cli>Notices ease of use vs Excel\u003C/li>\n\u003Cli>Gets curious about other features\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-productpricing-page\">3. Product/Pricing Page\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-productpricing-page\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Product/Pricing Page”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Gary evaluates:\u003C/p>\n\u003Cul>\n\u003Cli>PWA (free) vs Azure App (from €99/month)\u003C/li>\n\u003Cli>Comparison to Minitab\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ctas-on-this-journey\">CTAs on This Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ctas-on-this-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CTAs on This Journey”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Location\u003C/th>\u003Cth>CTA Text\u003C/th>\u003Cth>Destination\u003C/th>\u003Cth>Note\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Tool page hero\u003C/td>\u003Ctd>”Try Demo”\u003C/td>\u003Ctd>/app\u003C/td>\u003Ctd>Opens browser demo\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>After demo\u003C/td>\u003Ctd>”Paste Your Data”\u003C/td>\u003Ctd>/app\u003C/td>\u003Ctd>Try with own data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Two Mindsets\u003C/td>\u003Ctd>”See the full methodology”\u003C/td>\u003Ctd>/learn or /journey\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>End of page\u003C/td>\u003Ctd>”Try Demo - No Signup”\u003C/td>\u003Ctd>/app\u003C/td>\u003Ctd>Opens browser demo\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Related tools\u003C/td>\u003Ctd>”Next: Boxplot”\u003C/td>\u003Ctd>/tools/boxplot\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Updated Journey:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Tool page → “Try Demo” → Explore with samples\u003C/li>\n\u003Cli>Like it? → “Paste Your Data” → Try with own data (free)\u003C/li>\n\u003Cli>Need team features? → Azure App (from €99/month)\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-links-from-tool-pages\">Cross-Links from Tool Pages\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-links-from-tool-pages\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Links from Tool Pages”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>From\u003C/th>\u003Cth>Links To\u003C/th>\u003Cth>Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>/tools/i-chart\u003C/td>\u003Ctd>/tools/boxplot\u003C/td>\u003Ctd>”Next: find which factor”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>/tools/i-chart\u003C/td>\u003Ctd>/tools/capability\u003C/td>\u003Ctd>”Check: does it meet specs?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>/tools/i-chart\u003C/td>\u003Ctd>/learn/two-voices\u003C/td>\u003Ctd>”Deep dive: Two Voices”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>/tools/i-chart\u003C/td>\u003Ctd>/cases/bottleneck\u003C/td>\u003Ctd>”See it in action”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"mobile-considerations\">Mobile Considerations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Tool demo must work on mobile (touch-optimized)\u003C/li>\n\u003Cli>Sticky “Try VaRiScout” button at bottom\u003C/li>\n\u003Cli>Simplified chart interactions\u003C/li>\n\u003Cli>Key content visible without scrolling\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Tool page → Demo interaction\u003C/td>\u003Ctd>>50%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Demo → Product page\u003C/td>\u003Ctd>>15%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Product page → Conversion\u003C/td>\u003Ctd>>10%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tool page bounce rate\u003C/td>\u003Ctd><60%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Time on tool page\u003C/td>\u003Ctd>>90s\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"seo-notes\">SEO Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#seo-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SEO Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Target keywords per tool page:\u003C/p>\n\u003Cul>\n\u003Cli>/tools/i-chart: “control chart”, “I-MR chart”, “how to read control chart”\u003C/li>\n\u003Cli>/tools/boxplot: “boxplot”, “box and whisker”, “boxplot interpretation”\u003C/li>\n\u003Cli>/tools/pareto: “pareto chart”, “80/20 analysis”, “pareto diagram”\u003C/li>\n\u003Cli>/tools/capability: “Cp Cpk”, “capability analysis”, “process capability”\u003C/li>\n\u003C/ul>\n\u003Cp>Content structure for SEO:\u003C/p>\n\u003Cul>\n\u003Cli>H1 matches primary keyword\u003C/li>\n\u003Cli>Clear answer in first paragraph\u003C/li>\n\u003Cli>Visual content (charts) with alt text\u003C/li>\n\u003Cli>Internal links to related content\u003C/li>\n\u003C/ul>", + { + "headings": 4520, + "localImagePaths": 4551, + "remoteImagePaths": 4552, + "frontmatter": 4553, + "imagePaths": 4554 + }, + [ + 4521, 4523, 4524, 4525, 4526, 4527, 4528, 4529, 4530, 4533, 4536, 4539, 4542, 4543, 4546, 4547, + 4548 + ], + { "depth": 30, "slug": 4522, "text": 4510 }, + "flow-1-seo-learner--product", + { "depth": 33, "slug": 4127, "text": 4128 }, + { "depth": 79, "slug": 4072, "text": 4073 }, + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 79, "slug": 4078, "text": 4079 }, + { "depth": 79, "slug": 4316, "text": 4317 }, + { "depth": 79, "slug": 919, "text": 920 }, + { "depth": 33, "slug": 4531, "text": 4532 }, + "page-sequence", + "Page Sequence", + { "depth": 79, "slug": 4534, "text": 4535 }, + "1-tool-page-toolsi-chart", + "1. Tool Page (/tools/i-chart)", + { "depth": 79, "slug": 4537, "text": 4538 }, + "2-demo-interaction", + "2. Demo Interaction", + { "depth": 79, "slug": 4540, "text": 4541 }, + "3-productpricing-page", + "3. Product/Pricing Page", + { "depth": 33, "slug": 4397, "text": 4398 }, + { "depth": 33, "slug": 4544, "text": 4545 }, + "cross-links-from-tool-pages", + "Cross-Links from Tool Pages", + { "depth": 33, "slug": 4335, "text": 4336 }, + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4549, "text": 4550 }, + "seo-notes", + "SEO Notes", + [], + [], + { "title": 4510 }, + [], + "02-journeys/flows/social-discovery", + { "id": 4555, "data": 4557, "body": 4562, "filePath": 4563, "digest": 4564, "rendered": 4565 }, + { + "title": 4558, + "editUrl": 16, + "head": 4559, + "template": 18, + "sidebar": 4560, + "pagefind": 16, + "draft": 20 + }, + "Flow 2: Social Discovery → Case → Product", + [], + { "hidden": 20, "attrs": 4561 }, + {}, + "# Flow 2: Social Discovery → Case → Product\n\n> Curious Carlos sees a LinkedIn post, explores a case study, discovers VaRiScout\n>\n> **Priority:** High - best conversion story\n>\n> See also: [Journeys Overview](../index.md) for site architecture\n\n---\n\n## Persona: Curious Carlos\n\n| Attribute | Detail |\n| ----------------- | --------------------------------------------- |\n| **Role** | Operations Supervisor |\n| **Goal** | Understand variation better |\n| **Knowledge** | Interested but not formally trained |\n| **Pain points** | Sees problems but lacks tools to analyze them |\n| **Entry points** | YouTube, TikTok, Instagram, LinkedIn |\n| **Decision mode** | Needs to \"see it work\" before committing |\n\n### What Carlos is thinking:\n\n- \"That post about finding 46% of problems in one place is interesting\"\n- \"I wonder if I could do something like this at my plant\"\n- \"This seems easier than the stats stuff I've seen before\"\n\n---\n\n## Entry Points\n\n| Social Source | Content Type | Lands On |\n| ------------------ | -------------------- | ----------------- |\n| LinkedIn post | Case study teaser | /cases/bottleneck |\n| LinkedIn article | \"How we found 46%\" | /cases/X |\n| Instagram carousel | Before/after visuals | /cases/X or / |\n| TikTok clip | \"Watch me find it\" | / or /tools/X |\n\n---\n\n## Journey Flow\n\n### Mermaid Flowchart\n\n```mermaid\nflowchart TD\n A[LinkedIn Post\u003Cbr/>'Found 46% in ONE place'] --> B[/cases/bottleneck]\n B --> C[ACT 1: THE CASE\u003Cbr/>Sees averages hiding problem]\n C --> D[ACT 2: YOUR TURN\u003Cbr/>Interactive demo exploration]\n D --> E[ACT 3: SOLUTION\u003Cbr/>Aha! The methodology revealed]\n E --> F{Next Action}\n F -->|Explore more| G[Another case study]\n F -->|Ready to try| H[CTA: What's YOUR 46%?]\n G --> I[/pricing]\n H --> I\n I --> J{Outcome}\n J --> K[CONVERSION]\n J --> L[EMAIL CAPTURE]\n```\n\n### User Satisfaction Journey\n\n```mermaid\njourney\n title Social Discovery Journey\n section Hook\n See LinkedIn post: 4: User\n Intrigued by 46%: 5: User\n section Engagement\n Read Act 1 setup: 4: User\n Try demo yourself: 5: User\n section Revelation\n See solution unfold: 5: User\n Aha moment: 5: User\n section Decision\n Want to try own data: 5: User\n Check pricing: 4: User\n section Action\n Start with PWA demo: 5: User\n Or sign up for email: 4: User\n```\n\n### ASCII Reference\n\n```\n┌─────────────────┐\n│ LinkedIn │\n│ │\n│ \"This bakery │\n│ found 46% of │\n│ their problem │\n│ in ONE place\" │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│/cases/bottleneck│\n│ │\n│ ACT 1: THE CASE │\n│ Sees averages │\n│ \"Line B is │\n│ under target\" │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ ACT 2: YOUR TURN│\n│ │\n│ Explores demo │\n│ Clicks around │\n│ Maybe finds it │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ ACT 3: SOLUTION │\n│ │\n│ Scroll journey │\n│ \"Aha! That's │\n│ how you think │\n│ about it!\" │\n└────────┬────────┘\n │\n ┌────┴────┐\n │ │\n ▼ ▼\n┌────────┐ ┌────────────┐\n│ Another│ │ CTA: │\n│ case │ │ \"What's │\n│ │ │ YOUR 46%?\" │\n└────┬───┘ └─────┬──────┘\n │ │\n │ ▼\n │ ┌─────────────────┐\n │ │ /pricing │\n │ │ │\n │ │ Evaluates │\n └───▶│ │\n └────────┬────────┘\n │\n ▼\n ┌─────────────────┐\n │ CONVERSION │\n │ or │\n │ EMAIL CAPTURE │\n └─────────────────┘\n```\n\n---\n\n## The 3-Act Case Structure\n\nEvery case page follows this narrative arc:\n\n### Act 1: The Setup\n\n- Present the problem as management sees it\n- Show the averages, the dashboard view\n- \"Line B is 3% under target\"\n- Create cognitive dissonance: \"But wait...\"\n\n### Act 2: Your Turn\n\n- Interactive demo with the case data\n- User explores freely\n- Some hints available if stuck\n- \"Can you find where the 46% is hiding?\"\n\n### Act 3: The Solution\n\n- Scroll-based reveal of the analysis journey\n- Step by step: I-Chart → Boxplot → Pareto → Drill-down\n- The \"aha moment\": \"46% was in Machine C, Shift 2, Operator X\"\n- Methodology connection: This is the Four Lenses in action\n\n---\n\n## Page Sequence\n\n### 1. Case Landing (/cases/bottleneck)\n\n**Must answer in 5 seconds:** \"Is this relevant to me?\"\n\n- Industry recognition (manufacturing, bakery, coffee - something relatable)\n- Clear problem statement\n- Engaging visual teaser\n\n### 2. Act 1 Content\n\nCarlos reads the setup:\n\n- Identifies with the problem\n- Recognizes the \"averages trap\"\n- Gets curious about the solution\n\n### 3. Act 2 Demo\n\nCarlos interacts:\n\n- Clicks on charts\n- Sees linked filtering\n- May or may not find the answer\n- Feels engaged, not lectured\n\n### 4. Act 3 Reveal\n\nCarlos learns the methodology:\n\n- Sees the step-by-step analysis\n- Understands the thinking process\n- \"I could do this with my data\"\n\n---\n\n## CTAs on This Journey\n\n| Location | CTA Text | Destination | Note |\n| ------------- | --------------------------- | -------------------- | ------------------------------ |\n| After Act 3 | \"Find YOUR 46%\" | /app | Opens demo to try with samples |\n| After Act 3 | \"Paste Your Data\" | /app | For users ready for own data |\n| After Act 3 | \"Try another case\" | /cases | |\n| After Act 3 | \"Get case studies by email\" | Email capture | |\n| Sidebar | \"Learn the methodology\" | /learn/four-lenses | |\n| Related cases | \"Next: Hospital Ward Case\" | /cases/hospital-ward | |\n\n**Updated Journey:**\n\n1. Case study → \"Find YOUR 46%\" → Try Demo with samples\n2. Like it? → \"Paste Your Data\" → Try with own data (free)\n3. Need team features? → Azure App (from €99/month)\n\n---\n\n## Case Cross-Links\n\n| From Case | Links To | Reason |\n| ----------------- | -------------------- | -------------------------- |\n| /cases/bottleneck | /tools/i-chart | \"Learn more about I-Chart\" |\n| /cases/bottleneck | /cases/hospital-ward | \"Next case\" |\n| /cases/bottleneck | /learn/four-lenses | \"The methodology\" |\n| Any case | /pricing | \"Do this with your data\" |\n\n---\n\n## Mobile Considerations\n\n- Act 2 demo simplified for touch\n- Swipe-based Act 3 scroll experience\n- Sticky \"Find YOUR 46%\" at bottom\n- Charts optimized for portrait orientation\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ------------------------- | ------ |\n| Case Act 1 → Act 2 (demo) | >60% |\n| Case Act 2 → Act 3 | >70% |\n| Case → Product page | >20% |\n| Case → Another case | >30% |\n| Email capture rate | >5% |\n\n---\n\n## Social Post Templates\n\n### LinkedIn Post (teaser)\n\n```\nThis bakery found 46% of their quality problems in ONE place.\n\nThe dashboard said \"Line B is 3% under target.\"\nBut that average hid the real story.\n\nHere's how they found it → [link to /cases/bottleneck]\n\n#VariationScouting #LeanSixSigma #ProcessImprovement\n```\n\n### Instagram Carousel\n\n1. \"What the dashboard showed\" (bar chart)\n2. \"What the data revealed\" (I-Chart with pattern)\n3. \"Where the problem hid\" (Boxplot showing Factor C)\n4. \"46% in one place\" (Pareto)\n5. \"Find YOUR 46%\" (CTA)", + "src/content/docs/02-journeys/flows/social-discovery.md", + "c7e53b26f57245b9", + { "html": 4566, "metadata": 4567 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"flow-2-social-discovery--case--product\">Flow 2: Social Discovery → Case → Product\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#flow-2-social-discovery--case--product\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 2: Social Discovery → Case → Product”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Curious Carlos sees a LinkedIn post, explores a case study, discovers VaRiScout\u003C/p>\n\u003Cp>\u003Cstrong>Priority:\u003C/strong> High - best conversion story\u003C/p>\n\u003Cp>See also: \u003Ca href=\"../index.md\">Journeys Overview\u003C/a> for site architecture\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-curious-carlos\">Persona: Curious Carlos\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-curious-carlos\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona: Curious Carlos”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Operations Supervisor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Understand variation better\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Interested but not formally trained\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Sees problems but lacks tools to analyze them\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Entry points\u003C/strong>\u003C/td>\u003Ctd>YouTube, TikTok, Instagram, LinkedIn\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Needs to “see it work” before committing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-carlos-is-thinking\">What Carlos is thinking:\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-carlos-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Carlos is thinking:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“That post about finding 46% of problems in one place is interesting”\u003C/li>\n\u003Cli>“I wonder if I could do something like this at my plant”\u003C/li>\n\u003Cli>“This seems easier than the stats stuff I’ve seen before”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Social Source\u003C/th>\u003Cth>Content Type\u003C/th>\u003Cth>Lands On\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>LinkedIn post\u003C/td>\u003Ctd>Case study teaser\u003C/td>\u003Ctd>/cases/bottleneck\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LinkedIn article\u003C/td>\u003Ctd>”How we found 46%“\u003C/td>\u003Ctd>/cases/X\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Instagram carousel\u003C/td>\u003Ctd>Before/after visuals\u003C/td>\u003Ctd>/cases/X or /\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>TikTok clip\u003C/td>\u003Ctd>”Watch me find it”\u003C/td>\u003Ctd>/ or /tools/X\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mermaid-flowchart\">Mermaid Flowchart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mermaid-flowchart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mermaid Flowchart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[LinkedIn Post<br/>'Found 46% in ONE place'] --> B[/cases/bottleneck]\n B --> C[ACT 1: THE CASE<br/>Sees averages hiding problem]\n C --> D[ACT 2: YOUR TURN<br/>Interactive demo exploration]\n D --> E[ACT 3: SOLUTION<br/>Aha! The methodology revealed]\n E --> F{Next Action}\n F -->|Explore more| G[Another case study]\n F -->|Ready to try| H[CTA: What's YOUR 46%?]\n G --> I[/pricing]\n H --> I\n I --> J{Outcome}\n J --> K[CONVERSION]\n J --> L[EMAIL CAPTURE]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-satisfaction-journey\">User Satisfaction Journey\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-satisfaction-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Satisfaction Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Social Discovery Journey\n section Hook\n See LinkedIn post: 4: User\n Intrigued by 46%: 5: User\n section Engagement\n Read Act 1 setup: 4: User\n Try demo yourself: 5: User\n section Revelation\n See solution unfold: 5: User\n Aha moment: 5: User\n section Decision\n Want to try own data: 5: User\n Check pricing: 4: User\n section Action\n Start with PWA demo: 5: User\n Or sign up for email: 4: User\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ascii-reference\">ASCII Reference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ascii-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ASCII Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ LinkedIn │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"This bakery │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ found 46% of │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ their problem │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ in ONE place\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│/cases/bottleneck│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ACT 1: THE CASE │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Sees averages │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Line B is │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ under target\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ACT 2: YOUR TURN│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Explores demo │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Clicks around │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Maybe finds it │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ACT 3: SOLUTION │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Scroll journey │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Aha! That's │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ how you think │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ about it!\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────┐ ┌────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Another│ │ CTA: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ case │ │ \"What's │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ YOUR 46%?\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────┬───┘ └─────┬──────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ /pricing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Evaluates │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───▶│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CONVERSION │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ or │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ EMAIL CAPTURE │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ LinkedIn ││ ││ "This bakery ││ found 46% of ││ their problem ││ in ONE place" │└────────┬────────┘ │ ▼┌─────────────────┐│/cases/bottleneck││ ││ ACT 1: THE CASE ││ Sees averages ││ "Line B is ││ under target" │└────────┬────────┘ │ ▼┌─────────────────┐│ ACT 2: YOUR TURN││ ││ Explores demo ││ Clicks around ││ Maybe finds it │└────────┬────────┘ │ ▼┌─────────────────┐│ ACT 3: SOLUTION ││ ││ Scroll journey ││ "Aha! That's ││ how you think ││ about it!" │└────────┬────────┘ │ ┌────┴────┐ │ │ ▼ ▼┌────────┐ ┌────────────┐│ Another│ │ CTA: ││ case │ │ "What's ││ │ │ YOUR 46%?" │└────┬───┘ └─────┬──────┘ │ │ │ ▼ │ ┌─────────────────┐ │ │ /pricing │ │ │ │ │ │ Evaluates │ └───▶│ │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ CONVERSION │ │ or │ │ EMAIL CAPTURE │ └─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-3-act-case-structure\">The 3-Act Case Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-3-act-case-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The 3-Act Case Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every case page follows this narrative arc:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-1-the-setup\">Act 1: The Setup\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-1-the-setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 1: The Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Present the problem as management sees it\u003C/li>\n\u003Cli>Show the averages, the dashboard view\u003C/li>\n\u003Cli>“Line B is 3% under target”\u003C/li>\n\u003Cli>Create cognitive dissonance: “But wait…”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-2-your-turn\">Act 2: Your Turn\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-2-your-turn\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 2: Your Turn”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Interactive demo with the case data\u003C/li>\n\u003Cli>User explores freely\u003C/li>\n\u003Cli>Some hints available if stuck\u003C/li>\n\u003Cli>“Can you find where the 46% is hiding?”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-3-the-solution\">Act 3: The Solution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-3-the-solution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 3: The Solution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Scroll-based reveal of the analysis journey\u003C/li>\n\u003Cli>Step by step: I-Chart → Boxplot → Pareto → Drill-down\u003C/li>\n\u003Cli>The “aha moment”: “46% was in Machine C, Shift 2, Operator X”\u003C/li>\n\u003Cli>Methodology connection: This is the Four Lenses in action\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"page-sequence\">Page Sequence\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#page-sequence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Page Sequence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-case-landing-casesbottleneck\">1. Case Landing (/cases/bottleneck)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-case-landing-casesbottleneck\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Case Landing (/cases/bottleneck)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Must answer in 5 seconds:\u003C/strong> “Is this relevant to me?”\u003C/p>\n\u003Cul>\n\u003Cli>Industry recognition (manufacturing, bakery, coffee - something relatable)\u003C/li>\n\u003Cli>Clear problem statement\u003C/li>\n\u003Cli>Engaging visual teaser\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-act-1-content\">2. Act 1 Content\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-act-1-content\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Act 1 Content”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Carlos reads the setup:\u003C/p>\n\u003Cul>\n\u003Cli>Identifies with the problem\u003C/li>\n\u003Cli>Recognizes the “averages trap”\u003C/li>\n\u003Cli>Gets curious about the solution\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-act-2-demo\">3. Act 2 Demo\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-act-2-demo\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Act 2 Demo”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Carlos interacts:\u003C/p>\n\u003Cul>\n\u003Cli>Clicks on charts\u003C/li>\n\u003Cli>Sees linked filtering\u003C/li>\n\u003Cli>May or may not find the answer\u003C/li>\n\u003Cli>Feels engaged, not lectured\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-act-3-reveal\">4. Act 3 Reveal\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-act-3-reveal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Act 3 Reveal”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Carlos learns the methodology:\u003C/p>\n\u003Cul>\n\u003Cli>Sees the step-by-step analysis\u003C/li>\n\u003Cli>Understands the thinking process\u003C/li>\n\u003Cli>“I could do this with my data”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ctas-on-this-journey\">CTAs on This Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ctas-on-this-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CTAs on This Journey”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Location\u003C/th>\u003Cth>CTA Text\u003C/th>\u003Cth>Destination\u003C/th>\u003Cth>Note\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>After Act 3\u003C/td>\u003Ctd>”Find YOUR 46%“\u003C/td>\u003Ctd>/app\u003C/td>\u003Ctd>Opens demo to try with samples\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>After Act 3\u003C/td>\u003Ctd>”Paste Your Data”\u003C/td>\u003Ctd>/app\u003C/td>\u003Ctd>For users ready for own data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>After Act 3\u003C/td>\u003Ctd>”Try another case”\u003C/td>\u003Ctd>/cases\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>After Act 3\u003C/td>\u003Ctd>”Get case studies by email”\u003C/td>\u003Ctd>Email capture\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sidebar\u003C/td>\u003Ctd>”Learn the methodology”\u003C/td>\u003Ctd>/learn/four-lenses\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Related cases\u003C/td>\u003Ctd>”Next: Hospital Ward Case”\u003C/td>\u003Ctd>/cases/hospital-ward\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Updated Journey:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Case study → “Find YOUR 46%” → Try Demo with samples\u003C/li>\n\u003Cli>Like it? → “Paste Your Data” → Try with own data (free)\u003C/li>\n\u003Cli>Need team features? → Azure App (from €99/month)\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"case-cross-links\">Case Cross-Links\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#case-cross-links\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Case Cross-Links”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>From Case\u003C/th>\u003Cth>Links To\u003C/th>\u003Cth>Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>/cases/bottleneck\u003C/td>\u003Ctd>/tools/i-chart\u003C/td>\u003Ctd>”Learn more about I-Chart”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>/cases/bottleneck\u003C/td>\u003Ctd>/cases/hospital-ward\u003C/td>\u003Ctd>”Next case”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>/cases/bottleneck\u003C/td>\u003Ctd>/learn/four-lenses\u003C/td>\u003Ctd>”The methodology”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Any case\u003C/td>\u003Ctd>/pricing\u003C/td>\u003Ctd>”Do this with your data”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"mobile-considerations\">Mobile Considerations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Act 2 demo simplified for touch\u003C/li>\n\u003Cli>Swipe-based Act 3 scroll experience\u003C/li>\n\u003Cli>Sticky “Find YOUR 46%” at bottom\u003C/li>\n\u003Cli>Charts optimized for portrait orientation\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Case Act 1 → Act 2 (demo)\u003C/td>\u003Ctd>>60%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Case Act 2 → Act 3\u003C/td>\u003Ctd>>70%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Case → Product page\u003C/td>\u003Ctd>>20%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Case → Another case\u003C/td>\u003Ctd>>30%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Email capture rate\u003C/td>\u003Ctd>>5%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"social-post-templates\">Social Post Templates\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#social-post-templates\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Social Post Templates”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"linkedin-post-teaser\">LinkedIn Post (teaser)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#linkedin-post-teaser\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “LinkedIn Post (teaser)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">This bakery found 46% of their quality problems in ONE place.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">The dashboard said \"Line B is 3% under target.\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">But that average hid the real story.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Here's how they found it → [link to /cases/bottleneck]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">#VariationScouting #LeanSixSigma #ProcessImprovement\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"This bakery found 46% of their quality problems in ONE place.The dashboard said "Line B is 3% under target."But that average hid the real story.Here's how they found it → [link to /cases/bottleneck]#VariationScouting #LeanSixSigma #ProcessImprovement\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"instagram-carousel\">Instagram Carousel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#instagram-carousel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Instagram Carousel”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>“What the dashboard showed” (bar chart)\u003C/li>\n\u003Cli>“What the data revealed” (I-Chart with pattern)\u003C/li>\n\u003Cli>“Where the problem hid” (Boxplot showing Factor C)\u003C/li>\n\u003Cli>“46% in one place” (Pareto)\u003C/li>\n\u003Cli>“Find YOUR 46%” (CTA)\u003C/li>\n\u003C/ol>", + { + "headings": 4568, + "localImagePaths": 4620, + "remoteImagePaths": 4621, + "frontmatter": 4622, + "imagePaths": 4623 + }, + [ + 4569, 4571, 4574, 4575, 4576, 4577, 4578, 4579, 4580, 4583, 4586, 4589, 4592, 4593, 4596, 4599, + 4602, 4605, 4606, 4609, 4610, 4611, 4614, 4617 + ], + { "depth": 30, "slug": 4570, "text": 4558 }, + "flow-2-social-discovery--case--product", + { "depth": 33, "slug": 4572, "text": 4573 }, + "persona-curious-carlos", + "Persona: Curious Carlos", + { "depth": 79, "slug": 4307, "text": 4308 }, + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 79, "slug": 4078, "text": 4079 }, + { "depth": 79, "slug": 4316, "text": 4317 }, + { "depth": 79, "slug": 919, "text": 920 }, + { "depth": 33, "slug": 4581, "text": 4582 }, + "the-3-act-case-structure", + "The 3-Act Case Structure", + { "depth": 79, "slug": 4584, "text": 4585 }, + "act-1-the-setup", + "Act 1: The Setup", + { "depth": 79, "slug": 4587, "text": 4588 }, + "act-2-your-turn", + "Act 2: Your Turn", + { "depth": 79, "slug": 4590, "text": 4591 }, + "act-3-the-solution", + "Act 3: The Solution", + { "depth": 33, "slug": 4531, "text": 4532 }, + { "depth": 79, "slug": 4594, "text": 4595 }, + "1-case-landing-casesbottleneck", + "1. Case Landing (/cases/bottleneck)", + { "depth": 79, "slug": 4597, "text": 4598 }, + "2-act-1-content", + "2. Act 1 Content", + { "depth": 79, "slug": 4600, "text": 4601 }, + "3-act-2-demo", + "3. Act 2 Demo", + { "depth": 79, "slug": 4603, "text": 4604 }, + "4-act-3-reveal", + "4. Act 3 Reveal", + { "depth": 33, "slug": 4397, "text": 4398 }, + { "depth": 33, "slug": 4607, "text": 4608 }, + "case-cross-links", + "Case Cross-Links", + { "depth": 33, "slug": 4335, "text": 4336 }, + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4612, "text": 4613 }, + "social-post-templates", + "Social Post Templates", + { "depth": 79, "slug": 4615, "text": 4616 }, + "linkedin-post-teaser", + "LinkedIn Post (teaser)", + { "depth": 79, "slug": 4618, "text": 4619 }, + "instagram-carousel", + "Instagram Carousel", + [], + [], + { "title": 4558 }, + [], + "02-journeys/personas/curious-carlos", + { "id": 4624, "data": 4626, "body": 4631, "filePath": 4632, "digest": 4633, "rendered": 4634 }, + { + "title": 4627, + "editUrl": 16, + "head": 4628, + "template": 18, + "sidebar": 4629, + "pagefind": 16, + "draft": 20 + }, + "Curious Carlos", + [], + { "hidden": 20, "attrs": 4630 }, + {}, + "# Curious Carlos\n\n| Attribute | Detail |\n| ----------------- | --------------------------------------------- |\n| **Role** | Operations Supervisor |\n| **Goal** | Understand variation better |\n| **Knowledge** | Interested but not formally trained |\n| **Pain points** | Sees problems but lacks tools to analyze them |\n| **Decision mode** | Needs to \"see it work\" before committing |\n\n---\n\n## What Carlos is thinking\n\n- \"That post about finding 46% of problems in one place is interesting\"\n- \"I wonder if I could do something like this at my plant\"\n- \"This seems easier than the stats stuff I've seen before\"\n\n---\n\n## 4-Phase Journey\n\n```mermaid\njourney\n title Curious Carlos's Journey\n section Discovery\n See LinkedIn post about case: 4: Carlos\n Click to read case study: 5: Carlos\n section Exploration\n Read Act 1 - The Problem: 5: Carlos\n Try Act 2 - Demo: 4: Carlos\n See Act 3 - Solution: 5: Carlos\n section Consideration\n Think about own data: 4: Carlos\n Check pricing page: 3: Carlos\n section Adoption\n Try demo with samples: 5: Carlos\n Install PWA: 5: Carlos\n```\n\n---\n\n## Entry Points\n\n| Social Source | Content Type | Lands On |\n| ------------------ | -------------------- | ------------------- |\n| LinkedIn post | Case study teaser | /cases/bottleneck |\n| LinkedIn article | \"How we found 46%\" | /cases/X |\n| Instagram carousel | Before/after visuals | /cases/X or / |\n| TikTok clip | \"Watch me find it\" | / or /tools/X |\n| YouTube video | Tutorial content | /tools/X or /blog/X |\n\n---\n\n## Journey Flow\n\n```\n┌─────────────────┐\n│ LinkedIn │\n│ │\n│ \"This bakery │\n│ found 46% of │\n│ their problem │\n│ in ONE place\" │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│/cases/bottleneck│\n│ │\n│ ACT 1: THE CASE │\n│ Sees averages │\n│ \"Line B is │\n│ under target\" │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ ACT 2: YOUR TURN│\n│ │\n│ Explores demo │\n│ Clicks around │\n│ Maybe finds it │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ ACT 3: SOLUTION │\n│ │\n│ Scroll journey │\n│ \"Aha! That's │\n│ how you think │\n│ about it!\" │\n└────────┬────────┘\n │\n ┌────┴────┐\n │ │\n ▼ ▼\n┌────────┐ ┌────────────┐\n│ Another│ │ CTA: │\n│ case │ │ \"What's │\n│ │ │ YOUR 46%?\" │\n└────────┘ └─────┬──────┘\n │\n ▼\n ┌─────────────────┐\n │ Opens PWA to │\n │ try own data │\n └─────────────────┘\n```\n\n---\n\n## The 3-Act Case Experience\n\nEvery case page follows this narrative arc:\n\n### Act 1: The Setup\n\n- Present the problem as management sees it\n- Show the averages, the dashboard view\n- \"Line B is 3% under target\"\n- Create cognitive dissonance: \"But wait...\"\n\n### Act 2: Your Turn\n\n- Interactive demo with the case data\n- User explores freely\n- Some hints available if stuck\n- \"Can you find where the 46% is hiding?\"\n\n### Act 3: The Solution\n\n- Scroll-based reveal of the analysis journey\n- Step by step: I-Chart → Boxplot → Pareto → Drill-down\n- The \"aha moment\": \"46% was in Machine C, Shift 2, Operator X\"\n- Methodology connection: This is the Four Lenses in action\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ------------------------- | ------ |\n| Case Act 1 → Act 2 (demo) | >60% |\n| Case Act 2 → Act 3 | >70% |\n| Case → Product page | >20% |\n| Case → Another case | >30% |\n| Case → PWA conversion | >5% |\n\n---\n\n## Related Flows\n\n- [Social Discovery Flow](../flows/social-discovery.md) — Carlos's primary flow\n- [Content & YouTube Flow](../flows/content-youtube.md) — Alternative entry", + "src/content/docs/02-journeys/personas/curious-carlos.md", + "684658db0f0ad905", + { "html": 4635, "metadata": 4636 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"curious-carlos\">Curious Carlos\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#curious-carlos\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Curious Carlos”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Operations Supervisor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Understand variation better\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Interested but not formally trained\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Sees problems but lacks tools to analyze them\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Needs to “see it work” before committing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-carlos-is-thinking\">What Carlos is thinking\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-carlos-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Carlos is thinking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“That post about finding 46% of problems in one place is interesting”\u003C/li>\n\u003Cli>“I wonder if I could do something like this at my plant”\u003C/li>\n\u003Cli>“This seems easier than the stats stuff I’ve seen before”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-phase-journey\">4-Phase Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-phase-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4-Phase Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Curious Carlos's Journey\n section Discovery\n See LinkedIn post about case: 4: Carlos\n Click to read case study: 5: Carlos\n section Exploration\n Read Act 1 - The Problem: 5: Carlos\n Try Act 2 - Demo: 4: Carlos\n See Act 3 - Solution: 5: Carlos\n section Consideration\n Think about own data: 4: Carlos\n Check pricing page: 3: Carlos\n section Adoption\n Try demo with samples: 5: Carlos\n Install PWA: 5: Carlos\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Social Source\u003C/th>\u003Cth>Content Type\u003C/th>\u003Cth>Lands On\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>LinkedIn post\u003C/td>\u003Ctd>Case study teaser\u003C/td>\u003Ctd>/cases/bottleneck\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LinkedIn article\u003C/td>\u003Ctd>”How we found 46%“\u003C/td>\u003Ctd>/cases/X\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Instagram carousel\u003C/td>\u003Ctd>Before/after visuals\u003C/td>\u003Ctd>/cases/X or /\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>TikTok clip\u003C/td>\u003Ctd>”Watch me find it”\u003C/td>\u003Ctd>/ or /tools/X\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>YouTube video\u003C/td>\u003Ctd>Tutorial content\u003C/td>\u003Ctd>/tools/X or /blog/X\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ LinkedIn │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"This bakery │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ found 46% of │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ their problem │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ in ONE place\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│/cases/bottleneck│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ACT 1: THE CASE │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Sees averages │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Line B is │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ under target\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ACT 2: YOUR TURN│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Explores demo │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Clicks around │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Maybe finds it │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ACT 3: SOLUTION │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Scroll journey │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Aha! That's │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ how you think │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ about it!\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────┐ ┌────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Another│ │ CTA: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ case │ │ \"What's │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ YOUR 46%?\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┘ └─────┬──────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Opens PWA to │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ try own data │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ LinkedIn ││ ││ "This bakery ││ found 46% of ││ their problem ││ in ONE place" │└────────┬────────┘ │ ▼┌─────────────────┐│/cases/bottleneck││ ││ ACT 1: THE CASE ││ Sees averages ││ "Line B is ││ under target" │└────────┬────────┘ │ ▼┌─────────────────┐│ ACT 2: YOUR TURN││ ││ Explores demo ││ Clicks around ││ Maybe finds it │└────────┬────────┘ │ ▼┌─────────────────┐│ ACT 3: SOLUTION ││ ││ Scroll journey ││ "Aha! That's ││ how you think ││ about it!" │└────────┬────────┘ │ ┌────┴────┐ │ │ ▼ ▼┌────────┐ ┌────────────┐│ Another│ │ CTA: ││ case │ │ "What's ││ │ │ YOUR 46%?" │└────────┘ └─────┬──────┘ │ ▼ ┌─────────────────┐ │ Opens PWA to │ │ try own data │ └─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-3-act-case-experience\">The 3-Act Case Experience\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-3-act-case-experience\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The 3-Act Case Experience”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every case page follows this narrative arc:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-1-the-setup\">Act 1: The Setup\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-1-the-setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 1: The Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Present the problem as management sees it\u003C/li>\n\u003Cli>Show the averages, the dashboard view\u003C/li>\n\u003Cli>“Line B is 3% under target”\u003C/li>\n\u003Cli>Create cognitive dissonance: “But wait…”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-2-your-turn\">Act 2: Your Turn\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-2-your-turn\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 2: Your Turn”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Interactive demo with the case data\u003C/li>\n\u003Cli>User explores freely\u003C/li>\n\u003Cli>Some hints available if stuck\u003C/li>\n\u003Cli>“Can you find where the 46% is hiding?”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-3-the-solution\">Act 3: The Solution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-3-the-solution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 3: The Solution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Scroll-based reveal of the analysis journey\u003C/li>\n\u003Cli>Step by step: I-Chart → Boxplot → Pareto → Drill-down\u003C/li>\n\u003Cli>The “aha moment”: “46% was in Machine C, Shift 2, Operator X”\u003C/li>\n\u003Cli>Methodology connection: This is the Four Lenses in action\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Case Act 1 → Act 2 (demo)\u003C/td>\u003Ctd>>60%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Case Act 2 → Act 3\u003C/td>\u003Ctd>>70%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Case → Product page\u003C/td>\u003Ctd>>20%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Case → Another case\u003C/td>\u003Ctd>>30%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Case → PWA conversion\u003C/td>\u003Ctd>>5%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-flows\">Related Flows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-flows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Flows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../flows/social-discovery.md\">Social Discovery Flow\u003C/a> — Carlos’s primary flow\u003C/li>\n\u003Cli>\u003Ca href=\"../flows/content-youtube.md\">Content & YouTube Flow\u003C/a> — Alternative entry\u003C/li>\n\u003C/ul>", + { + "headings": 4637, + "localImagePaths": 4657, + "remoteImagePaths": 4658, + "frontmatter": 4659, + "imagePaths": 4660 + }, + [4638, 4640, 4642, 4645, 4646, 4647, 4650, 4651, 4652, 4653, 4654], + { "depth": 30, "slug": 4639, "text": 4627 }, + "curious-carlos", + { "depth": 33, "slug": 4307, "text": 4641 }, + "What Carlos is thinking", + { "depth": 33, "slug": 4643, "text": 4644 }, + "4-phase-journey", + "4-Phase Journey", + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 33, "slug": 4648, "text": 4649 }, + "the-3-act-case-experience", + "The 3-Act Case Experience", + { "depth": 79, "slug": 4584, "text": 4585 }, + { "depth": 79, "slug": 4587, "text": 4588 }, + { "depth": 79, "slug": 4590, "text": 4591 }, + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4655, "text": 4656 }, + "related-flows", + "Related Flows", + [], + [], + { "title": 4627 }, + [], + "02-journeys/personas/evaluator-erik", + { "id": 4661, "data": 4663, "body": 4668, "filePath": 4669, "digest": 4670, "rendered": 4671 }, + { + "title": 4664, + "editUrl": 16, + "head": 4665, + "template": 18, + "sidebar": 4666, + "pagefind": 16, + "draft": 20 + }, + "Evaluator Erik", + [], + { "hidden": 20, "attrs": 4667 }, + {}, + "# Evaluator Erik\n\n| Attribute | Detail |\n| ----------------- | ------------------------------------------------------------- |\n| **Role** | IT/Procurement |\n| **Goal** | Assess for organization |\n| **Knowledge** | Technical, security-focused |\n| **Pain points** | Too many tools to evaluate, security concerns, vendor lock-in |\n| **Decision mode** | Checklist-driven, needs documentation |\n\n---\n\n## What Erik is thinking\n\n- \"OpEx wants this tool - what's the security story?\"\n- \"Where does the data go?\"\n- \"Can we deploy this ourselves?\"\n- \"What's our exit strategy if we need to switch?\"\n\n---\n\n## 4-Phase Journey\n\n```mermaid\njourney\n title Evaluator Erik's Journey\n section Request\n Receive evaluation request: 3: Erik\n Initial security scan: 3: Erik\n section Assessment\n Review architecture docs: 4: Erik\n Check data residency: 4: Erik\n section Validation\n Verify SSO integration: 4: Erik\n Review compliance: 4: Erik\n section Approval\n Document findings: 5: Erik\n Approve or escalate: 4: Erik\n```\n\n---\n\n## Entry Points\n\n| Source | Context | Lands On |\n| --------------- | ---------------------------- | ------------------- |\n| OpEx request | \"Evaluate this for the team\" | / or /pricing |\n| Direct link | From colleague | /product/enterprise |\n| Security review | Due diligence | /product/enterprise |\n\n---\n\n## Erik's Evaluation Checklist\n\n| Question | Answer |\n| -------------------------- | --------------------------------- |\n| Security architecture? | Azure-native, your tenant |\n| Data residency? | Your choice of Azure region |\n| Authentication? | Azure AD SSO |\n| Compliance certifications? | Azure compliance + our docs |\n| SLA? | Azure SLA |\n| Exit strategy? | Export all data, standard formats |\n| Audit logging? | Azure native logging |\n| Encryption? | At rest and in transit |\n| GDPR compliance? | Yes - data stays in your tenant |\n\n---\n\n## Information Architecture for Erik\n\n### Must Find Quickly\n\n1. **Security documentation** - Not marketing, real technical specs\n2. **Architecture diagram** - Where data flows\n3. **Deployment guide** - How to install\n4. **Integration requirements** - What it needs\n5. **Exit/migration path** - How to leave\n\n### Page Structure Needs\n\n```\n/product/enterprise\n├── Overview (skim)\n├── Security & Compliance (FOCUS)\n│ ├── Data residency\n│ ├── Authentication\n│ ├── Encryption\n│ └── Audit logging\n├── Deployment\n│ ├── Prerequisites\n│ ├── Azure Marketplace\n│ └── Configuration\n├── Integration\n│ ├── Azure AD\n│ └── Power BI (if applicable)\n└── Data portability\n ├── Export formats\n └── Migration guide\n```\n\n---\n\n## Journey Flow\n\n```\n┌─────────────────┐\n│ OpEx sends │\n│ evaluation │\n│ request │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ /product/ │\n│ enterprise │\n│ │\n│ Quick scan: │\n│ \"Is this legit?\"│\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ Security docs │\n│ │\n│ - Architecture │\n│ - Data flow │\n│ - Encryption │\n│ - Compliance │\n└────────┬────────┘\n │\n ┌────┴────────────┐\n │ │\n ▼ ▼\n┌────────────┐ ┌────────────┐\n│ APPROVED │ │ QUESTIONS │\n│ │ │ │\n│ Proceed to │ │ Contact │\n│ deployment │ │ for more │\n│ │ │ info │\n└────────────┘ └────────────┘\n```\n\n---\n\n## Documentation Requirements\n\nErik needs:\n\n1. **PDF downloadable** - For internal distribution\n2. **No marketing fluff** - Technical facts only\n3. **Architecture diagrams** - Visual understanding\n4. **Compliance matrix** - Checkbox-friendly\n5. **Version history** - When docs were updated\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ----------------------------------- | ------ |\n| Enterprise page → Security docs | >80% |\n| Docs download rate | Track |\n| Time to approval (from first visit) | Track |\n| Questions via contact form | Track |\n\n---\n\n## Related Flows\n\n- [Enterprise Flow](../flows/enterprise.md) — Olivia initiates, Erik evaluates", + "src/content/docs/02-journeys/personas/evaluator-erik.md", + "495391129ee6ea56", + { "html": 4672, "metadata": 4673 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"evaluator-erik\">Evaluator Erik\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#evaluator-erik\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Evaluator Erik”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>IT/Procurement\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Assess for organization\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Technical, security-focused\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Too many tools to evaluate, security concerns, vendor lock-in\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Checklist-driven, needs documentation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-erik-is-thinking\">What Erik is thinking\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-erik-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Erik is thinking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“OpEx wants this tool - what’s the security story?”\u003C/li>\n\u003Cli>“Where does the data go?”\u003C/li>\n\u003Cli>“Can we deploy this ourselves?”\u003C/li>\n\u003Cli>“What’s our exit strategy if we need to switch?“\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-phase-journey\">4-Phase Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-phase-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4-Phase Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Evaluator Erik's Journey\n section Request\n Receive evaluation request: 3: Erik\n Initial security scan: 3: Erik\n section Assessment\n Review architecture docs: 4: Erik\n Check data residency: 4: Erik\n section Validation\n Verify SSO integration: 4: Erik\n Review compliance: 4: Erik\n section Approval\n Document findings: 5: Erik\n Approve or escalate: 4: Erik\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Source\u003C/th>\u003Cth>Context\u003C/th>\u003Cth>Lands On\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>OpEx request\u003C/td>\u003Ctd>”Evaluate this for the team”\u003C/td>\u003Ctd>/ or /pricing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Direct link\u003C/td>\u003Ctd>From colleague\u003C/td>\u003Ctd>/product/enterprise\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Security review\u003C/td>\u003Ctd>Due diligence\u003C/td>\u003Ctd>/product/enterprise\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"eriks-evaluation-checklist\">Erik’s Evaluation Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#eriks-evaluation-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Erik’s Evaluation Checklist”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Question\u003C/th>\u003Cth>Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Security architecture?\u003C/td>\u003Ctd>Azure-native, your tenant\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data residency?\u003C/td>\u003Ctd>Your choice of Azure region\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Authentication?\u003C/td>\u003Ctd>Azure AD SSO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Compliance certifications?\u003C/td>\u003Ctd>Azure compliance + our docs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SLA?\u003C/td>\u003Ctd>Azure SLA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Exit strategy?\u003C/td>\u003Ctd>Export all data, standard formats\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Audit logging?\u003C/td>\u003Ctd>Azure native logging\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Encryption?\u003C/td>\u003Ctd>At rest and in transit\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>GDPR compliance?\u003C/td>\u003Ctd>Yes - data stays in your tenant\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"information-architecture-for-erik\">Information Architecture for Erik\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#information-architecture-for-erik\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Information Architecture for Erik”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"must-find-quickly\">Must Find Quickly\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#must-find-quickly\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Must Find Quickly”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Security documentation\u003C/strong> - Not marketing, real technical specs\u003C/li>\n\u003Cli>\u003Cstrong>Architecture diagram\u003C/strong> - Where data flows\u003C/li>\n\u003Cli>\u003Cstrong>Deployment guide\u003C/strong> - How to install\u003C/li>\n\u003Cli>\u003Cstrong>Integration requirements\u003C/strong> - What it needs\u003C/li>\n\u003Cli>\u003Cstrong>Exit/migration path\u003C/strong> - How to leave\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"page-structure-needs\">Page Structure Needs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#page-structure-needs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Page Structure Needs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">/product/enterprise\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Overview (skim)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Security & Compliance (FOCUS)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Data residency\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Authentication\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Encryption\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Audit logging\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Deployment\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Prerequisites\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Azure Marketplace\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Configuration\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Integration\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Azure AD\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Power BI (if applicable)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Data portability\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Export formats\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Migration guide\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"/product/enterprise├── Overview (skim)├── Security & Compliance (FOCUS)│ ├── Data residency│ ├── Authentication│ ├── Encryption│ └── Audit logging├── Deployment│ ├── Prerequisites│ ├── Azure Marketplace│ └── Configuration├── Integration│ ├── Azure AD│ └── Power BI (if applicable)└── Data portability ├── Export formats └── Migration guide\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ OpEx sends │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ evaluation │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ request │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /product/ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ enterprise │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Quick scan: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Is this legit?\"│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Security docs │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Architecture │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Data flow │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Encryption │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Compliance │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────┐ ┌────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ APPROVED │ │ QUESTIONS │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Proceed to │ │ Contact │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ deployment │ │ for more │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ info │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────┘ └────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ OpEx sends ││ evaluation ││ request │└────────┬────────┘ │ ▼┌─────────────────┐│ /product/ ││ enterprise ││ ││ Quick scan: ││ "Is this legit?"│└────────┬────────┘ │ ▼┌─────────────────┐│ Security docs ││ ││ - Architecture ││ - Data flow ││ - Encryption ││ - Compliance │└────────┬────────┘ │ ┌────┴────────────┐ │ │ ▼ ▼┌────────────┐ ┌────────────┐│ APPROVED │ │ QUESTIONS ││ │ │ ││ Proceed to │ │ Contact ││ deployment │ │ for more ││ │ │ info │└────────────┘ └────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"documentation-requirements\">Documentation Requirements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#documentation-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Documentation Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Erik needs:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>PDF downloadable\u003C/strong> - For internal distribution\u003C/li>\n\u003Cli>\u003Cstrong>No marketing fluff\u003C/strong> - Technical facts only\u003C/li>\n\u003Cli>\u003Cstrong>Architecture diagrams\u003C/strong> - Visual understanding\u003C/li>\n\u003Cli>\u003Cstrong>Compliance matrix\u003C/strong> - Checkbox-friendly\u003C/li>\n\u003Cli>\u003Cstrong>Version history\u003C/strong> - When docs were updated\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Enterprise page → Security docs\u003C/td>\u003Ctd>>80%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Docs download rate\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Time to approval (from first visit)\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Questions via contact form\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-flows\">Related Flows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-flows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Flows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../flows/enterprise.md\">Enterprise Flow\u003C/a> — Olivia initiates, Erik evaluates\u003C/li>\n\u003C/ul>", + { + "headings": 4674, + "localImagePaths": 4700, + "remoteImagePaths": 4701, + "frontmatter": 4702, + "imagePaths": 4703 + }, + [4675, 4677, 4680, 4681, 4682, 4685, 4688, 4691, 4694, 4695, 4698, 4699], + { "depth": 30, "slug": 4676, "text": 4664 }, + "evaluator-erik", + { "depth": 33, "slug": 4678, "text": 4679 }, + "what-erik-is-thinking", + "What Erik is thinking", + { "depth": 33, "slug": 4643, "text": 4644 }, + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4683, "text": 4684 }, + "eriks-evaluation-checklist", + "Erik’s Evaluation Checklist", + { "depth": 33, "slug": 4686, "text": 4687 }, + "information-architecture-for-erik", + "Information Architecture for Erik", + { "depth": 79, "slug": 4689, "text": 4690 }, + "must-find-quickly", + "Must Find Quickly", + { "depth": 79, "slug": 4692, "text": 4693 }, + "page-structure-needs", + "Page Structure Needs", + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 33, "slug": 4696, "text": 4697 }, + "documentation-requirements", + "Documentation Requirements", + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4655, "text": 4656 }, + [], + [], + { "title": 4664 }, + [], + "02-journeys/personas/field-fiona", + { "id": 4704, "data": 4706, "body": 4711, "filePath": 4712, "digest": 4713, "rendered": 4714 }, + { + "title": 4707, + "editUrl": 16, + "head": 4708, + "template": 18, + "sidebar": 4709, + "pagefind": 16, + "draft": 20 + }, + "Field Fiona", + [], + { "hidden": 20, "attrs": 4710 }, + {}, + "# Field Fiona\n\n| Attribute | Detail |\n| ----------------- | -------------------------------------------------- |\n| **Role** | Field Quality Engineer, manufacturing floor |\n| **Goal** | Review charts during morning meetings, on the move |\n| **Knowledge** | SPC basics, uses Teams daily, rarely at a desktop |\n| **Pain points** | Desktop tools unusable on phone, can't show charts |\n| **Decision mode** | Needs instant access, touch-friendly, readable |\n\n---\n\n## What Fiona is thinking\n\n- \"I need to check the overnight data before the standup\"\n- \"Can I pull up the Pareto on my phone in the Teams meeting?\"\n- \"The desktop layout is tiny and impossible to tap on my phone\"\n- \"I just want to see one chart at a time, nice and big\"\n\n---\n\n## 4-Phase Journey\n\n```mermaid\njourney\n title Field Fiona's Journey\n section Awareness\n Team deploys Azure App: 4: Fiona\n Admin adds Teams tab: 5: Fiona\n section Consideration\n Opens Teams on phone: 3: Fiona\n Sees carousel layout: 5: Fiona\n section Decision\n Swipes through charts: 5: Fiona\n Drills into a factor: 5: Fiona\n section Adoption\n Reviews daily on phone: 5: Fiona\n Pins findings on the go: 5: Fiona\n```\n\n---\n\n## Key Scenarios\n\n### Morning Standup (Gemba Walk)\n\n1. Open Teams app on phone\n2. Tap VariScout channel tab\n3. Swipe to I-Chart — check overnight process stability\n4. Swipe to Boxplot — compare shift performance\n5. Tap a category to drill down\n6. Pin finding for follow-up\n\n### Production Floor Check\n\n1. Walk to a machine showing issues\n2. Pull up VariScout on phone via Teams\n3. Swipe to Pareto — see top contributors\n4. Open Findings from overflow menu\n5. Add a note about observed conditions\n\n---\n\n## Device Context\n\n| Context | Device | Viewport | Interaction |\n| --------------- | ---------------- | --------------- | ------------- |\n| Morning standup | iPhone / Android | 375×667–414×896 | Touch, swipe |\n| Floor check | iPhone / Android | 375×667–414×896 | Touch, swipe |\n| Desk review | Laptop / iPad | 768×1024+ | Mouse + touch |\n\n---\n\n## Design Requirements\n\n- **One chart at a time** on phone (carousel, not stacked grid)\n- **44px minimum touch targets** on all navigation buttons\n- **Swipe navigation** between charts (native feel)\n- **Overflow menu** for toolbar actions (too many for phone header)\n- **Full-screen Findings** overlay (sidebar doesn't fit on phone)\n- **Bottom-sheet action menu** for category highlights and findings on phone", + "src/content/docs/02-journeys/personas/field-fiona.md", + "628612c7b3734ed0", + { "html": 4715, "metadata": 4716 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"field-fiona\">Field Fiona\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#field-fiona\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Field Fiona”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Field Quality Engineer, manufacturing floor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Review charts during morning meetings, on the move\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>SPC basics, uses Teams daily, rarely at a desktop\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Desktop tools unusable on phone, can’t show charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Needs instant access, touch-friendly, readable\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-fiona-is-thinking\">What Fiona is thinking\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-fiona-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Fiona is thinking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“I need to check the overnight data before the standup”\u003C/li>\n\u003Cli>“Can I pull up the Pareto on my phone in the Teams meeting?”\u003C/li>\n\u003Cli>“The desktop layout is tiny and impossible to tap on my phone”\u003C/li>\n\u003Cli>“I just want to see one chart at a time, nice and big”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-phase-journey\">4-Phase Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-phase-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4-Phase Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Field Fiona's Journey\n section Awareness\n Team deploys Azure App: 4: Fiona\n Admin adds Teams tab: 5: Fiona\n section Consideration\n Opens Teams on phone: 3: Fiona\n Sees carousel layout: 5: Fiona\n section Decision\n Swipes through charts: 5: Fiona\n Drills into a factor: 5: Fiona\n section Adoption\n Reviews daily on phone: 5: Fiona\n Pins findings on the go: 5: Fiona\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-scenarios\">Key Scenarios\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-scenarios\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Scenarios”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"morning-standup-gemba-walk\">Morning Standup (Gemba Walk)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#morning-standup-gemba-walk\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Morning Standup (Gemba Walk)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Open Teams app on phone\u003C/li>\n\u003Cli>Tap VariScout channel tab\u003C/li>\n\u003Cli>Swipe to I-Chart — check overnight process stability\u003C/li>\n\u003Cli>Swipe to Boxplot — compare shift performance\u003C/li>\n\u003Cli>Tap a category to drill down\u003C/li>\n\u003Cli>Pin finding for follow-up\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"production-floor-check\">Production Floor Check\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#production-floor-check\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Production Floor Check”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Walk to a machine showing issues\u003C/li>\n\u003Cli>Pull up VariScout on phone via Teams\u003C/li>\n\u003Cli>Swipe to Pareto — see top contributors\u003C/li>\n\u003Cli>Open Findings from overflow menu\u003C/li>\n\u003Cli>Add a note about observed conditions\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"device-context\">Device Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#device-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Device Context”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Context\u003C/th>\u003Cth>Device\u003C/th>\u003Cth>Viewport\u003C/th>\u003Cth>Interaction\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Morning standup\u003C/td>\u003Ctd>iPhone / Android\u003C/td>\u003Ctd>375×667–414×896\u003C/td>\u003Ctd>Touch, swipe\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Floor check\u003C/td>\u003Ctd>iPhone / Android\u003C/td>\u003Ctd>375×667–414×896\u003C/td>\u003Ctd>Touch, swipe\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Desk review\u003C/td>\u003Ctd>Laptop / iPad\u003C/td>\u003Ctd>768×1024+\u003C/td>\u003Ctd>Mouse + touch\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"design-requirements\">Design Requirements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#design-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>One chart at a time\u003C/strong> on phone (carousel, not stacked grid)\u003C/li>\n\u003Cli>\u003Cstrong>44px minimum touch targets\u003C/strong> on all navigation buttons\u003C/li>\n\u003Cli>\u003Cstrong>Swipe navigation\u003C/strong> between charts (native feel)\u003C/li>\n\u003Cli>\u003Cstrong>Overflow menu\u003C/strong> for toolbar actions (too many for phone header)\u003C/li>\n\u003Cli>\u003Cstrong>Full-screen Findings\u003C/strong> overlay (sidebar doesn’t fit on phone)\u003C/li>\n\u003Cli>\u003Cstrong>Bottom-sheet action menu\u003C/strong> for category highlights and findings on phone\u003C/li>\n\u003C/ul>", + { + "headings": 4717, + "localImagePaths": 4739, + "remoteImagePaths": 4740, + "frontmatter": 4741, + "imagePaths": 4742 + }, + [4718, 4720, 4723, 4724, 4727, 4730, 4733, 4736], + { "depth": 30, "slug": 4719, "text": 4707 }, + "field-fiona", + { "depth": 33, "slug": 4721, "text": 4722 }, + "what-fiona-is-thinking", + "What Fiona is thinking", + { "depth": 33, "slug": 4643, "text": 4644 }, + { "depth": 33, "slug": 4725, "text": 4726 }, + "key-scenarios", + "Key Scenarios", + { "depth": 79, "slug": 4728, "text": 4729 }, + "morning-standup-gemba-walk", + "Morning Standup (Gemba Walk)", + { "depth": 79, "slug": 4731, "text": 4732 }, + "production-floor-check", + "Production Floor Check", + { "depth": 33, "slug": 4734, "text": 4735 }, + "device-context", + "Device Context", + { "depth": 33, "slug": 4737, "text": 4738 }, + "design-requirements", + "Design Requirements", + [], + [], + { "title": 4707 }, + [], + "02-journeys/personas/green-belt-gary", + { "id": 4743, "data": 4745, "body": 4750, "filePath": 4751, "digest": 4752, "rendered": 4753 }, + { + "title": 4746, + "editUrl": 16, + "head": 4747, + "template": 18, + "sidebar": 4748, + "pagefind": 16, + "draft": 20 + }, + "Green Belt Gary", + [], + { "hidden": 20, "attrs": 4749 }, + {}, + "# Green Belt Gary\n\n| Attribute | Detail |\n| ----------------- | --------------------------------------------- |\n| **Role** | Quality Engineer, Green Belt certified |\n| **Goal** | Find better tools than Excel |\n| **Knowledge** | Knows basics, wants efficiency |\n| **Pain points** | Excel is tedious, Minitab is expensive |\n| **Decision mode** | Evaluates tool capability, ease of use, price |\n\n---\n\n## What Gary is thinking\n\n- \"I need to create a control chart but Excel is painful\"\n- \"Minitab costs too much for what I need\"\n- \"I just want something that works for basic SPC\"\n\n---\n\n## 4-Phase Journey\n\n```mermaid\njourney\n title Green Belt Gary's Journey\n section Awareness\n Google search for control charts: 3: Gary\n Find VariScout tool page: 4: Gary\n section Consideration\n Explore interactive demo: 5: Gary\n Read methodology content: 5: Gary\n section Decision\n Compare pricing options: 4: Gary\n Evaluate free PWA: 4: Gary\n section Adoption\n Install PWA application: 5: Gary\n Paste first dataset: 5: Gary\n```\n\n---\n\n## Entry Points\n\n| Search Query | Lands On | Intent |\n| ------------------------------ | ----------------- | ------------------------- |\n| \"how to read control chart\" | /tools/i-chart | Learning + tool discovery |\n| \"boxplot interpretation\" | /tools/boxplot | Specific tool help |\n| \"capability analysis tutorial\" | /tools/capability | Learning Cp/Cpk |\n| \"free control chart software\" | /tools/i-chart | Tool shopping |\n| \"Minitab alternative\" | / or /pricing | Direct comparison |\n\n---\n\n## Journey Flow\n\n```\n┌─────────────────┐\n│ Google Search │\n│ \"how to read │\n│ control chart\" │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ /tools/i-chart │\n│ │\n│ ✓ Answers query │\n│ ✓ Visual first │\n│ ✓ Demo link │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ Scrolls down │────▶ \"Try It\" Demo\n│ │\n│ Sees patterns │ Interactive\n│ section │ exploration\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ \"Two Voices\" │\n│ │\n│ Resonates with │\n│ EDA approach │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ /pricing │\n│ │\n│ │\n│ Evaluates │\n│ options │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ CONVERSION │\n│ │\n│ Tries PWA (free)│\n│ or Azure App │\n│ │\n└─────────────────┘\n```\n\n---\n\n## Key Touchpoints\n\n### Tool Page (/tools/i-chart)\n\n**Must answer in 5 seconds:** \"Does this answer my question?\"\n\nPage structure:\n\n1. **Hero:** Interactive I-Chart with sample data\n2. **What it shows:** Clear explanation of control limits, patterns\n3. **Try it section:** Demo with pre-loaded data\n4. **Two Voices:** EDA vs traditional approach (resonance point)\n5. **Next steps:** Links to related tools\n\n### Demo Interaction\n\nGary clicks around, explores the demo:\n\n- Sees linked filtering in action\n- Notices ease of use vs Excel\n- Gets curious about other features\n\n### Product/Pricing Page\n\nGary evaluates:\n\n- PWA (free) vs Azure App (€99/month Standard or €299/month Team)\n- Comparison to Minitab\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ---------------------------- | ------ |\n| Tool page → Demo interaction | >50% |\n| Demo → Product page | >15% |\n| Product page → Conversion | >10% |\n| Tool page bounce rate | \u003C60% |\n| Time on tool page | >90s |\n\n---\n\n## Related Flows\n\n- [SEO Learner Flow](../flows/seo-learner.md) — Gary's primary flow", + "src/content/docs/02-journeys/personas/green-belt-gary.md", + "b5ac4267b8271aec", + { "html": 4754, "metadata": 4755 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"green-belt-gary\">Green Belt Gary\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#green-belt-gary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Green Belt Gary”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>Quality Engineer, Green Belt certified\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Find better tools than Excel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Knows basics, wants efficiency\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Excel is tedious, Minitab is expensive\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Evaluates tool capability, ease of use, price\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-gary-is-thinking\">What Gary is thinking\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-gary-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Gary is thinking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“I need to create a control chart but Excel is painful”\u003C/li>\n\u003Cli>“Minitab costs too much for what I need”\u003C/li>\n\u003Cli>“I just want something that works for basic SPC”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-phase-journey\">4-Phase Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-phase-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4-Phase Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Green Belt Gary's Journey\n section Awareness\n Google search for control charts: 3: Gary\n Find VariScout tool page: 4: Gary\n section Consideration\n Explore interactive demo: 5: Gary\n Read methodology content: 5: Gary\n section Decision\n Compare pricing options: 4: Gary\n Evaluate free PWA: 4: Gary\n section Adoption\n Install PWA application: 5: Gary\n Paste first dataset: 5: Gary\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Search Query\u003C/th>\u003Cth>Lands On\u003C/th>\u003Cth>Intent\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”how to read control chart”\u003C/td>\u003Ctd>/tools/i-chart\u003C/td>\u003Ctd>Learning + tool discovery\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”boxplot interpretation”\u003C/td>\u003Ctd>/tools/boxplot\u003C/td>\u003Ctd>Specific tool help\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”capability analysis tutorial”\u003C/td>\u003Ctd>/tools/capability\u003C/td>\u003Ctd>Learning Cp/Cpk\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”free control chart software”\u003C/td>\u003Ctd>/tools/i-chart\u003C/td>\u003Ctd>Tool shopping\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Minitab alternative”\u003C/td>\u003Ctd>/ or /pricing\u003C/td>\u003Ctd>Direct comparison\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Google Search │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"how to read │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ control chart\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /tools/i-chart │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ✓ Answers query │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ✓ Visual first │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ✓ Demo link │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Scrolls down │────▶ \"Try It\" Demo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Sees patterns │ Interactive\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ section │ exploration\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Two Voices\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Resonates with │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ EDA approach │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /pricing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Evaluates │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ options │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CONVERSION │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Tries PWA (free)│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ or Azure App │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ Google Search ││ "how to read ││ control chart" │└────────┬────────┘ │ ▼┌─────────────────┐│ /tools/i-chart ││ ││ ✓ Answers query ││ ✓ Visual first ││ ✓ Demo link │└────────┬────────┘ │ ▼┌─────────────────┐│ Scrolls down │────▶ "Try It" Demo│ ││ Sees patterns │ Interactive│ section │ exploration└────────┬────────┘ │ ▼┌─────────────────┐│ "Two Voices" ││ ││ Resonates with ││ EDA approach │└────────┬────────┘ │ ▼┌─────────────────┐│ /pricing ││ ││ ││ Evaluates ││ options │└────────┬────────┘ │ ▼┌─────────────────┐│ CONVERSION ││ ││ Tries PWA (free)││ or Azure App ││ │└─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-touchpoints\">Key Touchpoints\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-touchpoints\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Touchpoints”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tool-page-toolsi-chart\">Tool Page (/tools/i-chart)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tool-page-toolsi-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tool Page (/tools/i-chart)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Must answer in 5 seconds:\u003C/strong> “Does this answer my question?”\u003C/p>\n\u003Cp>Page structure:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Hero:\u003C/strong> Interactive I-Chart with sample data\u003C/li>\n\u003Cli>\u003Cstrong>What it shows:\u003C/strong> Clear explanation of control limits, patterns\u003C/li>\n\u003Cli>\u003Cstrong>Try it section:\u003C/strong> Demo with pre-loaded data\u003C/li>\n\u003Cli>\u003Cstrong>Two Voices:\u003C/strong> EDA vs traditional approach (resonance point)\u003C/li>\n\u003Cli>\u003Cstrong>Next steps:\u003C/strong> Links to related tools\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"demo-interaction\">Demo Interaction\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#demo-interaction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Demo Interaction”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Gary clicks around, explores the demo:\u003C/p>\n\u003Cul>\n\u003Cli>Sees linked filtering in action\u003C/li>\n\u003Cli>Notices ease of use vs Excel\u003C/li>\n\u003Cli>Gets curious about other features\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"productpricing-page\">Product/Pricing Page\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#productpricing-page\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product/Pricing Page”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Gary evaluates:\u003C/p>\n\u003Cul>\n\u003Cli>PWA (free) vs Azure App (€99/month Standard or €299/month Team)\u003C/li>\n\u003Cli>Comparison to Minitab\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Tool page → Demo interaction\u003C/td>\u003Ctd>>50%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Demo → Product page\u003C/td>\u003Ctd>>15%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Product page → Conversion\u003C/td>\u003Ctd>>10%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tool page bounce rate\u003C/td>\u003Ctd><60%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Time on tool page\u003C/td>\u003Ctd>>90s\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-flows\">Related Flows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-flows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Flows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../flows/seo-learner.md\">SEO Learner Flow\u003C/a> — Gary’s primary flow\u003C/li>\n\u003C/ul>", + { + "headings": 4756, + "localImagePaths": 4778, + "remoteImagePaths": 4779, + "frontmatter": 4780, + "imagePaths": 4781 + }, + [4757, 4759, 4761, 4762, 4763, 4764, 4767, 4770, 4773, 4776, 4777], + { "depth": 30, "slug": 4758, "text": 4746 }, + "green-belt-gary", + { "depth": 33, "slug": 4072, "text": 4760 }, + "What Gary is thinking", + { "depth": 33, "slug": 4643, "text": 4644 }, + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 33, "slug": 4765, "text": 4766 }, + "key-touchpoints", + "Key Touchpoints", + { "depth": 79, "slug": 4768, "text": 4769 }, + "tool-page-toolsi-chart", + "Tool Page (/tools/i-chart)", + { "depth": 79, "slug": 4771, "text": 4772 }, + "demo-interaction", + "Demo Interaction", + { "depth": 79, "slug": 4774, "text": 4775 }, + "productpricing-page", + "Product/Pricing Page", + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4655, "text": 4656 }, + [], + [], + { "title": 4746 }, + [], + "02-journeys/personas/opex-olivia", + { "id": 4782, "data": 4784, "body": 4789, "filePath": 4790, "digest": 4791, "rendered": 4792 }, + { + "title": 4785, + "editUrl": 16, + "head": 4786, + "template": 18, + "sidebar": 4787, + "pagefind": 16, + "draft": 20 + }, + "OpEx Olivia", + [], + { "hidden": 20, "attrs": 4788 }, + {}, + "# OpEx Olivia\n\n| Attribute | Detail |\n| ----------------- | -------------------------------------------------- |\n| **Role** | OpEx Manager |\n| **Goal** | Find tools for team |\n| **Knowledge** | Strategic, evaluates ROI |\n| **Pain points** | Budget constraints, IT approval, change management |\n| **Decision mode** | Needs security docs, deployment guide, pricing |\n\n---\n\n## What Olivia is thinking\n\n- \"My team needs better analysis tools\"\n- \"Can I justify the cost vs Minitab?\"\n- \"What's the IT/security story?\"\n- \"How hard is deployment?\"\n\n---\n\n## 4-Phase Journey\n\n```mermaid\njourney\n title OpEx Olivia's Journey\n section Awareness\n Receive colleague referral: 4: Olivia\n Visit homepage: 4: Olivia\n section Evaluation\n Explore methodology: 5: Olivia\n Review enterprise page: 4: Olivia\n section Validation\n Check security docs: 3: Olivia\n Review pricing: 4: Olivia\n section Decision\n Self-serve purchase: 5: Olivia\n OR request consultant help: 4: Olivia\n```\n\n---\n\n## Entry Points\n\n| Source | Arrives Via | Lands On |\n| ------------------- | ------------------- | ------------- |\n| Colleague referral | Direct link | / or /pricing |\n| Conference | QR code / card | / |\n| LinkedIn | Company page / post | / or /pricing |\n| Team member request | \"Check this out\" | /pricing |\n\n---\n\n## Journey Flow\n\n```\n┌─────────────────┐\n│ Referral from │\n│ colleague or │\n│ conference │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ / (Homepage) │\n│ │\n│ Quick scan: │\n│ \"What is this?\" │\n│ \"Who is it for?\"│\n└────────┬────────┘\n │\n ┌────┴────────────┐\n │ │\n ▼ ▼\n┌────────────┐ ┌────────────┐\n│ /journey │ │ /pricing │\n│ │ │ │\n│ See the │ │ Jump to │\n│ methodology│ │ enterprise │\n└─────┬──────┘ └─────┬──────┘\n │ │\n ▼ │\n┌────────────┐ │\n│ \"I get it\" │ │\n│ Now eval │────────┘\n│ for team │\n└─────┬──────┘\n │\n ▼\n┌─────────────────┐\n│ /product/ │\n│ enterprise │\n│ │\n│ Features │\n│ Security docs │\n│ Deployment guide│\n│ Pricing │\n└────────┬────────┘\n │\n ┌────┴────────────────┐\n │ │\n ▼ ▼\n┌────────────────┐ ┌─────────────────┐\n│ SUBSCRIBE │ │ NEED HELP? │\n│ │ │ │\n│ Azure │ │ Your existing │\n│ Marketplace │ │ consultants │\n│ Managed App │ │ can assist │\n│ deploys auto │ │ │\n└────────────────┘ └─────────────────┘\n```\n\n---\n\n## Information Olivia Needs\n\n| Question | Answer Location |\n| --------------------------- | ------------------------ |\n| What does it do? | /journey, /tools |\n| Is it secure? | /product/enterprise |\n| Where's my data? | /product/enterprise |\n| How much does it cost? | /pricing |\n| How do I deploy? | /getting-started |\n| Who supports it? | /support |\n| Can I try it first? | /app (free, permanently) |\n| What training is available? | Training links |\n\n---\n\n## Enterprise Page Requirements\n\nThe /product/enterprise page must answer:\n\n### 1. Security & Compliance\n\n- Where is data stored? → \"Your Azure tenant, your data\"\n- SSO support? → Azure AD / Microsoft Entra ID\n- Compliance? → SOC 2 considerations, GDPR\n- Audit logs? → Azure native logging\n\n### 2. Deployment\n\n- How to deploy? → Azure Marketplace Managed Application\n- Time to deploy? → Minutes (Managed Application)\n- Who deploys? → Azure Marketplace handles it\n- Updates? → Automatic via Azure\n\n### 3. Pricing\n\n- Standard: €99/month — all analysis features, local file storage\n- Team: €299/month — adds OneDrive/SharePoint, Teams integration, photos\n- Both plans: unlimited users in your tenant, no per-user fees\n\n### 4. Support\n\n- Documentation-first\n- Community support (free tier)\n- Email support (paid tier)\n- \"Your existing LSS/IT consultants can assist\"\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ---------------------------- | ------ |\n| Homepage → Enterprise page | Track |\n| Enterprise page → Deployment | >5% |\n| Enterprise page → Contact | >2% |\n| Marketplace subscriptions | Track |\n\n---\n\n## Related Flows\n\n- [Enterprise Flow](../flows/enterprise.md) — Olivia's primary flow", + "src/content/docs/02-journeys/personas/opex-olivia.md", + "7834a9029869a466", + { "html": 4793, "metadata": 4794 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"opex-olivia\">OpEx Olivia\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#opex-olivia\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “OpEx Olivia”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>OpEx Manager\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Find tools for team\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Strategic, evaluates ROI\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Budget constraints, IT approval, change management\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Needs security docs, deployment guide, pricing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-olivia-is-thinking\">What Olivia is thinking\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-olivia-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Olivia is thinking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“My team needs better analysis tools”\u003C/li>\n\u003Cli>“Can I justify the cost vs Minitab?”\u003C/li>\n\u003Cli>“What’s the IT/security story?”\u003C/li>\n\u003Cli>“How hard is deployment?“\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-phase-journey\">4-Phase Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-phase-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4-Phase Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title OpEx Olivia's Journey\n section Awareness\n Receive colleague referral: 4: Olivia\n Visit homepage: 4: Olivia\n section Evaluation\n Explore methodology: 5: Olivia\n Review enterprise page: 4: Olivia\n section Validation\n Check security docs: 3: Olivia\n Review pricing: 4: Olivia\n section Decision\n Self-serve purchase: 5: Olivia\n OR request consultant help: 4: Olivia\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Source\u003C/th>\u003Cth>Arrives Via\u003C/th>\u003Cth>Lands On\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Colleague referral\u003C/td>\u003Ctd>Direct link\u003C/td>\u003Ctd>/ or /pricing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Conference\u003C/td>\u003Ctd>QR code / card\u003C/td>\u003Ctd>/\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LinkedIn\u003C/td>\u003Ctd>Company page / post\u003C/td>\u003Ctd>/ or /pricing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Team member request\u003C/td>\u003Ctd>”Check this out”\u003C/td>\u003Ctd>/pricing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Referral from │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ colleague or │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ conference │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ / (Homepage) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Quick scan: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"What is this?\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Who is it for?\"│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────┐ ┌────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /journey │ │ /pricing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ See the │ │ Jump to │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ methodology│ │ enterprise │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────┬──────┘ └─────┬──────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"I get it\" │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Now eval │────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ for team │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────┬──────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /product/ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ enterprise │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Features │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Security docs │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Deployment guide│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Pricing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────┐ ┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ SUBSCRIBE │ │ NEED HELP? │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Azure │ │ Your existing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Marketplace │ │ consultants │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Managed App │ │ can assist │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ deploys auto │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────────┘ └─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ Referral from ││ colleague or ││ conference │└────────┬────────┘ │ ▼┌─────────────────┐│ / (Homepage) ││ ││ Quick scan: ││ "What is this?" ││ "Who is it for?"│└────────┬────────┘ │ ┌────┴────────────┐ │ │ ▼ ▼┌────────────┐ ┌────────────┐│ /journey │ │ /pricing ││ │ │ ││ See the │ │ Jump to ││ methodology│ │ enterprise │└─────┬──────┘ └─────┬──────┘ │ │ ▼ │┌────────────┐ ││ "I get it" │ ││ Now eval │────────┘│ for team │└─────┬──────┘ │ ▼┌─────────────────┐│ /product/ ││ enterprise ││ ││ Features ││ Security docs ││ Deployment guide││ Pricing │└────────┬────────┘ │ ┌────┴────────────────┐ │ │ ▼ ▼┌────────────────┐ ┌─────────────────┐│ SUBSCRIBE │ │ NEED HELP? ││ │ │ ││ Azure │ │ Your existing ││ Marketplace │ │ consultants ││ Managed App │ │ can assist ││ deploys auto │ │ │└────────────────┘ └─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"information-olivia-needs\">Information Olivia Needs\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#information-olivia-needs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Information Olivia Needs”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Question\u003C/th>\u003Cth>Answer Location\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>What does it do?\u003C/td>\u003Ctd>/journey, /tools\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Is it secure?\u003C/td>\u003Ctd>/product/enterprise\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Where’s my data?\u003C/td>\u003Ctd>/product/enterprise\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>How much does it cost?\u003C/td>\u003Ctd>/pricing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>How do I deploy?\u003C/td>\u003Ctd>/getting-started\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Who supports it?\u003C/td>\u003Ctd>/support\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Can I try it first?\u003C/td>\u003Ctd>/app (free, permanently)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>What training is available?\u003C/td>\u003Ctd>Training links\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"enterprise-page-requirements\">Enterprise Page Requirements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#enterprise-page-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Enterprise Page Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The /product/enterprise page must answer:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-security--compliance\">1. Security & Compliance\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-security--compliance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Security & Compliance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Where is data stored? → “Your Azure tenant, your data”\u003C/li>\n\u003Cli>SSO support? → Azure AD / Microsoft Entra ID\u003C/li>\n\u003Cli>Compliance? → SOC 2 considerations, GDPR\u003C/li>\n\u003Cli>Audit logs? → Azure native logging\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-deployment\">2. Deployment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-deployment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Deployment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>How to deploy? → Azure Marketplace Managed Application\u003C/li>\n\u003Cli>Time to deploy? → Minutes (Managed Application)\u003C/li>\n\u003Cli>Who deploys? → Azure Marketplace handles it\u003C/li>\n\u003Cli>Updates? → Automatic via Azure\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-pricing\">3. Pricing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-pricing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Pricing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Standard: €99/month — all analysis features, local file storage\u003C/li>\n\u003Cli>Team: €299/month — adds OneDrive/SharePoint, Teams integration, photos\u003C/li>\n\u003Cli>Both plans: unlimited users in your tenant, no per-user fees\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-support\">4. Support\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Support”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Documentation-first\u003C/li>\n\u003Cli>Community support (free tier)\u003C/li>\n\u003Cli>Email support (paid tier)\u003C/li>\n\u003Cli>“Your existing LSS/IT consultants can assist”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Homepage → Enterprise page\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Enterprise page → Deployment\u003C/td>\u003Ctd>>5%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Enterprise page → Contact\u003C/td>\u003Ctd>>2%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Marketplace subscriptions\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-flows\">Related Flows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-flows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Flows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../flows/enterprise.md\">Enterprise Flow\u003C/a> — Olivia’s primary flow\u003C/li>\n\u003C/ul>", + { + "headings": 4795, + "localImagePaths": 4811, + "remoteImagePaths": 4812, + "frontmatter": 4813, + "imagePaths": 4814 + }, + [4796, 4798, 4800, 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, 4810], + { "depth": 30, "slug": 4797, "text": 4785 }, + "opex-olivia", + { "depth": 33, "slug": 4192, "text": 4799 }, + "What Olivia is thinking", + { "depth": 33, "slug": 4643, "text": 4644 }, + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 33, "slug": 4400, "text": 4401 }, + { "depth": 33, "slug": 4379, "text": 4380 }, + { "depth": 79, "slug": 4382, "text": 4383 }, + { "depth": 79, "slug": 4385, "text": 4386 }, + { "depth": 79, "slug": 4388, "text": 4389 }, + { "depth": 79, "slug": 4391, "text": 4392 }, + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4655, "text": 4656 }, + [], + [], + { "title": 4785 }, + [], + "02-journeys/personas/student-sara", + { "id": 4815, "data": 4817, "body": 4822, "filePath": 4823, "digest": 4824, "rendered": 4825 }, + { + "title": 4818, + "editUrl": 16, + "head": 4819, + "template": 18, + "sidebar": 4820, + "pagefind": 16, + "draft": 20 + }, + "Student Sara", + [], + { "hidden": 20, "attrs": 4821 }, + {}, + "# Student Sara\n\n| Attribute | Detail |\n| ----------------- | ------------------------------------------------------------- |\n| **Role** | LSS student / trainee |\n| **Goal** | Learn methodology |\n| **Knowledge** | Learning, needs guidance |\n| **Pain points** | Theory feels abstract, tools seem complex |\n| **Decision mode** | Follows instructor recommendations, looks for free/affordable |\n\n---\n\n## What Sara is thinking\n\n- \"I need to practice what I learned in class\"\n- \"The instructor mentioned this tool\"\n- \"I want to understand the concepts, not just click buttons\"\n- \"Is there a free version I can use?\"\n\n---\n\n## 4-Phase Journey\n\n```mermaid\njourney\n title Student Sara's Journey\n section Discovery\n Instructor mentions VariScout: 5: Sara\n Search for tool: 4: Sara\n section Learning\n Explore methodology content: 5: Sara\n Try case studies: 5: Sara\n section Practice\n Use demo with samples: 5: Sara\n Paste course data: 4: Sara\n section Application\n Complete assignment: 5: Sara\n Share with study group: 4: Sara\n```\n\n---\n\n## Entry Points\n\n| Source | Intent | Lands On |\n| ------------------------------- | ---------------------- | ---------------- |\n| Course link | Instructor recommended | /app or / |\n| Google \"control chart tutorial\" | Self-learning | /tools/i-chart |\n| YouTube search | Visual learning | Video → /tools/X |\n| Study group share | Peer recommendation | / or /app |\n\n---\n\n## Journey Flow\n\n```\n┌─────────────────┐\n│ Course / Class │\n│ │\n│ Instructor: │\n│ \"Try VaRiScout\" │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ / (Homepage) │\n│ │\n│ Looks for: │\n│ - Free version │\n│ - Tutorials │\n│ - Documentation │\n└────────┬────────┘\n │\n ┌────┴────────────┐\n │ │\n ▼ ▼\n┌────────────┐ ┌────────────┐\n│ /learn │ │ /cases │\n│ │ │ │\n│ Four │ │ Practice │\n│ Lenses │ │ examples │\n│ Two Voices │ │ │\n└─────┬──────┘ └─────┬──────┘\n │ │\n └───────┬───────┘\n │\n ▼\n ┌─────────────────┐\n │ /app (Demo) │\n │ │\n │ Try with │\n │ sample data │\n └────────┬────────┘\n │\n ▼\n ┌─────────────────┐\n │ Paste own │\n │ course data │\n │ │\n │ Complete │\n │ assignment │\n └─────────────────┘\n```\n\n---\n\n## Key Content Needs\n\n### Learning Resources\n\n- Clear explanations of methodology\n- Step-by-step tutorials\n- Video walkthroughs\n- Glossary of terms\n\n### Practice Opportunities\n\n- Sample datasets with known patterns\n- Case studies with \"find the answer\" format\n- Guided exercises\n\n### Assignment Support\n\n- Screenshot-friendly interface for reports\n- Clear interpretation guidance\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ------------------------------ | ------ |\n| Course referral → /app | >60% |\n| /learn → /cases | >40% |\n| Demo usage duration | >5 min |\n| Return visits (study sessions) | >3 |\n\n---\n\n## Related Flows\n\n- [SEO Learner Flow](../flows/seo-learner.md) — Self-discovery path\n- [Content & YouTube Flow](../flows/content-youtube.md) — Video learning path", + "src/content/docs/02-journeys/personas/student-sara.md", + "fc9e2184b2083607", + { "html": 4826, "metadata": 4827 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"student-sara\">Student Sara\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#student-sara\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Student Sara”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>LSS student / trainee\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Learn methodology\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Learning, needs guidance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Theory feels abstract, tools seem complex\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Follows instructor recommendations, looks for free/affordable\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-sara-is-thinking\">What Sara is thinking\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-sara-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Sara is thinking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“I need to practice what I learned in class”\u003C/li>\n\u003Cli>“The instructor mentioned this tool”\u003C/li>\n\u003Cli>“I want to understand the concepts, not just click buttons”\u003C/li>\n\u003Cli>“Is there a free version I can use?“\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-phase-journey\">4-Phase Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-phase-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4-Phase Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Student Sara's Journey\n section Discovery\n Instructor mentions VariScout: 5: Sara\n Search for tool: 4: Sara\n section Learning\n Explore methodology content: 5: Sara\n Try case studies: 5: Sara\n section Practice\n Use demo with samples: 5: Sara\n Paste course data: 4: Sara\n section Application\n Complete assignment: 5: Sara\n Share with study group: 4: Sara\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Source\u003C/th>\u003Cth>Intent\u003C/th>\u003Cth>Lands On\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Course link\u003C/td>\u003Ctd>Instructor recommended\u003C/td>\u003Ctd>/app or /\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Google “control chart tutorial”\u003C/td>\u003Ctd>Self-learning\u003C/td>\u003Ctd>/tools/i-chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>YouTube search\u003C/td>\u003Ctd>Visual learning\u003C/td>\u003Ctd>Video → /tools/X\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Study group share\u003C/td>\u003Ctd>Peer recommendation\u003C/td>\u003Ctd>/ or /app\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Course / Class │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Instructor: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Try VaRiScout\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ / (Homepage) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Looks for: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Free version │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Tutorials │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Documentation │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────┐ ┌────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /learn │ │ /cases │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Four │ │ Practice │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Lenses │ │ examples │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Two Voices │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────┬──────┘ └─────┬──────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───────┬───────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /app (Demo) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Try with │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ sample data │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Paste own │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ course data │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Complete │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ assignment │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ Course / Class ││ ││ Instructor: ││ "Try VaRiScout" │└────────┬────────┘ │ ▼┌─────────────────┐│ / (Homepage) ││ ││ Looks for: ││ - Free version ││ - Tutorials ││ - Documentation │└────────┬────────┘ │ ┌────┴────────────┐ │ │ ▼ ▼┌────────────┐ ┌────────────┐│ /learn │ │ /cases ││ │ │ ││ Four │ │ Practice ││ Lenses │ │ examples ││ Two Voices │ │ │└─────┬──────┘ └─────┬──────┘ │ │ └───────┬───────┘ │ ▼ ┌─────────────────┐ │ /app (Demo) │ │ │ │ Try with │ │ sample data │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Paste own │ │ course data │ │ │ │ Complete │ │ assignment │ └─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-content-needs\">Key Content Needs\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-content-needs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Content Needs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"learning-resources\">Learning Resources\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#learning-resources\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Learning Resources”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Clear explanations of methodology\u003C/li>\n\u003Cli>Step-by-step tutorials\u003C/li>\n\u003Cli>Video walkthroughs\u003C/li>\n\u003Cli>Glossary of terms\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"practice-opportunities\">Practice Opportunities\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#practice-opportunities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Practice Opportunities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Sample datasets with known patterns\u003C/li>\n\u003Cli>Case studies with “find the answer” format\u003C/li>\n\u003Cli>Guided exercises\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"assignment-support\">Assignment Support\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#assignment-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Assignment Support”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Screenshot-friendly interface for reports\u003C/li>\n\u003Cli>Clear interpretation guidance\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Course referral → /app\u003C/td>\u003Ctd>>60%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>/learn → /cases\u003C/td>\u003Ctd>>40%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Demo usage duration\u003C/td>\u003Ctd>>5 min\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Return visits (study sessions)\u003C/td>\u003Ctd>>3\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-flows\">Related Flows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-flows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Flows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../flows/seo-learner.md\">SEO Learner Flow\u003C/a> — Self-discovery path\u003C/li>\n\u003Cli>\u003Ca href=\"../flows/content-youtube.md\">Content & YouTube Flow\u003C/a> — Video learning path\u003C/li>\n\u003C/ul>", + { + "headings": 4828, + "localImagePaths": 4851, + "remoteImagePaths": 4852, + "frontmatter": 4853, + "imagePaths": 4854 + }, + [4829, 4831, 4834, 4835, 4836, 4837, 4840, 4843, 4846, 4849, 4850], + { "depth": 30, "slug": 4830, "text": 4818 }, + "student-sara", + { "depth": 33, "slug": 4832, "text": 4833 }, + "what-sara-is-thinking", + "What Sara is thinking", + { "depth": 33, "slug": 4643, "text": 4644 }, + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 33, "slug": 4838, "text": 4839 }, + "key-content-needs", + "Key Content Needs", + { "depth": 79, "slug": 4841, "text": 4842 }, + "learning-resources", + "Learning Resources", + { "depth": 79, "slug": 4844, "text": 4845 }, + "practice-opportunities", + "Practice Opportunities", + { "depth": 79, "slug": 4847, "text": 4848 }, + "assignment-support", + "Assignment Support", + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4655, "text": 4656 }, + [], + [], + { "title": 4818 }, + [], + "02-journeys/personas/trainer-tina", + { "id": 4855, "data": 4857, "body": 4862, "filePath": 4863, "digest": 4864, "rendered": 4865 }, + { + "title": 4858, + "editUrl": 16, + "head": 4859, + "template": 18, + "sidebar": 4860, + "pagefind": 16, + "draft": 20 + }, + "Trainer Tina", + [], + { "hidden": 20, "attrs": 4861 }, + {}, + "# Trainer Tina\n\n| Attribute | Detail |\n| ----------------- | ------------------------------------------------------------------ |\n| **Role** | LSS Trainer / Consultant |\n| **Goal** | Tools for courses & clients |\n| **Knowledge** | Expert, evaluates for students |\n| **Pain points** | Needs tools students can afford, wants consistent methodology |\n| **Decision mode** | Evaluates pedagogy, practical applicability, licensing for classes |\n\n---\n\n## What Tina is thinking\n\n- \"Is this tool aligned with how I teach?\"\n- \"Can my students afford it?\"\n- \"Does it reinforce the methodology or just push buttons?\"\n- \"How can I integrate this into my courses?\"\n\n---\n\n## 4-Phase Journey\n\n```mermaid\njourney\n title Trainer Tina's Journey\n section Awareness\n See on LinkedIn or conference: 4: Tina\n Explore methodology content: 5: Tina\n section Evaluation\n Test with own data: 5: Tina\n Review Four Lenses alignment: 5: Tina\n section Adoption\n Use in training session: 5: Tina\n Collect student feedback: 4: Tina\n section Partnership\n Recommend to clients: 5: Tina\n Explore partnership: 4: Tina\n```\n\n---\n\n## Entry Points\n\n| Source | Context | Lands On |\n| ------------------------ | --------------------------- | ------------------ |\n| LinkedIn | LSS community posts | / or /learn |\n| YouTube | Tutorial content | /tools/X |\n| Watson network | Methodology reference | /learn/four-lenses |\n| Conference | Tool demonstration | / |\n| Colleague recommendation | \"Works great in my courses\" | / |\n\n---\n\n## Tina's Evaluation Criteria\n\n### Pedagogical Alignment\n\n| Criterion | Question |\n| ------------- | ---------------------------------------------- |\n| Methodology | Does it teach the Four Lenses? |\n| Visualization | Does it show relationships, not just numbers? |\n| Exploration | Does it encourage \"clicking around\" to learn? |\n| Narrative | Does it support the \"find the story\" approach? |\n| Progressive | Does it build from simple to complex? |\n\n### Practical Considerations\n\n| Criterion | Question |\n| ------------------ | ---------------------------------------------- |\n| Student cost | Can students use it? (Permanently free PWA) |\n| Classroom use | Can I demo live without internet issues? |\n| Assignment support | Can students complete exercises with it? |\n| Export | Can students include screenshots in reports? |\n| Support | Is documentation sufficient for self-learning? |\n\n---\n\n## Journey Flow\n\n```\n┌─────────────────┐\n│ LinkedIn post │\n│ or conference │\n│ demo │\n└────────┬────────┘\n │\n ▼\n┌─────────────────┐\n│ /learn │\n│ │\n│ Four Lenses │\n│ Two Voices │\n│ EDA philosophy │\n└────────┬────────┘\n │\n ┌────┴───── \"Does this align with\n │ how I teach?\"\n │\n ▼\n┌─────────────────┐\n│ /cases │\n│ │\n│ Try case │\n│ studies with │\n│ own approach │\n└────────┬────────┘\n │\n ┌────┴───── \"Can I use this in\n │ my training?\"\n │\n ▼\n┌─────────────────┐\n│ /app │\n│ │\n│ Test with real │\n│ client data │\n│ (paste from │\n│ Excel) │\n└────────┬────────┘\n │\n ┌────┴────────────┐\n │ │\n ▼ ▼\n┌────────────┐ ┌────────────┐\n│ USE IN │ │ RECOMMEND │\n│ TRAINING │ │ TO CLIENTS │\n│ │ │ │\n│ Integrate │ │ Suggest │\n│ into │ │ as tool │\n│ curriculum │ │ for teams │\n└────────────┘ └────────────┘\n```\n\n---\n\n## Value Proposition for Trainers\n\n### Why Tina Would Choose VariScout\n\n1. **Methodology-first** - Not just charts, but the thinking behind them\n2. **EDA approach** - Aligned with practical process improvement\n3. **Permanently free PWA for students** - No barrier to classroom use\n4. **Case-based learning** - Ready-made teaching materials\n5. **Visual exploration** - Students \"discover\" rather than calculate\n\n### Partnership Opportunities\n\n- Curriculum integration materials\n- Custom branding for training organizations\n- Azure App recommendation for client teams (from €99/month)\n- Co-marketing with training courses\n\n---\n\n## Success Metrics\n\n| Metric | Target |\n| ------------------------------- | ------ |\n| /learn page engagement | >3 min |\n| /cases → /app (trainer pattern) | Track |\n| Repeat visits (course prep) | Track |\n| Student referrals from trainers | Track |\n\n---\n\n## Related Flows\n\n- [Content & YouTube Flow](../flows/content-youtube.md) — Discovery via content\n- [SEO Learner Flow](../flows/seo-learner.md) — Students Tina sends", + "src/content/docs/02-journeys/personas/trainer-tina.md", + "0262c4b7a9b889a5", + { "html": 4866, "metadata": 4867 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"trainer-tina\">Trainer Tina\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#trainer-tina\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Trainer Tina”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Role\u003C/strong>\u003C/td>\u003Ctd>LSS Trainer / Consultant\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Tools for courses & clients\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Knowledge\u003C/strong>\u003C/td>\u003Ctd>Expert, evaluates for students\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pain points\u003C/strong>\u003C/td>\u003Ctd>Needs tools students can afford, wants consistent methodology\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Decision mode\u003C/strong>\u003C/td>\u003Ctd>Evaluates pedagogy, practical applicability, licensing for classes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-tina-is-thinking\">What Tina is thinking\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-tina-is-thinking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Tina is thinking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“Is this tool aligned with how I teach?”\u003C/li>\n\u003Cli>“Can my students afford it?”\u003C/li>\n\u003Cli>“Does it reinforce the methodology or just push buttons?”\u003C/li>\n\u003Cli>“How can I integrate this into my courses?“\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-phase-journey\">4-Phase Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-phase-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4-Phase Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">journey\n title Trainer Tina's Journey\n section Awareness\n See on LinkedIn or conference: 4: Tina\n Explore methodology content: 5: Tina\n section Evaluation\n Test with own data: 5: Tina\n Review Four Lenses alignment: 5: Tina\n section Adoption\n Use in training session: 5: Tina\n Collect student feedback: 4: Tina\n section Partnership\n Recommend to clients: 5: Tina\n Explore partnership: 4: Tina\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"entry-points\">Entry Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#entry-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entry Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Source\u003C/th>\u003Cth>Context\u003C/th>\u003Cth>Lands On\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>LinkedIn\u003C/td>\u003Ctd>LSS community posts\u003C/td>\u003Ctd>/ or /learn\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>YouTube\u003C/td>\u003Ctd>Tutorial content\u003C/td>\u003Ctd>/tools/X\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Watson network\u003C/td>\u003Ctd>Methodology reference\u003C/td>\u003Ctd>/learn/four-lenses\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Conference\u003C/td>\u003Ctd>Tool demonstration\u003C/td>\u003Ctd>/\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Colleague recommendation\u003C/td>\u003Ctd>”Works great in my courses”\u003C/td>\u003Ctd>/\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tinas-evaluation-criteria\">Tina’s Evaluation Criteria\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tinas-evaluation-criteria\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tina’s Evaluation Criteria”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pedagogical-alignment\">Pedagogical Alignment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pedagogical-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pedagogical Alignment”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Question\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Methodology\u003C/td>\u003Ctd>Does it teach the Four Lenses?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Visualization\u003C/td>\u003Ctd>Does it show relationships, not just numbers?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Exploration\u003C/td>\u003Ctd>Does it encourage “clicking around” to learn?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Narrative\u003C/td>\u003Ctd>Does it support the “find the story” approach?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Progressive\u003C/td>\u003Ctd>Does it build from simple to complex?\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"practical-considerations\">Practical Considerations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#practical-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Practical Considerations”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Question\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Student cost\u003C/td>\u003Ctd>Can students use it? (Permanently free PWA)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Classroom use\u003C/td>\u003Ctd>Can I demo live without internet issues?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Assignment support\u003C/td>\u003Ctd>Can students complete exercises with it?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Export\u003C/td>\u003Ctd>Can students include screenshots in reports?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Support\u003C/td>\u003Ctd>Is documentation sufficient for self-learning?\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"journey-flow\">Journey Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#journey-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Journey Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ LinkedIn post │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ or conference │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ demo │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /learn │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Four Lenses │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Two Voices │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ EDA philosophy │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴───── \"Does this align with\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ how I teach?\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /cases │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Try case │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ studies with │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ own approach │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴───── \"Can I use this in\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ my training?\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ /app │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Test with real │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ client data │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (paste from │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Excel) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────┬────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────┐ ┌────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ USE IN │ │ RECOMMEND │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ TRAINING │ │ TO CLIENTS │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Integrate │ │ Suggest │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ into │ │ as tool │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ curriculum │ │ for teams │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────┘ └────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ LinkedIn post ││ or conference ││ demo │└────────┬────────┘ │ ▼┌─────────────────┐│ /learn ││ ││ Four Lenses ││ Two Voices ││ EDA philosophy │└────────┬────────┘ │ ┌────┴───── "Does this align with │ how I teach?" │ ▼┌─────────────────┐│ /cases ││ ││ Try case ││ studies with ││ own approach │└────────┬────────┘ │ ┌────┴───── "Can I use this in │ my training?" │ ▼┌─────────────────┐│ /app ││ ││ Test with real ││ client data ││ (paste from ││ Excel) │└────────┬────────┘ │ ┌────┴────────────┐ │ │ ▼ ▼┌────────────┐ ┌────────────┐│ USE IN │ │ RECOMMEND ││ TRAINING │ │ TO CLIENTS ││ │ │ ││ Integrate │ │ Suggest ││ into │ │ as tool ││ curriculum │ │ for teams │└────────────┘ └────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"value-proposition-for-trainers\">Value Proposition for Trainers\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#value-proposition-for-trainers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Value Proposition for Trainers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-tina-would-choose-variscout\">Why Tina Would Choose VariScout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-tina-would-choose-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Tina Would Choose VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Methodology-first\u003C/strong> - Not just charts, but the thinking behind them\u003C/li>\n\u003Cli>\u003Cstrong>EDA approach\u003C/strong> - Aligned with practical process improvement\u003C/li>\n\u003Cli>\u003Cstrong>Permanently free PWA for students\u003C/strong> - No barrier to classroom use\u003C/li>\n\u003Cli>\u003Cstrong>Case-based learning\u003C/strong> - Ready-made teaching materials\u003C/li>\n\u003Cli>\u003Cstrong>Visual exploration\u003C/strong> - Students “discover” rather than calculate\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"partnership-opportunities\">Partnership Opportunities\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#partnership-opportunities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Partnership Opportunities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Curriculum integration materials\u003C/li>\n\u003Cli>Custom branding for training organizations\u003C/li>\n\u003Cli>Azure App recommendation for client teams (from €99/month)\u003C/li>\n\u003Cli>Co-marketing with training courses\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-metrics\">Success Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>/learn page engagement\u003C/td>\u003Ctd>>3 min\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>/cases → /app (trainer pattern)\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Repeat visits (course prep)\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student referrals from trainers\u003C/td>\u003Ctd>Track\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-flows\">Related Flows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-flows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Flows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../flows/content-youtube.md\">Content & YouTube Flow\u003C/a> — Discovery via content\u003C/li>\n\u003Cli>\u003Ca href=\"../flows/seo-learner.md\">SEO Learner Flow\u003C/a> — Students Tina sends\u003C/li>\n\u003C/ul>", + { + "headings": 4868, + "localImagePaths": 4897, + "remoteImagePaths": 4898, + "frontmatter": 4899, + "imagePaths": 4900 + }, + [4869, 4871, 4874, 4875, 4876, 4879, 4882, 4885, 4886, 4889, 4892, 4895, 4896], + { "depth": 30, "slug": 4870, "text": 4858 }, + "trainer-tina", + { "depth": 33, "slug": 4872, "text": 4873 }, + "what-tina-is-thinking", + "What Tina is thinking", + { "depth": 33, "slug": 4643, "text": 4644 }, + { "depth": 33, "slug": 910, "text": 911 }, + { "depth": 33, "slug": 4877, "text": 4878 }, + "tinas-evaluation-criteria", + "Tina’s Evaluation Criteria", + { "depth": 79, "slug": 4880, "text": 4881 }, + "pedagogical-alignment", + "Pedagogical Alignment", + { "depth": 79, "slug": 4883, "text": 4884 }, + "practical-considerations", + "Practical Considerations", + { "depth": 33, "slug": 4075, "text": 4076 }, + { "depth": 33, "slug": 4887, "text": 4888 }, + "value-proposition-for-trainers", + "Value Proposition for Trainers", + { "depth": 79, "slug": 4890, "text": 4891 }, + "why-tina-would-choose-variscout", + "Why Tina Would Choose VariScout", + { "depth": 79, "slug": 4893, "text": 4894 }, + "partnership-opportunities", + "Partnership Opportunities", + { "depth": 33, "slug": 1417, "text": 1418 }, + { "depth": 33, "slug": 4655, "text": 4656 }, + [], + [], + { "title": 4858 }, + [], + "02-journeys/use-cases/batch-consistency", + { "id": 4901, "data": 4903, "body": 4908, "filePath": 4909, "digest": 4910, "rendered": 4911 }, + { + "title": 4904, + "editUrl": 16, + "head": 4905, + "template": 18, + "sidebar": 4906, + "pagefind": 16, + "draft": 20 + }, + "Batch Process Consistency", + [], + { "hidden": 20, "attrs": 4907 }, + {}, + "# Batch Process Consistency\n\n## The Problem\n\nA Process or Production Chemist runs the same recipe batch after batch — same ingredients, same settings, same procedure. But yield and purity vary. Some batches are perfect; others require rework or fail release testing. \"What's changing?\" is the question nobody can answer, because the data is recorded per batch but never analyzed across batches by factor.\n\nThe variables are numerous: raw material lot, reactor vessel, operator, ambient conditions, time-of-year. The data exists in the batch record system, but each batch is reviewed individually for release — nobody looks at the patterns across 100+ batches to find the hidden factor driving inconsistency.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ---------------------------- | ------------------------ | ---------------------------------------------------------- | ------------------------------- |\n| Process / Production Chemist | Chemical, Food, Pharma | \"batch variation analysis,\" \"batch-to-batch consistency\" | Batch records, Excel trending |\n| Production Manager | Food, Beverage, Chemical | \"batch quality variation causes,\" \"production consistency\" | Quality reports, ERP batch data |\n| Quality Engineer | Process manufacturing | \"batch process SPC,\" \"batch analysis tool\" | Manual Excel charts per batch |\n\n## Keyword Cluster\n\n**Primary:**\n\n- batch variation analysis\n- batch-to-batch consistency\n- batch process quality\n\n**Long-tail:**\n\n- why does batch quality vary with same recipe\n- batch consistency analysis tool\n- how to find cause of batch variation\n- reactor vessel comparison quality\n- raw material lot impact on batch quality\n\n**Related queries:**\n\n- SPC for batch processes\n- batch process control chart\n- process manufacturing quality tools\n- batch release trend analysis\n- chemical process variation reduction\n\n## The VariScout Journey\n\n1. **Paste batch data** — rows with Batch ID, Vessel, Material Lot, Operator, Date, Season, Yield/Purity columns\n2. **I-Chart** — batch results over time: instability visible, with clusters of good and bad batches (but no obvious time pattern)\n3. **Boxplot by Vessel** — Vessel 2 has wider spread and lower median yield. eta-squared: \"Vessel explains 22% of yield variation\"\n4. **Boxplot by Material Lot** — Supplier B's lots have higher variation. eta-squared: \"Material lot explains 31% of yield variation\"\n5. **Drill-down: Vessel 2** — boxplot by Material Lot within Vessel 2. The combination of Vessel 2 + Supplier B material = worst batches\n6. **Drill-down: Vessel 2 + Supplier B** — I-Chart shows all 8 problem batches cluster here\n7. **Capability** — Cpk overall: 0.9. Cpk excluding Vessel 2 + Supplier B: 1.4. Fixing this combination alone makes the process capable.\n\n**Aha moment:** \"Same recipe, same settings — but Vessel 2 reacts differently with Supplier B's raw material. Neither factor alone is bad enough to catch. It's the _interaction_ that kills yield. The drill-down made it obvious.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| ---------------------------------------------------- | ------------------------------------------------------ |\n| \"Same recipe, different results — we don't know why\" | Vessel 2 + Supplier B material = root cause identified |\n| Each batch reviewed individually | Cross-batch analysis reveals patterns |\n| Root cause attributed to \"normal variation\" | eta-squared quantifies factor contributions |\n| Process runs at Cpk = 0.9 (not capable) | Fixing one interaction: Cpk jumps to 1.4 |\n| Rework costs accepted as normal | Specific improvement target with measurable impact |\n\n## Website Content Map\n\n**Landing page:** `/solutions/batch-analysis`\n\n- Headline: \"Same recipe. Different results. Find out why in 30 seconds.\"\n- Key message: Cross-batch analysis reveals which vessel, material lot, or operator combination drives inconsistency\n- Interactive demo: Batch process dataset with vessel and material lot factors\n\n**Case study:** Chemical/food batch data — 100 batches, 3 vessels, 4 material lots, 5 operators\n\n- Narrative: \"They ran the same recipe 100 times. The drill-down revealed why 15% of batches failed.\"\n- eta-squared showing factor contributions\n- Interaction effect: neither factor alone is the problem\n\n**Blog posts:**\n\n- \"Batch-to-Batch Variation: It's Not Random, and Here's How to Find the Pattern\" (methodology)\n- \"SPC for Batch Processes: A Practical Guide\" (educational)\n- \"The Interaction Effect: When Two 'OK' Factors Create a Problem Together\" (advanced)\n\n**Social:**\n\n- LinkedIn: \"Same recipe, 100 batches, 15% failure rate. In 30 seconds we found the specific vessel + material combination that explained it all. Here's the analysis.\" (discovery story)\n- YouTube: \"Batch Process Variation Analysis\" — 5-minute demo\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------------ | ----------------------- | ------------------------------------------------------------------------------- |\n| Root cause investigation | **PWA** (free) | Paste batch data, find the factor combination |\n| Ongoing batch monitoring | **Excel Add-in** (free) | Connect to batch record export, trend analysis |\n| Process team | **Azure App** (paid) | Multiple chemists, Performance Mode across products/parameters, shared analysis |", + "src/content/docs/02-journeys/use-cases/batch-consistency.md", + "7b965e510276d1da", + { "html": 4912, "metadata": 4913 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"batch-process-consistency\">Batch Process Consistency\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#batch-process-consistency\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Batch Process Consistency”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A Process or Production Chemist runs the same recipe batch after batch — same ingredients, same settings, same procedure. But yield and purity vary. Some batches are perfect; others require rework or fail release testing. “What’s changing?” is the question nobody can answer, because the data is recorded per batch but never analyzed across batches by factor.\u003C/p>\n\u003Cp>The variables are numerous: raw material lot, reactor vessel, operator, ambient conditions, time-of-year. The data exists in the batch record system, but each batch is reviewed individually for release — nobody looks at the patterns across 100+ batches to find the hidden factor driving inconsistency.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Process / Production Chemist\u003C/td>\u003Ctd>Chemical, Food, Pharma\u003C/td>\u003Ctd>”batch variation analysis,” “batch-to-batch consistency”\u003C/td>\u003Ctd>Batch records, Excel trending\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Production Manager\u003C/td>\u003Ctd>Food, Beverage, Chemical\u003C/td>\u003Ctd>”batch quality variation causes,” “production consistency”\u003C/td>\u003Ctd>Quality reports, ERP batch data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quality Engineer\u003C/td>\u003Ctd>Process manufacturing\u003C/td>\u003Ctd>”batch process SPC,” “batch analysis tool”\u003C/td>\u003Ctd>Manual Excel charts per batch\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>batch variation analysis\u003C/li>\n\u003Cli>batch-to-batch consistency\u003C/li>\n\u003Cli>batch process quality\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>why does batch quality vary with same recipe\u003C/li>\n\u003Cli>batch consistency analysis tool\u003C/li>\n\u003Cli>how to find cause of batch variation\u003C/li>\n\u003Cli>reactor vessel comparison quality\u003C/li>\n\u003Cli>raw material lot impact on batch quality\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>SPC for batch processes\u003C/li>\n\u003Cli>batch process control chart\u003C/li>\n\u003Cli>process manufacturing quality tools\u003C/li>\n\u003Cli>batch release trend analysis\u003C/li>\n\u003Cli>chemical process variation reduction\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Paste batch data\u003C/strong> — rows with Batch ID, Vessel, Material Lot, Operator, Date, Season, Yield/Purity columns\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — batch results over time: instability visible, with clusters of good and bad batches (but no obvious time pattern)\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Vessel\u003C/strong> — Vessel 2 has wider spread and lower median yield. eta-squared: “Vessel explains 22% of yield variation”\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Material Lot\u003C/strong> — Supplier B’s lots have higher variation. eta-squared: “Material lot explains 31% of yield variation”\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Vessel 2\u003C/strong> — boxplot by Material Lot within Vessel 2. The combination of Vessel 2 + Supplier B material = worst batches\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Vessel 2 + Supplier B\u003C/strong> — I-Chart shows all 8 problem batches cluster here\u003C/li>\n\u003Cli>\u003Cstrong>Capability\u003C/strong> — Cpk overall: 0.9. Cpk excluding Vessel 2 + Supplier B: 1.4. Fixing this combination alone makes the process capable.\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “Same recipe, same settings — but Vessel 2 reacts differently with Supplier B’s raw material. Neither factor alone is bad enough to catch. It’s the \u003Cem>interaction\u003C/em> that kills yield. The drill-down made it obvious.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Same recipe, different results — we don’t know why”\u003C/td>\u003Ctd>Vessel 2 + Supplier B material = root cause identified\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Each batch reviewed individually\u003C/td>\u003Ctd>Cross-batch analysis reveals patterns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Root cause attributed to “normal variation”\u003C/td>\u003Ctd>eta-squared quantifies factor contributions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Process runs at Cpk = 0.9 (not capable)\u003C/td>\u003Ctd>Fixing one interaction: Cpk jumps to 1.4\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Rework costs accepted as normal\u003C/td>\u003Ctd>Specific improvement target with measurable impact\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/batch-analysis\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Same recipe. Different results. Find out why in 30 seconds.”\u003C/li>\n\u003Cli>Key message: Cross-batch analysis reveals which vessel, material lot, or operator combination drives inconsistency\u003C/li>\n\u003Cli>Interactive demo: Batch process dataset with vessel and material lot factors\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Chemical/food batch data — 100 batches, 3 vessels, 4 material lots, 5 operators\u003C/p>\n\u003Cul>\n\u003Cli>Narrative: “They ran the same recipe 100 times. The drill-down revealed why 15% of batches failed.”\u003C/li>\n\u003Cli>eta-squared showing factor contributions\u003C/li>\n\u003Cli>Interaction effect: neither factor alone is the problem\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“Batch-to-Batch Variation: It’s Not Random, and Here’s How to Find the Pattern” (methodology)\u003C/li>\n\u003Cli>“SPC for Batch Processes: A Practical Guide” (educational)\u003C/li>\n\u003Cli>“The Interaction Effect: When Two ‘OK’ Factors Create a Problem Together” (advanced)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “Same recipe, 100 batches, 15% failure rate. In 30 seconds we found the specific vessel + material combination that explained it all. Here’s the analysis.” (discovery story)\u003C/li>\n\u003Cli>YouTube: “Batch Process Variation Analysis” — 5-minute demo\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Root cause investigation\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste batch data, find the factor combination\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Ongoing batch monitoring\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to batch record export, trend analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Process team\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Multiple chemists, Performance Mode across products/parameters, shared analysis\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 4914, + "localImagePaths": 4938, + "remoteImagePaths": 4939, + "frontmatter": 4940, + "imagePaths": 4941 + }, + [4915, 4917, 4920, 4923, 4926, 4929, 4932, 4935], + { "depth": 30, "slug": 4916, "text": 4904 }, + "batch-process-consistency", + { "depth": 33, "slug": 4918, "text": 4919 }, + "the-problem", + "The Problem", + { "depth": 33, "slug": 4921, "text": 4922 }, + "target-searcher", + "Target Searcher", + { "depth": 33, "slug": 4924, "text": 4925 }, + "keyword-cluster", + "Keyword Cluster", + { "depth": 33, "slug": 4927, "text": 4928 }, + "the-variscout-journey", + "The VariScout Journey", + { "depth": 33, "slug": 4930, "text": 4931 }, + "before--after", + "Before / After", + { "depth": 33, "slug": 4933, "text": 4934 }, + "website-content-map", + "Website Content Map", + { "depth": 33, "slug": 4936, "text": 4937 }, + "platform-fit", + "Platform Fit", + [], + [], + { "title": 4904 }, + [], + "02-journeys/use-cases/bottleneck-analysis", + { "id": 4942, "data": 4944, "body": 4949, "filePath": 4950, "digest": 4951, "rendered": 4952 }, + { + "title": 4945, + "editUrl": 16, + "head": 4946, + "template": 18, + "sidebar": 4947, + "pagefind": 16, + "draft": 20 + }, + "Assembly Line Bottleneck Analysis", + [], + { "hidden": 20, "attrs": 4948 }, + {}, + "# Assembly Line Bottleneck Analysis\n\n## The Problem\n\nA Production Manager or Industrial Engineer has a line that's below throughput target. Management points at Station 3 because it has the highest average cycle time. But is that actually the bottleneck? The real bottleneck might be a station with lower average but wildly inconsistent cycle times — unpredictability starves downstream stations more than a consistently slow one.\n\nThe data exists in the MES or a cycle time spreadsheet, but it's displayed as averages and bar charts. Nobody looks at the _variation_ — and that's where the real answer hides.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ------------------------------- | -------------------------- | ------------------------------------------------------------------ | ---------------------------------- |\n| Production / IE Manager | Manufacturing, Assembly | \"bottleneck analysis manufacturing,\" \"cycle time variation\" | MES dashboards, Excel averages |\n| Continuous Improvement Engineer | Any production environment | \"production bottleneck identification,\" \"line balancing variation\" | Value stream maps, time studies |\n| Operations Supervisor | Assembly, Packaging | \"where is my bottleneck,\" \"throughput analysis\" | Gut feel, Pareto of downtime codes |\n\n## Keyword Cluster\n\n**Primary:**\n\n- bottleneck analysis manufacturing\n- cycle time variation analysis\n- production bottleneck identification\n\n**Long-tail:**\n\n- how to find bottleneck with data\n- cycle time variation vs average\n- which station is the real bottleneck\n- line balancing using variation data\n- throughput analysis beyond averages\n\n**Related queries:**\n\n- SPC for cycle times\n- control chart for production line\n- variation analysis assembly line\n- Theory of Constraints variation\n- bottleneck analysis tool free\n\n## The VariScout Journey\n\n1. **Paste cycle time data** — rows with Station, Operator, Shift, Product Variant, Cycle Time columns\n2. **I-Chart** — all stations combined shows instability (mixed signals — expected)\n3. **Boxplot by Station** — surprise: Station 2 has a wider box than Station 3. eta-squared: \"Station explains 28% of variation, but Station 2 _dominates_ the spread\"\n4. **Drill-down: Station 2** — filter, then boxplot by Operator. One operator has 3x the variation of the others\n5. **Drill-down: Station 2 + Operator B** — I-Chart shows special causes on alternating shifts\n6. **Boxplot by Product Variant** — Product Variant C takes significantly longer at Station 2 (design issue, not operator issue)\n7. **Staged analysis** — before/after the last changeover: Station 2 setup procedure is the root cause\n\n**Aha moment:** \"Station 3 has the highest average, but it's _stable_ — consistently 45 seconds. Station 2 averages 38 seconds but ranges from 25 to 70. The unpredictability in Station 2 causes waiting and starvation downstream. The bottleneck isn't where the average is highest — it's where the variation is highest.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| ------------------------------------- | --------------------------------------------------------- |\n| \"Station 3 is the bottleneck\" (wrong) | Station 2's _variation_ is the real constraint |\n| Improvement effort on wrong station | Focused effort on Station 2 setup and Operator B training |\n| Averages hide the problem | Boxplot + eta-squared reveal variation structure |\n| Days of time study analysis | 30-second paste-and-analyze |\n| No quantification of impact | \"Station 2 explains 28% of total cycle time variation\" |\n\n## Website Content Map\n\n**Landing page:** `/solutions/bottleneck-analysis`\n\n- Headline: \"Your bottleneck isn't where you think it is.\"\n- Key message: Averages point you to the wrong station. Variation analysis finds the real constraint.\n- Interactive demo: 5-station cycle time dataset\n\n**Case study:** Assembly line with 5 stations, 3 shifts, 4 operators — bottleneck case in `packages/data`\n\n- Narrative: \"Management blamed Station 3. The data told a different story.\"\n- Walk through the aggregation trap step by step\n- Show eta-squared quantifying station contribution\n\n**Blog posts:**\n\n- \"The Aggregation Trap: Why Averages Find the Wrong Bottleneck\" (methodology)\n- \"Variation Analysis for Production Lines: A 5-Minute Guide\" (educational)\n- \"Beyond Theory of Constraints: Using SPC to Find Real Bottlenecks\" (advanced)\n\n**Social:**\n\n- LinkedIn: \"We spent 3 months optimizing the wrong station. Here's how 30 seconds of data analysis would have found the real bottleneck.\" (narrative)\n- YouTube: \"The Aggregation Trap\" — 3-minute explainer with VariScout demo\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------ | ----------------------- | ------------------------------------------------------------------------------- |\n| Investigation | **PWA** (free) | Paste cycle time export, find the bottleneck in minutes |\n| Ongoing monitoring | **Excel Add-in** (free) | Connect to MES export spreadsheet, slicer by station/shift |\n| Team analysis | **Azure App** (paid) | Multiple engineers, Performance Mode across stations, shared drill-down history |", + "src/content/docs/02-journeys/use-cases/bottleneck-analysis.md", + "196a41db223920a5", + { "html": 4953, "metadata": 4954 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"assembly-line-bottleneck-analysis\">Assembly Line Bottleneck Analysis\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#assembly-line-bottleneck-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Assembly Line Bottleneck Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A Production Manager or Industrial Engineer has a line that’s below throughput target. Management points at Station 3 because it has the highest average cycle time. But is that actually the bottleneck? The real bottleneck might be a station with lower average but wildly inconsistent cycle times — unpredictability starves downstream stations more than a consistently slow one.\u003C/p>\n\u003Cp>The data exists in the MES or a cycle time spreadsheet, but it’s displayed as averages and bar charts. Nobody looks at the \u003Cem>variation\u003C/em> — and that’s where the real answer hides.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Production / IE Manager\u003C/td>\u003Ctd>Manufacturing, Assembly\u003C/td>\u003Ctd>”bottleneck analysis manufacturing,” “cycle time variation”\u003C/td>\u003Ctd>MES dashboards, Excel averages\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Continuous Improvement Engineer\u003C/td>\u003Ctd>Any production environment\u003C/td>\u003Ctd>”production bottleneck identification,” “line balancing variation”\u003C/td>\u003Ctd>Value stream maps, time studies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Operations Supervisor\u003C/td>\u003Ctd>Assembly, Packaging\u003C/td>\u003Ctd>”where is my bottleneck,” “throughput analysis”\u003C/td>\u003Ctd>Gut feel, Pareto of downtime codes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>bottleneck analysis manufacturing\u003C/li>\n\u003Cli>cycle time variation analysis\u003C/li>\n\u003Cli>production bottleneck identification\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to find bottleneck with data\u003C/li>\n\u003Cli>cycle time variation vs average\u003C/li>\n\u003Cli>which station is the real bottleneck\u003C/li>\n\u003Cli>line balancing using variation data\u003C/li>\n\u003Cli>throughput analysis beyond averages\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>SPC for cycle times\u003C/li>\n\u003Cli>control chart for production line\u003C/li>\n\u003Cli>variation analysis assembly line\u003C/li>\n\u003Cli>Theory of Constraints variation\u003C/li>\n\u003Cli>bottleneck analysis tool free\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Paste cycle time data\u003C/strong> — rows with Station, Operator, Shift, Product Variant, Cycle Time columns\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — all stations combined shows instability (mixed signals — expected)\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Station\u003C/strong> — surprise: Station 2 has a wider box than Station 3. eta-squared: “Station explains 28% of variation, but Station 2 \u003Cem>dominates\u003C/em> the spread”\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Station 2\u003C/strong> — filter, then boxplot by Operator. One operator has 3x the variation of the others\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Station 2 + Operator B\u003C/strong> — I-Chart shows special causes on alternating shifts\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Product Variant\u003C/strong> — Product Variant C takes significantly longer at Station 2 (design issue, not operator issue)\u003C/li>\n\u003Cli>\u003Cstrong>Staged analysis\u003C/strong> — before/after the last changeover: Station 2 setup procedure is the root cause\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “Station 3 has the highest average, but it’s \u003Cem>stable\u003C/em> — consistently 45 seconds. Station 2 averages 38 seconds but ranges from 25 to 70. The unpredictability in Station 2 causes waiting and starvation downstream. The bottleneck isn’t where the average is highest — it’s where the variation is highest.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Station 3 is the bottleneck” (wrong)\u003C/td>\u003Ctd>Station 2’s \u003Cem>variation\u003C/em> is the real constraint\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Improvement effort on wrong station\u003C/td>\u003Ctd>Focused effort on Station 2 setup and Operator B training\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Averages hide the problem\u003C/td>\u003Ctd>Boxplot + eta-squared reveal variation structure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Days of time study analysis\u003C/td>\u003Ctd>30-second paste-and-analyze\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No quantification of impact\u003C/td>\u003Ctd>”Station 2 explains 28% of total cycle time variation”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/bottleneck-analysis\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Your bottleneck isn’t where you think it is.”\u003C/li>\n\u003Cli>Key message: Averages point you to the wrong station. Variation analysis finds the real constraint.\u003C/li>\n\u003Cli>Interactive demo: 5-station cycle time dataset\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Assembly line with 5 stations, 3 shifts, 4 operators — bottleneck case in \u003Ccode dir=\"auto\">packages/data\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Narrative: “Management blamed Station 3. The data told a different story.”\u003C/li>\n\u003Cli>Walk through the aggregation trap step by step\u003C/li>\n\u003Cli>Show eta-squared quantifying station contribution\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“The Aggregation Trap: Why Averages Find the Wrong Bottleneck” (methodology)\u003C/li>\n\u003Cli>“Variation Analysis for Production Lines: A 5-Minute Guide” (educational)\u003C/li>\n\u003Cli>“Beyond Theory of Constraints: Using SPC to Find Real Bottlenecks” (advanced)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “We spent 3 months optimizing the wrong station. Here’s how 30 seconds of data analysis would have found the real bottleneck.” (narrative)\u003C/li>\n\u003Cli>YouTube: “The Aggregation Trap” — 3-minute explainer with VariScout demo\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Investigation\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste cycle time export, find the bottleneck in minutes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Ongoing monitoring\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to MES export spreadsheet, slicer by station/shift\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Team analysis\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Multiple engineers, Performance Mode across stations, shared drill-down history\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 4955, + "localImagePaths": 4965, + "remoteImagePaths": 4966, + "frontmatter": 4967, + "imagePaths": 4968 + }, + [4956, 4958, 4959, 4960, 4961, 4962, 4963, 4964], + { "depth": 30, "slug": 4957, "text": 4945 }, + "assembly-line-bottleneck-analysis", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 4945 }, + [], + "02-journeys/use-cases/call-center-performance", + { "id": 4969, "data": 4971, "body": 4976, "filePath": 4977, "digest": 4978, "rendered": 4979 }, + { + "title": 4972, + "editUrl": 16, + "head": 4973, + "template": 18, + "sidebar": 4974, + "pagefind": 16, + "draft": 20 + }, + "Call Center Performance Analysis", + [], + { "hidden": 20, "attrs": 4975 }, + {}, + "# Call Center Performance Analysis\n\n## The Problem\n\nAn Operations Manager oversees a call center or service desk where \"average handle time meets target.\" But customer satisfaction scores vary wildly, and some agents get far more escalations than others. The team dashboard shows aggregate metrics — AHT, first call resolution, abandon rate — but doesn't reveal _which agents_ on _which issue types_ are driving the poor outcomes.\n\nThe data is in the CRM or ACD system — thousands of call records with timestamps, agent IDs, issue categories, and resolution codes. Reports summarize by team or day. Nobody stratifies by agent + issue type to find the specific training gaps.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ---------------------- | ---------------------------- | ------------------------------------------------------------------ | --------------------------- |\n| Operations Manager | Call center, IT service desk | \"call center performance analysis,\" \"agent performance comparison\" | ACD reports, CRM dashboards |\n| Workforce Analyst | BPO, Service operations | \"AHT variation analysis,\" \"call center quality improvement\" | Excel, BI tools (averages) |\n| Quality Assurance Lead | Customer service | \"call center Six Sigma,\" \"service desk metrics analysis\" | Call monitoring, scorecards |\n\n## Keyword Cluster\n\n**Primary:**\n\n- call center performance analysis\n- agent performance comparison\n- AHT variation analysis\n\n**Long-tail:**\n\n- how to compare call center agent performance\n- call center handle time variation by agent\n- first call resolution variation analysis\n- which agents need training based on data\n- service desk performance metrics beyond averages\n\n**Related queries:**\n\n- call center quality improvement tools\n- contact center Six Sigma\n- agent coaching data analysis\n- call center SPC\n- service level variation analysis\n\n## The VariScout Journey\n\n1. **Paste call record data** — rows with Agent, Issue Category, Handle Time, Resolution (FCR/Escalation), Shift, Customer Type columns\n2. **I-Chart** — handle times over time show high variation with frequent spikes\n3. **Boxplot by Agent** — agents show very different distributions. eta-squared: \"Agent explains 41% of handle time variation.\" Some agents are consistent (narrow box); others are all over the place\n4. **Drill-down: worst agent** — boxplot by Issue Category reveals: Agent C is fine on billing issues but handle time triples on technical issues (training gap, not a bad agent)\n5. **Pareto** — escalation count by agent + issue category: Agent C + Technical = 38% of all escalations\n6. **Capability vs SLA** — against \"resolve within 10 minutes\" target: overall Cpk = 0.9, but Agent A Cpk = 1.4, Agent C Cpk = 0.3 on technical issues\n7. **I-Chart for Agent C** — over weeks, shows improvement after targeted coaching (staged analysis: before/after training)\n\n**Aha moment:** \"We thought Agent C was underperforming overall. The drill-down showed they're excellent on billing issues but struggle with technical problems. The fix isn't a performance review — it's targeted technical training. The data pinpointed the exact gap.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| -------------------------------------------- | ----------------------------------------------------------- |\n| \"Team AHT is on target\" | Agent C + Technical issues = specific gap |\n| Performance reviews based on overall metrics | Drill-down reveals issue-type-specific strengths/weaknesses |\n| Training programs are generic | Targeted coaching based on agent + issue data |\n| No quantification of agent impact | eta-squared: \"Agent explains 41% of handle time variation\" |\n| Improvement not tracked | I-Chart + staged analysis validates coaching effectiveness |\n\n## Website Content Map\n\n**Landing page:** `/solutions/call-center-quality`\n\n- Headline: \"Your average handle time is on target. But which agents on which issues are driving escalations?\"\n- Key message: Drill-down from team averages to agent + issue type reveals specific coaching opportunities\n- Interactive demo: Call center dataset with agent and issue type factors\n\n**Case study:** Service desk data — 8 agents, 5 issue categories, 3 shifts, 2 months\n\n- Narrative: \"We stopped giving generic training and started coaching the specific gaps the data revealed.\"\n- eta-squared showing agent contribution to handle time variation\n- Before/after staged analysis showing improvement post-coaching\n\n**Blog posts:**\n\n- \"Beyond AHT: Using Variation Analysis for Call Center Performance\" (methodology)\n- \"Why Agent Averages Are Misleading — and What to Measure Instead\" (educational)\n- \"Targeted Agent Coaching with Data: A Call Center Case Study\" (practical)\n\n**Social:**\n\n- LinkedIn: \"We analyzed 10,000 call records in 30 seconds. The result: Agent C isn't underperforming — they need technical training. Here's how we found the exact gap.\" (coaching story)\n- YouTube: \"Call Center Performance Drill-Down\" — 4-minute demo\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------------ | ----------------------- | ----------------------------------------------------------------- |\n| One-off analysis | **PWA** (free) | Paste CRM export, find performance patterns |\n| Regular monitoring | **Excel Add-in** (free) | Connect to ACD data export, slicer by agent/issue/shift |\n| Workforce analytics team | **Azure App** (paid) | Multiple analysts, Performance Mode across agents, trend tracking |", + "src/content/docs/02-journeys/use-cases/call-center-performance.md", + "af1f59f0bcaf4d00", + { "html": 4980, "metadata": 4981 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"call-center-performance-analysis\">Call Center Performance Analysis\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#call-center-performance-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Call Center Performance Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>An Operations Manager oversees a call center or service desk where “average handle time meets target.” But customer satisfaction scores vary wildly, and some agents get far more escalations than others. The team dashboard shows aggregate metrics — AHT, first call resolution, abandon rate — but doesn’t reveal \u003Cem>which agents\u003C/em> on \u003Cem>which issue types\u003C/em> are driving the poor outcomes.\u003C/p>\n\u003Cp>The data is in the CRM or ACD system — thousands of call records with timestamps, agent IDs, issue categories, and resolution codes. Reports summarize by team or day. Nobody stratifies by agent + issue type to find the specific training gaps.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Operations Manager\u003C/td>\u003Ctd>Call center, IT service desk\u003C/td>\u003Ctd>”call center performance analysis,” “agent performance comparison”\u003C/td>\u003Ctd>ACD reports, CRM dashboards\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Workforce Analyst\u003C/td>\u003Ctd>BPO, Service operations\u003C/td>\u003Ctd>”AHT variation analysis,” “call center quality improvement”\u003C/td>\u003Ctd>Excel, BI tools (averages)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quality Assurance Lead\u003C/td>\u003Ctd>Customer service\u003C/td>\u003Ctd>”call center Six Sigma,” “service desk metrics analysis”\u003C/td>\u003Ctd>Call monitoring, scorecards\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>call center performance analysis\u003C/li>\n\u003Cli>agent performance comparison\u003C/li>\n\u003Cli>AHT variation analysis\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to compare call center agent performance\u003C/li>\n\u003Cli>call center handle time variation by agent\u003C/li>\n\u003Cli>first call resolution variation analysis\u003C/li>\n\u003Cli>which agents need training based on data\u003C/li>\n\u003Cli>service desk performance metrics beyond averages\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>call center quality improvement tools\u003C/li>\n\u003Cli>contact center Six Sigma\u003C/li>\n\u003Cli>agent coaching data analysis\u003C/li>\n\u003Cli>call center SPC\u003C/li>\n\u003Cli>service level variation analysis\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Paste call record data\u003C/strong> — rows with Agent, Issue Category, Handle Time, Resolution (FCR/Escalation), Shift, Customer Type columns\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — handle times over time show high variation with frequent spikes\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Agent\u003C/strong> — agents show very different distributions. eta-squared: “Agent explains 41% of handle time variation.” Some agents are consistent (narrow box); others are all over the place\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: worst agent\u003C/strong> — boxplot by Issue Category reveals: Agent C is fine on billing issues but handle time triples on technical issues (training gap, not a bad agent)\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong> — escalation count by agent + issue category: Agent C + Technical = 38% of all escalations\u003C/li>\n\u003Cli>\u003Cstrong>Capability vs SLA\u003C/strong> — against “resolve within 10 minutes” target: overall Cpk = 0.9, but Agent A Cpk = 1.4, Agent C Cpk = 0.3 on technical issues\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart for Agent C\u003C/strong> — over weeks, shows improvement after targeted coaching (staged analysis: before/after training)\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “We thought Agent C was underperforming overall. The drill-down showed they’re excellent on billing issues but struggle with technical problems. The fix isn’t a performance review — it’s targeted technical training. The data pinpointed the exact gap.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Team AHT is on target”\u003C/td>\u003Ctd>Agent C + Technical issues = specific gap\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance reviews based on overall metrics\u003C/td>\u003Ctd>Drill-down reveals issue-type-specific strengths/weaknesses\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Training programs are generic\u003C/td>\u003Ctd>Targeted coaching based on agent + issue data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No quantification of agent impact\u003C/td>\u003Ctd>eta-squared: “Agent explains 41% of handle time variation”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Improvement not tracked\u003C/td>\u003Ctd>I-Chart + staged analysis validates coaching effectiveness\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/call-center-quality\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Your average handle time is on target. But which agents on which issues are driving escalations?”\u003C/li>\n\u003Cli>Key message: Drill-down from team averages to agent + issue type reveals specific coaching opportunities\u003C/li>\n\u003Cli>Interactive demo: Call center dataset with agent and issue type factors\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Service desk data — 8 agents, 5 issue categories, 3 shifts, 2 months\u003C/p>\n\u003Cul>\n\u003Cli>Narrative: “We stopped giving generic training and started coaching the specific gaps the data revealed.”\u003C/li>\n\u003Cli>eta-squared showing agent contribution to handle time variation\u003C/li>\n\u003Cli>Before/after staged analysis showing improvement post-coaching\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“Beyond AHT: Using Variation Analysis for Call Center Performance” (methodology)\u003C/li>\n\u003Cli>“Why Agent Averages Are Misleading — and What to Measure Instead” (educational)\u003C/li>\n\u003Cli>“Targeted Agent Coaching with Data: A Call Center Case Study” (practical)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “We analyzed 10,000 call records in 30 seconds. The result: Agent C isn’t underperforming — they need technical training. Here’s how we found the exact gap.” (coaching story)\u003C/li>\n\u003Cli>YouTube: “Call Center Performance Drill-Down” — 4-minute demo\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>One-off analysis\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste CRM export, find performance patterns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regular monitoring\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to ACD data export, slicer by agent/issue/shift\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Workforce analytics team\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Multiple analysts, Performance Mode across agents, trend tracking\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 4982, + "localImagePaths": 4992, + "remoteImagePaths": 4993, + "frontmatter": 4994, + "imagePaths": 4995 + }, + [4983, 4985, 4986, 4987, 4988, 4989, 4990, 4991], + { "depth": 30, "slug": 4984, "text": 4972 }, + "call-center-performance-analysis", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 4972 }, + [], + "02-journeys/use-cases/complaint-investigation", + { "id": 4996, "data": 4998, "body": 5003, "filePath": 5004, "digest": 5005, "rendered": 5006 }, + { + "title": 4999, + "editUrl": 16, + "head": 5000, + "template": 18, + "sidebar": 5001, + "pagefind": 16, + "draft": 20 + }, + "Customer Complaint Investigation", + [], + { "hidden": 20, "attrs": 5002 }, + {}, + "# Customer Complaint Investigation\n\n## The Problem\n\nA Quality Manager receives a customer complaint: \"Your product is inconsistent — the last 3 shipments were out of spec.\" The customer demands a root cause analysis and corrective action within 48 hours. The QM needs to investigate fast: What changed? Which batch? Which line? Was it a process shift, a material change, or a measurement issue?\n\nThe production data exists, but it's in a quality system or spreadsheet with thousands of rows. The QM needs to filter to the complaint period, compare it to the prior baseline, and identify what's different — all while the customer is waiting.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ------------------------------- | ----------------------- | ------------------------------------------------------------------ | ---------------------------------- |\n| Quality Manager | Any manufacturing | \"customer complaint investigation,\" \"quality complaint analysis\" | 8D reports, Excel filtering |\n| Quality Engineer | Manufacturing, Food | \"root cause analysis customer complaint,\" \"8D investigation tools\" | Fishbone diagrams, 5-Why (no data) |\n| Customer Quality Representative | Automotive, Electronics | \"quality complaint response data,\" \"corrective action analysis\" | Manual report writing |\n\n## Keyword Cluster\n\n**Primary:**\n\n- customer complaint investigation\n- quality complaint analysis\n- 8D investigation tools\n\n**Long-tail:**\n\n- how to investigate quality complaint with data\n- customer complaint root cause analysis example\n- what changed in production process\n- before and after quality analysis\n- complaint investigation SPC approach\n\n**Related queries:**\n\n- 8D problem solving tools\n- corrective action analysis manufacturing\n- process change detection SPC\n- customer complaint response template\n- variation analysis complaint period\n\n## The VariScout Journey\n\n1. **Filter production data to complaint period** — paste data, identify the suspect timeframe from customer complaint dates\n2. **I-Chart** — over the full timeline: is there a visible shift or increase in variation during the complaint period? Nelson rules flag the change point\n3. **Staged analysis: before / during / after** — quantify: \"Mean shifted from 10.2 to 10.8 during the complaint period. Variation increased 40%.\"\n4. **Boxplot by factor** — during the complaint period, what's different? Line, shift, operator, material lot. eta-squared identifies the dominant factor\n5. **Drill-down** — \"Material Lot 4872 explains 52% of the variation during the complaint period. This lot was received 2 weeks before the first complaint.\"\n6. **Capability** — Cpk during complaint period vs baseline: 1.45 → 0.78. Visual evidence for the customer showing the process was capable before and is being corrected\n7. **I-Chart post-correction** — after removing the suspect material lot: process returns to baseline. Corrective action validated.\n\n**Aha moment:** \"In 20 minutes we identified the specific material lot that caused the problem, quantified its impact, and showed the customer a before/during/after capability comparison. The 8D response that usually takes 2 weeks was done in an afternoon.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| ----------------------------------------- | ------------------------------------------------------- |\n| \"Something changed\" — vague investigation | Specific lot + factor identified with eta-squared |\n| 2-week investigation cycle | Same-day identification |\n| 8D report with fishbone and opinions | 8D report with I-Chart, capability comparison, and data |\n| Customer loses confidence | Customer sees quantified evidence and corrective action |\n| No before/after validation | Staged analysis proves correction worked |\n\n## Website Content Map\n\n**Landing page:** `/solutions/complaint-investigation`\n\n- Headline: \"Customer complaint? Find the root cause in 20 minutes, not 2 weeks.\"\n- Key message: Filter to complaint period, compare to baseline, identify the factor that changed — all with visual evidence\n- Interactive demo: Production dataset spanning before/during/after complaint period\n\n**Case study:** Manufacturing complaint — product inconsistency over 3 shipments\n\n- Narrative: \"The customer called on Monday. By Wednesday, we had the root cause, the corrective action, and the data to prove it.\"\n- Staged analysis showing clear before/during/after comparison\n- eta-squared identifying the material lot as the dominant factor\n\n**Blog posts:**\n\n- \"8D Investigations with Data: From Fishbone to Facts in 20 Minutes\" (methodology)\n- \"How to Use SPC for Customer Complaint Response\" (educational)\n- \"Before/After Analysis: Proving Your Corrective Action Worked\" (tool + methodology)\n\n**Social:**\n\n- LinkedIn: \"Customer complaint investigation used to take 2 weeks and a fishbone diagram. Now it takes 20 minutes and actual data. Here's the approach.\" (methodology story)\n- YouTube: \"Customer Complaint Investigation with VariScout\" — 5-minute walkthrough\n\n## Platform Fit\n\n| Stage | Product | Why |\n| --------------------- | ----------------------- | ----------------------------------------------------------------------- |\n| Urgent investigation | **PWA** (free) | Paste production data, filter to complaint period, find root cause fast |\n| Systematic tracking | **Excel Add-in** (free) | Connect to production quality spreadsheet, analyze by period |\n| Quality team workflow | **Azure App** (paid) | Multiple QEs investigating, shared analysis, audit trail for 8D reports |", + "src/content/docs/02-journeys/use-cases/complaint-investigation.md", + "24392619a5b5e36e", + { "html": 5007, "metadata": 5008 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"customer-complaint-investigation\">Customer Complaint Investigation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#customer-complaint-investigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Customer Complaint Investigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A Quality Manager receives a customer complaint: “Your product is inconsistent — the last 3 shipments were out of spec.” The customer demands a root cause analysis and corrective action within 48 hours. The QM needs to investigate fast: What changed? Which batch? Which line? Was it a process shift, a material change, or a measurement issue?\u003C/p>\n\u003Cp>The production data exists, but it’s in a quality system or spreadsheet with thousands of rows. The QM needs to filter to the complaint period, compare it to the prior baseline, and identify what’s different — all while the customer is waiting.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Quality Manager\u003C/td>\u003Ctd>Any manufacturing\u003C/td>\u003Ctd>”customer complaint investigation,” “quality complaint analysis”\u003C/td>\u003Ctd>8D reports, Excel filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quality Engineer\u003C/td>\u003Ctd>Manufacturing, Food\u003C/td>\u003Ctd>”root cause analysis customer complaint,” “8D investigation tools”\u003C/td>\u003Ctd>Fishbone diagrams, 5-Why (no data)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Customer Quality Representative\u003C/td>\u003Ctd>Automotive, Electronics\u003C/td>\u003Ctd>”quality complaint response data,” “corrective action analysis”\u003C/td>\u003Ctd>Manual report writing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>customer complaint investigation\u003C/li>\n\u003Cli>quality complaint analysis\u003C/li>\n\u003Cli>8D investigation tools\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to investigate quality complaint with data\u003C/li>\n\u003Cli>customer complaint root cause analysis example\u003C/li>\n\u003Cli>what changed in production process\u003C/li>\n\u003Cli>before and after quality analysis\u003C/li>\n\u003Cli>complaint investigation SPC approach\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>8D problem solving tools\u003C/li>\n\u003Cli>corrective action analysis manufacturing\u003C/li>\n\u003Cli>process change detection SPC\u003C/li>\n\u003Cli>customer complaint response template\u003C/li>\n\u003Cli>variation analysis complaint period\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Filter production data to complaint period\u003C/strong> — paste data, identify the suspect timeframe from customer complaint dates\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — over the full timeline: is there a visible shift or increase in variation during the complaint period? Nelson rules flag the change point\u003C/li>\n\u003Cli>\u003Cstrong>Staged analysis: before / during / after\u003C/strong> — quantify: “Mean shifted from 10.2 to 10.8 during the complaint period. Variation increased 40%.”\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by factor\u003C/strong> — during the complaint period, what’s different? Line, shift, operator, material lot. eta-squared identifies the dominant factor\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down\u003C/strong> — “Material Lot 4872 explains 52% of the variation during the complaint period. This lot was received 2 weeks before the first complaint.”\u003C/li>\n\u003Cli>\u003Cstrong>Capability\u003C/strong> — Cpk during complaint period vs baseline: 1.45 → 0.78. Visual evidence for the customer showing the process was capable before and is being corrected\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart post-correction\u003C/strong> — after removing the suspect material lot: process returns to baseline. Corrective action validated.\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “In 20 minutes we identified the specific material lot that caused the problem, quantified its impact, and showed the customer a before/during/after capability comparison. The 8D response that usually takes 2 weeks was done in an afternoon.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Something changed” — vague investigation\u003C/td>\u003Ctd>Specific lot + factor identified with eta-squared\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2-week investigation cycle\u003C/td>\u003Ctd>Same-day identification\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8D report with fishbone and opinions\u003C/td>\u003Ctd>8D report with I-Chart, capability comparison, and data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Customer loses confidence\u003C/td>\u003Ctd>Customer sees quantified evidence and corrective action\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No before/after validation\u003C/td>\u003Ctd>Staged analysis proves correction worked\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/complaint-investigation\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Customer complaint? Find the root cause in 20 minutes, not 2 weeks.”\u003C/li>\n\u003Cli>Key message: Filter to complaint period, compare to baseline, identify the factor that changed — all with visual evidence\u003C/li>\n\u003Cli>Interactive demo: Production dataset spanning before/during/after complaint period\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Manufacturing complaint — product inconsistency over 3 shipments\u003C/p>\n\u003Cul>\n\u003Cli>Narrative: “The customer called on Monday. By Wednesday, we had the root cause, the corrective action, and the data to prove it.”\u003C/li>\n\u003Cli>Staged analysis showing clear before/during/after comparison\u003C/li>\n\u003Cli>eta-squared identifying the material lot as the dominant factor\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“8D Investigations with Data: From Fishbone to Facts in 20 Minutes” (methodology)\u003C/li>\n\u003Cli>“How to Use SPC for Customer Complaint Response” (educational)\u003C/li>\n\u003Cli>“Before/After Analysis: Proving Your Corrective Action Worked” (tool + methodology)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “Customer complaint investigation used to take 2 weeks and a fishbone diagram. Now it takes 20 minutes and actual data. Here’s the approach.” (methodology story)\u003C/li>\n\u003Cli>YouTube: “Customer Complaint Investigation with VariScout” — 5-minute walkthrough\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Urgent investigation\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste production data, filter to complaint period, find root cause fast\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Systematic tracking\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to production quality spreadsheet, analyze by period\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quality team workflow\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Multiple QEs investigating, shared analysis, audit trail for 8D reports\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5009, + "localImagePaths": 5019, + "remoteImagePaths": 5020, + "frontmatter": 5021, + "imagePaths": 5022 + }, + [5010, 5012, 5013, 5014, 5015, 5016, 5017, 5018], + { "depth": 30, "slug": 5011, "text": 4999 }, + "customer-complaint-investigation", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 4999 }, + [], + "02-journeys/use-cases/consultant-delivery", + { "id": 5023, "data": 5025, "body": 5030, "filePath": 5031, "digest": 5032, "rendered": 5033 }, + { + "title": 5026, + "editUrl": 16, + "head": 5027, + "template": 18, + "sidebar": 5028, + "pagefind": 16, + "draft": 20 + }, + "LSS Consultant Client Delivery", + [], + { "hidden": 20, "attrs": 5029 }, + {}, + "# LSS Consultant Client Delivery\n\n## The Problem\n\nA freelance or boutique Lean Six Sigma consultant walks into a client meeting. The client has Excel spreadsheets full of production data but no analysis tools. Minitab demos require a license. The consultant needs to show value in the first 30 minutes — \"Look what's hiding in your data\" — to win the engagement.\n\nAfter the project starts, the consultant needs to teach the client team to do their own analysis. Handing them a Minitab license ($1,695/year) or teaching them Excel formulas doesn't work. The client team needs something free, immediate, and self-explanatory that they'll actually use after the consultant leaves.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ------------------------ | --------------------- | -------------------------------------------------------------- | ---------------------------------- |\n| Freelance LSS Consultant | Professional services | \"SPC tool for client presentations,\" \"free data analysis tool\" | Minitab (personal license), Excel |\n| Boutique Consulting Firm | Quality consulting | \"variation analysis demo tool,\" \"client meeting analysis tool\" | PowerPoint with screenshots, Excel |\n| Corporate CI Coach | Internal consulting | \"quality tools for teams,\" \"Six Sigma tools free\" | Internal templates, Excel macros |\n\n## Keyword Cluster\n\n**Primary:**\n\n- Six Sigma consultant tools\n- SPC tool for presentations\n- free variation analysis tool\n\n**Long-tail:**\n\n- how to show value in first client meeting\n- data analysis tool for consulting demonstrations\n- free SPC software for client handoff\n- Lean Six Sigma consultant toolkit\n- variation analysis without Minitab\n\n**Related queries:**\n\n- Minitab alternative for consulting\n- client meeting data analysis demo\n- teaching SPC to non-statisticians\n- quality consulting tools\n- SPC tools that clients can use\n\n## The VariScout Journey\n\n### The Client Meeting Demo\n\n1. **Client shares Excel file** — \"Here's our defect data from last quarter\"\n2. **Consultant opens PWA, pastes data** — 5 seconds, no login, no install\n3. **I-Chart** — \"See these spikes? Those aren't random — let me show you what's driving them.\"\n4. **Boxplot by factor** — \"46% of your variation comes from Machine 3. Did you know that?\" Client's eyes widen.\n5. **Drill-down** — \"And it's specifically Machine 3 on night shift. That's where 46% of your defects are born.\"\n6. **Pareto** — \"80% of your defect cost comes from 2 of 8 defect categories.\"\n7. **Capability** — \"Your process has a Cpk of 0.7. That means you're inherently incapable of meeting spec consistently. No amount of inspection fixes this.\"\n\n**Aha moment (client):** \"You found that in 3 minutes? We've been looking at this data for months and never saw that Machine 3 on night shift was the problem.\"\n\n### The Client Handoff\n\n8. **Share PWA link** — \"Here, bookmark this. Paste your data anytime. It's free forever.\"\n9. **Teach Four Lenses** — \"Every time you have data, ask these four questions: Change, Failure, Flow, Value.\"\n10. **Recommend Azure App** — \"When your team is ready for shared analysis and Performance Mode across all your machines, that's the next step.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| -------------------------------------------- | ----------------------------------------------------------- |\n| First meeting: PowerPoint with past projects | First meeting: live analysis of _client's own data_ |\n| Value demonstration takes weeks | Value demonstrated in 3 minutes |\n| Client dependent on consultant's Minitab | Client has free PWA for self-service analysis |\n| Teaching Excel formulas for SPC | Teaching thinking (Four Lenses), tool handles the math |\n| Post-engagement: tools abandoned | Post-engagement: PWA still accessible, no license to expire |\n| Software cost barrier for small clients | Free entry point, paid upgrade when ready |\n\n## Website Content Map\n\n**Landing page:** `/solutions/consulting`\n\n- Headline: \"Show your client what's hiding in their data. In the first 3 minutes.\"\n- Key message: Open the PWA, paste their Excel data, reveal the insight — in the meeting. Then hand them the tool for free.\n- Interactive demo: Generic manufacturing dataset showing the \"3-minute demo\" flow\n\n**Case study:** Consultant meeting scenario — client's defect data reveals machine + shift pattern\n\n- Narrative: \"The client said: 'You found that in 3 minutes? We've been looking at this data for months.'\"\n- Demonstrate the full meeting flow: paste → I-Chart → Boxplot → Drill-down → insight\n- Show the handoff: \"Here's the link. It's free forever.\"\n\n**Blog posts:**\n\n- \"How to Win a Consulting Engagement in the First 5 Minutes with Data\" (methodology)\n- \"The Best Free SPC Tool for Client Handoff\" (competitive + tool)\n- \"Teaching Variation Thinking, Not Software: A Consultant's Approach\" (thought leadership)\n\n**Social:**\n\n- LinkedIn: \"I stopped bringing PowerPoint to client meetings. I bring their data and VariScout instead. 3 minutes to insight. Here's what happened.\" (story format)\n- YouTube: \"The 3-Minute Client Demo\" — consultant workflow from paste to aha moment\n\n## Platform Fit\n\n| Stage | Product | Why |\n| -------------------- | -------------------- | ---------------------------------------------------------------------------------------- |\n| Client meeting demo | **PWA** (free) | Paste client data live, no setup, instant credibility |\n| Client self-service | **PWA** (free) | Share link — client can analyze their own data anytime |\n| Client team adoption | **Azure App** (paid) | When the team outgrows individual analysis: shared data, Performance Mode, OneDrive sync |\n\n### The Multiplier Effect\n\nConsultants are force multipliers. Each consultant introduces VariScout to 5-15 client organizations per year. The free PWA removes the objection (\"I can't afford Minitab for the whole team\"), and the Azure App captures the upgrade when teams are ready. One satisfied consultant = dozens of potential Azure subscriptions.", + "src/content/docs/02-journeys/use-cases/consultant-delivery.md", + "36b36fad4285662e", + { "html": 5034, "metadata": 5035 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"lss-consultant-client-delivery\">LSS Consultant Client Delivery\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#lss-consultant-client-delivery\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “LSS Consultant Client Delivery”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A freelance or boutique Lean Six Sigma consultant walks into a client meeting. The client has Excel spreadsheets full of production data but no analysis tools. Minitab demos require a license. The consultant needs to show value in the first 30 minutes — “Look what’s hiding in your data” — to win the engagement.\u003C/p>\n\u003Cp>After the project starts, the consultant needs to teach the client team to do their own analysis. Handing them a Minitab license ($1,695/year) or teaching them Excel formulas doesn’t work. The client team needs something free, immediate, and self-explanatory that they’ll actually use after the consultant leaves.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Freelance LSS Consultant\u003C/td>\u003Ctd>Professional services\u003C/td>\u003Ctd>”SPC tool for client presentations,” “free data analysis tool”\u003C/td>\u003Ctd>Minitab (personal license), Excel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boutique Consulting Firm\u003C/td>\u003Ctd>Quality consulting\u003C/td>\u003Ctd>”variation analysis demo tool,” “client meeting analysis tool”\u003C/td>\u003Ctd>PowerPoint with screenshots, Excel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Corporate CI Coach\u003C/td>\u003Ctd>Internal consulting\u003C/td>\u003Ctd>”quality tools for teams,” “Six Sigma tools free”\u003C/td>\u003Ctd>Internal templates, Excel macros\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Six Sigma consultant tools\u003C/li>\n\u003Cli>SPC tool for presentations\u003C/li>\n\u003Cli>free variation analysis tool\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to show value in first client meeting\u003C/li>\n\u003Cli>data analysis tool for consulting demonstrations\u003C/li>\n\u003Cli>free SPC software for client handoff\u003C/li>\n\u003Cli>Lean Six Sigma consultant toolkit\u003C/li>\n\u003Cli>variation analysis without Minitab\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Minitab alternative for consulting\u003C/li>\n\u003Cli>client meeting data analysis demo\u003C/li>\n\u003Cli>teaching SPC to non-statisticians\u003C/li>\n\u003Cli>quality consulting tools\u003C/li>\n\u003Cli>SPC tools that clients can use\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-client-meeting-demo\">The Client Meeting Demo\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-client-meeting-demo\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Client Meeting Demo”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Client shares Excel file\u003C/strong> — “Here’s our defect data from last quarter”\u003C/li>\n\u003Cli>\u003Cstrong>Consultant opens PWA, pastes data\u003C/strong> — 5 seconds, no login, no install\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — “See these spikes? Those aren’t random — let me show you what’s driving them.”\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by factor\u003C/strong> — “46% of your variation comes from Machine 3. Did you know that?” Client’s eyes widen.\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down\u003C/strong> — “And it’s specifically Machine 3 on night shift. That’s where 46% of your defects are born.”\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong> — “80% of your defect cost comes from 2 of 8 defect categories.”\u003C/li>\n\u003Cli>\u003Cstrong>Capability\u003C/strong> — “Your process has a Cpk of 0.7. That means you’re inherently incapable of meeting spec consistently. No amount of inspection fixes this.”\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment (client):\u003C/strong> “You found that in 3 minutes? We’ve been looking at this data for months and never saw that Machine 3 on night shift was the problem.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-client-handoff\">The Client Handoff\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-client-handoff\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Client Handoff”\u003C/span>\u003C/a>\u003C/div>\n\u003Col start=\"8\">\n\u003Cli>\u003Cstrong>Share PWA link\u003C/strong> — “Here, bookmark this. Paste your data anytime. It’s free forever.”\u003C/li>\n\u003Cli>\u003Cstrong>Teach Four Lenses\u003C/strong> — “Every time you have data, ask these four questions: Change, Failure, Flow, Value.”\u003C/li>\n\u003Cli>\u003Cstrong>Recommend Azure App\u003C/strong> — “When your team is ready for shared analysis and Performance Mode across all your machines, that’s the next step.”\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>First meeting: PowerPoint with past projects\u003C/td>\u003Ctd>First meeting: live analysis of \u003Cem>client’s own data\u003C/em>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Value demonstration takes weeks\u003C/td>\u003Ctd>Value demonstrated in 3 minutes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Client dependent on consultant’s Minitab\u003C/td>\u003Ctd>Client has free PWA for self-service analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Teaching Excel formulas for SPC\u003C/td>\u003Ctd>Teaching thinking (Four Lenses), tool handles the math\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Post-engagement: tools abandoned\u003C/td>\u003Ctd>Post-engagement: PWA still accessible, no license to expire\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Software cost barrier for small clients\u003C/td>\u003Ctd>Free entry point, paid upgrade when ready\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/consulting\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Show your client what’s hiding in their data. In the first 3 minutes.”\u003C/li>\n\u003Cli>Key message: Open the PWA, paste their Excel data, reveal the insight — in the meeting. Then hand them the tool for free.\u003C/li>\n\u003Cli>Interactive demo: Generic manufacturing dataset showing the “3-minute demo” flow\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Consultant meeting scenario — client’s defect data reveals machine + shift pattern\u003C/p>\n\u003Cul>\n\u003Cli>Narrative: “The client said: ‘You found that in 3 minutes? We’ve been looking at this data for months.’”\u003C/li>\n\u003Cli>Demonstrate the full meeting flow: paste → I-Chart → Boxplot → Drill-down → insight\u003C/li>\n\u003Cli>Show the handoff: “Here’s the link. It’s free forever.”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“How to Win a Consulting Engagement in the First 5 Minutes with Data” (methodology)\u003C/li>\n\u003Cli>“The Best Free SPC Tool for Client Handoff” (competitive + tool)\u003C/li>\n\u003Cli>“Teaching Variation Thinking, Not Software: A Consultant’s Approach” (thought leadership)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “I stopped bringing PowerPoint to client meetings. I bring their data and VariScout instead. 3 minutes to insight. Here’s what happened.” (story format)\u003C/li>\n\u003Cli>YouTube: “The 3-Minute Client Demo” — consultant workflow from paste to aha moment\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Client meeting demo\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste client data live, no setup, instant credibility\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Client self-service\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Share link — client can analyze their own data anytime\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Client team adoption\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>When the team outgrows individual analysis: shared data, Performance Mode, OneDrive sync\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-multiplier-effect\">The Multiplier Effect\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-multiplier-effect\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Multiplier Effect”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Consultants are force multipliers. Each consultant introduces VariScout to 5-15 client organizations per year. The free PWA removes the objection (“I can’t afford Minitab for the whole team”), and the Azure App captures the upgrade when teams are ready. One satisfied consultant = dozens of potential Azure subscriptions.\u003C/p>", + { + "headings": 5036, + "localImagePaths": 5055, + "remoteImagePaths": 5056, + "frontmatter": 5057, + "imagePaths": 5058 + }, + [5037, 5039, 5040, 5041, 5042, 5043, 5046, 5049, 5050, 5051, 5052], + { "depth": 30, "slug": 5038, "text": 5026 }, + "lss-consultant-client-delivery", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 79, "slug": 5044, "text": 5045 }, + "the-client-meeting-demo", + "The Client Meeting Demo", + { "depth": 79, "slug": 5047, "text": 5048 }, + "the-client-handoff", + "The Client Handoff", + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + { "depth": 79, "slug": 5053, "text": 5054 }, + "the-multiplier-effect", + "The Multiplier Effect", + [], + [], + { "title": 5026 }, + [], + "02-journeys/use-cases/copq-drilldown", + { "id": 5059, "data": 5061, "body": 5066, "filePath": 5067, "digest": 5068, "rendered": 5069 }, + { + "title": 5062, + "editUrl": 16, + "head": 5063, + "template": 18, + "sidebar": 5064, + "pagefind": 16, + "draft": 20 + }, + "COPQ Drill-Down", + [], + { "hidden": 20, "attrs": 5065 }, + {}, + "# COPQ Drill-Down\n\n## The Problem\n\nA Continuous Improvement or OpEx Manager knows the Cost of Poor Quality is too high — scrap, rework, warranty claims, downtime. The total number is reported monthly, but it's spread across products, lines, defect types, and shifts. Where should the next improvement project focus? Leadership wants a business case with specific targets, not \"we'll work on quality.\"\n\nThe data exists in the ERP or quality system, but it's summarized in monthly reports — total scrap cost by department. Nobody drills into the interaction effects: which _specific combination_ of product + line + shift + defect type drives the most cost?\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ----------------- | ----------------- | -------------------------------------------------------------- | ---------------------------------- |\n| CI / OpEx Manager | Any manufacturing | \"cost of poor quality analysis,\" \"COPQ reduction\" | ERP reports, Excel pivot tables |\n| Quality Manager | Manufacturing | \"scrap analysis by factor,\" \"defect Pareto analysis\" | Monthly quality reports |\n| Plant Manager | Manufacturing | \"where to focus improvement project,\" \"quality cost breakdown\" | Management dashboards (aggregated) |\n\n## Keyword Cluster\n\n**Primary:**\n\n- cost of poor quality analysis\n- COPQ reduction tools\n- scrap analysis by factor\n\n**Long-tail:**\n\n- how to prioritize quality improvement projects\n- Pareto analysis defect cost example\n- scrap cost breakdown by product and line\n- COPQ drill-down methodology\n- where to focus improvement efforts with data\n\n**Related queries:**\n\n- Pareto chart cost of quality\n- defect analysis manufacturing\n- quality cost categories analysis\n- Six Sigma project selection tool\n- cost of poor quality is 20% of revenue\n\n## The VariScout Journey\n\n1. **Paste COPQ data** — rows with Product, Line, Shift, Defect Type, Cost (or defect count) columns\n2. **Pareto** — rank defect types by cost. \"Dimensional out-of-spec\" = 42% of total COPQ. Clear starting point\n3. **Boxplot by Line** — for the top defect type: which line contributes most? eta-squared: \"Line explains 35% of variation in this defect\"\n4. **Drill-down: Line 2** — filter to worst line, boxplot by Shift. Night shift has 2.5x the defect rate\n5. **Drill-down: Line 2 + Night shift** — boxplot by Product. Product X dominates\n6. **I-Chart** — over time: did this start recently (assignable cause) or is it chronic?\n7. **Staged analysis** — if a change was made: before/after validates improvement\n\n**The Pareto path:** Total COPQ ($2.4M) → Dimensional OOS ($1.0M, 42%) → Line 2 ($580K, 58% of that) → Night shift ($380K, 66% of that) → Product X ($290K, 76% of that). Improvement project target: $290K annually from one specific combination.\n\n**Aha moment:** \"Our total COPQ is $2.4M/year and it felt overwhelming. 30 seconds of drill-down showed us that one product on one line on one shift accounts for $290K. That's a focused improvement project with a clear business case.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| ---------------------------------------------- | --------------------------------------------------------- |\n| \"COPQ is $2.4M — where do we start?\" | \"Product X + Line 2 + Night shift = $290K target\" |\n| Improvement project based on loudest complaint | Data-driven project selection with specific dollar impact |\n| Monthly summary reports hide the structure | Pareto → Boxplot → Drill-down reveals the path |\n| No quantification of factor contribution | eta-squared: \"Line explains 35% of this defect type\" |\n| Weeks to build analysis for management review | 30-second analysis with visual evidence for business case |\n\n## Website Content Map\n\n**Landing page:** `/solutions/copq-analysis`\n\n- Headline: \"Your COPQ is $2.4M. In 30 seconds, we'll show you where $290K of it comes from.\"\n- Key message: Drill-down from total cost to specific product + line + shift combination\n- Interactive demo: COPQ dataset with multi-level drill-down\n\n**Case study:** Manufacturing COPQ dataset — 5 products, 3 lines, 3 shifts, 8 defect types, 12 months\n\n- Walk through the Pareto cascade: total → defect → line → shift → product\n- Show dollar values narrowing at each level\n- Business case format: \"This improvement project targets $290K/year\"\n\n**Blog posts:**\n\n- \"COPQ Is 20% of Revenue. Here's How to Find the 20% of COPQ That Matters.\" (methodology)\n- \"From $2.4M to $290K: A COPQ Drill-Down Example\" (case study format)\n- \"Pareto Analysis Isn't Enough — You Need the Second Drill-Down\" (advanced)\n\n**Social:**\n\n- LinkedIn: \"Every manufacturer knows COPQ is too high. Few know exactly where it comes from. Here's a 30-second analysis that finds the needle in the haystack.\" (visual cascade)\n- YouTube: \"COPQ Drill-Down: Finding $290K in 30 Seconds\" — step-by-step demo\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------ | ----------------------- | --------------------------------------------------------------------------- |\n| Project selection | **PWA** (free) | Paste COPQ data, find the biggest opportunity in minutes |\n| Ongoing tracking | **Excel Add-in** (free) | Connect to quality cost spreadsheet, slicer by period/product/line |\n| OpEx team workflow | **Azure App** (paid) | Multiple analysts, Performance Mode across cost categories, shared analysis |", + "src/content/docs/02-journeys/use-cases/copq-drilldown.md", + "84b88f36eb91e25e", + { "html": 5070, "metadata": 5071 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"copq-drill-down\">COPQ Drill-Down\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#copq-drill-down\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “COPQ Drill-Down”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A Continuous Improvement or OpEx Manager knows the Cost of Poor Quality is too high — scrap, rework, warranty claims, downtime. The total number is reported monthly, but it’s spread across products, lines, defect types, and shifts. Where should the next improvement project focus? Leadership wants a business case with specific targets, not “we’ll work on quality.”\u003C/p>\n\u003Cp>The data exists in the ERP or quality system, but it’s summarized in monthly reports — total scrap cost by department. Nobody drills into the interaction effects: which \u003Cem>specific combination\u003C/em> of product + line + shift + defect type drives the most cost?\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>CI / OpEx Manager\u003C/td>\u003Ctd>Any manufacturing\u003C/td>\u003Ctd>”cost of poor quality analysis,” “COPQ reduction”\u003C/td>\u003Ctd>ERP reports, Excel pivot tables\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quality Manager\u003C/td>\u003Ctd>Manufacturing\u003C/td>\u003Ctd>”scrap analysis by factor,” “defect Pareto analysis”\u003C/td>\u003Ctd>Monthly quality reports\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Plant Manager\u003C/td>\u003Ctd>Manufacturing\u003C/td>\u003Ctd>”where to focus improvement project,” “quality cost breakdown”\u003C/td>\u003Ctd>Management dashboards (aggregated)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>cost of poor quality analysis\u003C/li>\n\u003Cli>COPQ reduction tools\u003C/li>\n\u003Cli>scrap analysis by factor\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to prioritize quality improvement projects\u003C/li>\n\u003Cli>Pareto analysis defect cost example\u003C/li>\n\u003Cli>scrap cost breakdown by product and line\u003C/li>\n\u003Cli>COPQ drill-down methodology\u003C/li>\n\u003Cli>where to focus improvement efforts with data\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Pareto chart cost of quality\u003C/li>\n\u003Cli>defect analysis manufacturing\u003C/li>\n\u003Cli>quality cost categories analysis\u003C/li>\n\u003Cli>Six Sigma project selection tool\u003C/li>\n\u003Cli>cost of poor quality is 20% of revenue\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Paste COPQ data\u003C/strong> — rows with Product, Line, Shift, Defect Type, Cost (or defect count) columns\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong> — rank defect types by cost. “Dimensional out-of-spec” = 42% of total COPQ. Clear starting point\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Line\u003C/strong> — for the top defect type: which line contributes most? eta-squared: “Line explains 35% of variation in this defect”\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Line 2\u003C/strong> — filter to worst line, boxplot by Shift. Night shift has 2.5x the defect rate\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Line 2 + Night shift\u003C/strong> — boxplot by Product. Product X dominates\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — over time: did this start recently (assignable cause) or is it chronic?\u003C/li>\n\u003Cli>\u003Cstrong>Staged analysis\u003C/strong> — if a change was made: before/after validates improvement\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>The Pareto path:\u003C/strong> Total COPQ ($2.4M) → Dimensional OOS ($1.0M, 42%) → Line 2 ($580K, 58% of that) → Night shift ($380K, 66% of that) → Product X ($290K, 76% of that). Improvement project target: $290K annually from one specific combination.\u003C/p>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “Our total COPQ is $2.4M/year and it felt overwhelming. 30 seconds of drill-down showed us that one product on one line on one shift accounts for $290K. That’s a focused improvement project with a clear business case.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”COPQ is $2.4M — where do we start?\"\u003C/td>\u003Ctd>\"Product X + Line 2 + Night shift = $290K target”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Improvement project based on loudest complaint\u003C/td>\u003Ctd>Data-driven project selection with specific dollar impact\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Monthly summary reports hide the structure\u003C/td>\u003Ctd>Pareto → Boxplot → Drill-down reveals the path\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No quantification of factor contribution\u003C/td>\u003Ctd>eta-squared: “Line explains 35% of this defect type”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Weeks to build analysis for management review\u003C/td>\u003Ctd>30-second analysis with visual evidence for business case\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/copq-analysis\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Your COPQ is $2.4M. In 30 seconds, we’ll show you where $290K of it comes from.”\u003C/li>\n\u003Cli>Key message: Drill-down from total cost to specific product + line + shift combination\u003C/li>\n\u003Cli>Interactive demo: COPQ dataset with multi-level drill-down\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Manufacturing COPQ dataset — 5 products, 3 lines, 3 shifts, 8 defect types, 12 months\u003C/p>\n\u003Cul>\n\u003Cli>Walk through the Pareto cascade: total → defect → line → shift → product\u003C/li>\n\u003Cli>Show dollar values narrowing at each level\u003C/li>\n\u003Cli>Business case format: “This improvement project targets $290K/year”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“COPQ Is 20% of Revenue. Here’s How to Find the 20% of COPQ That Matters.” (methodology)\u003C/li>\n\u003Cli>“From $2.4M to $290K: A COPQ Drill-Down Example” (case study format)\u003C/li>\n\u003Cli>“Pareto Analysis Isn’t Enough — You Need the Second Drill-Down” (advanced)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “Every manufacturer knows COPQ is too high. Few know exactly where it comes from. Here’s a 30-second analysis that finds the needle in the haystack.” (visual cascade)\u003C/li>\n\u003Cli>YouTube: “COPQ Drill-Down: Finding $290K in 30 Seconds” — step-by-step demo\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Project selection\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste COPQ data, find the biggest opportunity in minutes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Ongoing tracking\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to quality cost spreadsheet, slicer by period/product/line\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx team workflow\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Multiple analysts, Performance Mode across cost categories, shared analysis\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5072, + "localImagePaths": 5082, + "remoteImagePaths": 5083, + "frontmatter": 5084, + "imagePaths": 5085 + }, + [5073, 5075, 5076, 5077, 5078, 5079, 5080, 5081], + { "depth": 30, "slug": 5074, "text": 5062 }, + "copq-drill-down", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 5062 }, + [], + "02-journeys/use-cases", + { "id": 5086, "data": 5088, "body": 5092, "filePath": 5093, "digest": 5094, "rendered": 5095 }, + { + "title": 908, + "editUrl": 16, + "head": 5089, + "template": 18, + "sidebar": 5090, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 5091 }, + {}, + "# Use Cases\n\nStrategic use cases grounded in VariScout's actual capabilities. Each describes a specific problem that brings searchers to VariScout, the analysis journey they take, and website content opportunities.\n\nThese use cases complement the [personas](../personas/) (who finds VariScout) by describing **what problems bring them in**.\n\n---\n\n## SEO Scoring\n\nEach use case is scored across five dimensions (1-5 scale):\n\n- **Volume** — Monthly search volume for primary keywords\n- **Intent** — How likely the searcher is to need a tool (not just information)\n- **Competition** — Inverse: lower competition = higher score opportunity\n- **Content Fit** — How well VariScout's features solve the stated problem\n- **Keyword Cluster** — Breadth of related queries that can be targeted\n\n| Pick | Use Case | Volume | Intent | Comp. | Fit | Cluster | **Score** | Industry |\n| ---- | ----------------------------------------------------- | ------ | ------ | ----- | --- | ------- | --------- | --------------------- |\n| 1 | [Supplier Performance](supplier-performance.md) | 5 | 5 | 4 | 5 | 5 | **24** | Supply Chain |\n| 2 | [University SPC](university-spc.md) | 5 | 5 | 4 | 5 | 5 | **24** | Education |\n| 3 | [Assembly Bottleneck](bottleneck-analysis.md) | 4 | 4 | 4 | 5 | 5 | **22** | Manufacturing |\n| 4 | [Supplier PPAP](supplier-ppap.md) | 4 | 5 | 3 | 5 | 5 | **22** | Automotive |\n| 5 | [COPQ Drill-Down](copq-drilldown.md) | 4 | 5 | 3 | 5 | 4 | **21** | Cross-industry |\n| 6 | [Customer Complaint](complaint-investigation.md) | 4 | 4 | 4 | 5 | 4 | **21** | Cross-industry |\n| 7 | [Patient Wait Time](patient-wait-time.md) | 4 | 3 | 3 | 4 | 4 | **18** | Healthcare |\n| 8 | [Call Center Performance](call-center-performance.md) | 4 | 3 | 4 | 3 | 4 | **18** | Service Ops |\n| 9 | [On-Time Delivery](on-time-delivery.md) | 3 | 3 | 3 | 3 | 3 | **15** | Logistics |\n| 10 | [Pharma OOS](pharma-oos.md) | 3 | 5 | 3 | 4 | 4 | **19** | Pharma |\n| 11 | [Consultant Delivery](consultant-delivery.md) | 3 | 4 | 2 | 5 | 3 | **17** | Professional Services |\n| 12 | [Batch Consistency](batch-consistency.md) | 3 | 4 | 3 | 4 | 4 | **18** | Food / Chemical |\n| 13 | [Lead Time Variation](lead-time-variation.md) | 4 | 4 | 3 | 4 | 4 | **19** | Supply Chain |\n\n---\n\n## Theme Groupings\n\n### Drill-Down Reveals Hidden Structure\n\nUse cases where averages mislead and stratification exposes the real story.\n\n| Use Case | The Misleading Average | What Drill-Down Reveals |\n| ----------------------------------------------------- | ---------------------------------- | ------------------------------------------------------------- |\n| [Supplier Performance](supplier-performance.md) | \"All suppliers meet spec\" | Supplier C fails dimension B; 80% of rejects from 2 suppliers |\n| [COPQ Drill-Down](copq-drilldown.md) | \"Scrap is 3% overall\" | Product X + Line 2 + Night shift = 52% of total COPQ |\n| [Batch Consistency](batch-consistency.md) | \"Same recipe, same result\" | Vessel 2 + Supplier B raw material = poor batches |\n| [Call Center Performance](call-center-performance.md) | \"Average handle time meets target\" | Agent C + Issue Type 3 = specific training gap |\n\n### The Aggregation Trap\n\nUse cases where the overall metric hides critical variation.\n\n| Use Case | The Aggregated Metric | What's Hidden |\n| --------------------------------------------- | ------------------------------------ | -------------------------------------------------------------------- |\n| [Assembly Bottleneck](bottleneck-analysis.md) | \"Station 3 has highest average time\" | Station 2 has 3x the variation — unpredictability is the bottleneck |\n| [Patient Wait Time](patient-wait-time.md) | \"Average wait: 45 minutes\" | Night shift: 95% utilization, 2-hour waits hidden by daytime lulls |\n| [Lead Time Variation](lead-time-variation.md) | \"Average lead time: 5 days\" | Supplier X fine for small orders, wildly inconsistent for large ones |\n\n### Multi-Channel Capability\n\nUse cases that leverage Performance Mode to compare parallel processes.\n\n| Use Case | The Channels | Key Metric |\n| --------------------------------- | ----------------------------------- | ------------------------------------------- |\n| [Supplier PPAP](supplier-ppap.md) | Critical characteristics / cavities | Cpk per characteristic, worst-first ranking |\n| [Pharma OOS](pharma-oos.md) | Batches / analysts / instruments | Cpk vs acceptance criteria |\n\n### Capability vs SLA\n\nUse cases where process capability is measured against a service target.\n\n| Use Case | The SLA | Capability Question |\n| ------------------------------------------------ | --------------------- | ------------------------------------------ |\n| [On-Time Delivery](on-time-delivery.md) | Deliver within 3 days | Which carrier/route/product fails the SLA? |\n| [Customer Complaint](complaint-investigation.md) | Product consistency | What changed during the complaint period? |\n\n### Education & Adoption\n\nUse cases focused on learning methodology and spreading tool adoption.\n\n| Use Case | Entry Point | Conversion Path |\n| --------------------------------------------- | -------------------- | --------------------------------------------- |\n| [University SPC](university-spc.md) | Course link / Google | Free PWA forever, case studies as assignments |\n| [Consultant Delivery](consultant-delivery.md) | Client meeting demo | Free PWA for client, Azure App for team |\n\n---\n\n## Content Phasing\n\n### Phase 1 — Core, Highest SEO Impact\n\n| Use Case | SEO Score | Priority Reason |\n| ------------------------------------------------ | --------- | ------------------------------------------------------ |\n| [Supplier Performance](supplier-performance.md) | 24 | Massive keyword cluster, growing supply chain interest |\n| [University SPC](university-spc.md) | 24 | Highest volume, direct PWA conversion |\n| [Assembly Bottleneck](bottleneck-analysis.md) | 22 | Cross-industry appeal, compelling narrative |\n| [Supplier PPAP](supplier-ppap.md) | 22 | High-intent automotive, buyers know what they need |\n| [COPQ Drill-Down](copq-drilldown.md) | 21 | High-value keyword, universal manufacturing pain |\n| [Customer Complaint](complaint-investigation.md) | 21 | Universal, every manufacturer searches this |\n\n### Phase 2 — Founder Stories & Services\n\n| Use Case | SEO Score | Priority Reason |\n| ----------------------------------------------------- | --------- | ---------------------------------------------- |\n| [Patient Wait Time](patient-wait-time.md) | 18 | Founder hospital experience, authentic stories |\n| [Call Center Performance](call-center-performance.md) | 18 | Founder call center experience, credibility |\n| [On-Time Delivery](on-time-delivery.md) | 15 | Distinct logistics angle, OTD as universal KPI |\n\n### Phase 3 — Niche & Multiplier\n\n| Use Case | SEO Score | Priority Reason |\n| --------------------------------------------- | --------- | --------------------------------------------------------------- |\n| [Pharma OOS](pharma-oos.md) | 19 | High intent, regulated industry |\n| [Consultant Delivery](consultant-delivery.md) | 17 | Multiplier effect — consultants bring VariScout to every client |\n| [Batch Consistency](batch-consistency.md) | 18 | Broad manufacturing / food appeal |\n| [Lead Time Variation](lead-time-variation.md) | 19 | Growing supply chain interest |\n\n---\n\n## Industry Coverage\n\n| Industry | Use Cases | Count |\n| --------------------- | ----------------------------------------- | ----- |\n| Manufacturing | Bottleneck, Batch Consistency | 2 |\n| Supply Chain | Supplier Performance, Lead Time Variation | 2 |\n| Automotive | Supplier PPAP | 1 |\n| Pharma | Pharma OOS | 1 |\n| Education | University SPC | 1 |\n| Food / Chemical | Batch Consistency | 1 |\n| Healthcare | Patient Wait Time | 1 |\n| Service Operations | Call Center Performance | 1 |\n| Logistics | On-Time Delivery | 1 |\n| Professional Services | Consultant Delivery | 1 |\n| Cross-industry | COPQ, Customer Complaint | 2 |\n\n---\n\n## Relationship to Personas\n\nThese use cases describe **problems**; [personas](../personas/) describe **people**. They work together:\n\n| Persona | Most Likely Use Cases |\n| --------------- | --------------------------------------------------------- |\n| Green Belt Gary | Supplier Performance, COPQ, Bottleneck, Batch Consistency |\n| Curious Carlos | Bottleneck, Customer Complaint, Lead Time |\n| Student Sara | University SPC |\n| Trainer Tina | University SPC, Consultant Delivery |\n| OpEx Olivia | COPQ, Supplier PPAP, Multi-site (future) |\n| Evaluator Erik | Supplier Performance, Patient Wait Time, Call Center |", + "src/content/docs/02-journeys/use-cases/index.md", + "1936100fe5382005", + { "html": 5096, "metadata": 5097 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"use-cases\">Use Cases\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#use-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Cases”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Strategic use cases grounded in VariScout’s actual capabilities. Each describes a specific problem that brings searchers to VariScout, the analysis journey they take, and website content opportunities.\u003C/p>\n\u003Cp>These use cases complement the \u003Ca href=\"../personas/\">personas\u003C/a> (who finds VariScout) by describing \u003Cstrong>what problems bring them in\u003C/strong>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"seo-scoring\">SEO Scoring\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#seo-scoring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SEO Scoring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each use case is scored across five dimensions (1-5 scale):\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Volume\u003C/strong> — Monthly search volume for primary keywords\u003C/li>\n\u003Cli>\u003Cstrong>Intent\u003C/strong> — How likely the searcher is to need a tool (not just information)\u003C/li>\n\u003Cli>\u003Cstrong>Competition\u003C/strong> — Inverse: lower competition = higher score opportunity\u003C/li>\n\u003Cli>\u003Cstrong>Content Fit\u003C/strong> — How well VariScout’s features solve the stated problem\u003C/li>\n\u003Cli>\u003Cstrong>Keyword Cluster\u003C/strong> — Breadth of related queries that can be targeted\u003C/li>\n\u003C/ul>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pick\u003C/th>\u003Cth>Use Case\u003C/th>\u003Cth>Volume\u003C/th>\u003Cth>Intent\u003C/th>\u003Cth>Comp.\u003C/th>\u003Cth>Fit\u003C/th>\u003Cth>Cluster\u003C/th>\u003Cth>\u003Cstrong>Score\u003C/strong>\u003C/th>\u003Cth>Industry\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>\u003Ca href=\"supplier-performance.md\">Supplier Performance\u003C/a>\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>\u003Cstrong>24\u003C/strong>\u003C/td>\u003Ctd>Supply Chain\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>\u003Ca href=\"university-spc.md\">University SPC\u003C/a>\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>\u003Cstrong>24\u003C/strong>\u003C/td>\u003Ctd>Education\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>\u003Ca href=\"bottleneck-analysis.md\">Assembly Bottleneck\u003C/a>\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>\u003Cstrong>22\u003C/strong>\u003C/td>\u003Ctd>Manufacturing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>\u003Ca href=\"supplier-ppap.md\">Supplier PPAP\u003C/a>\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>\u003Cstrong>22\u003C/strong>\u003C/td>\u003Ctd>Automotive\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>\u003Ca href=\"copq-drilldown.md\">COPQ Drill-Down\u003C/a>\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>\u003Cstrong>21\u003C/strong>\u003C/td>\u003Ctd>Cross-industry\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>\u003Ca href=\"complaint-investigation.md\">Customer Complaint\u003C/a>\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>\u003Cstrong>21\u003C/strong>\u003C/td>\u003Ctd>Cross-industry\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>\u003Ca href=\"patient-wait-time.md\">Patient Wait Time\u003C/a>\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>\u003Cstrong>18\u003C/strong>\u003C/td>\u003Ctd>Healthcare\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>\u003Ca href=\"call-center-performance.md\">Call Center Performance\u003C/a>\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>\u003Cstrong>18\u003C/strong>\u003C/td>\u003Ctd>Service Ops\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>\u003Ca href=\"on-time-delivery.md\">On-Time Delivery\u003C/a>\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>\u003Cstrong>15\u003C/strong>\u003C/td>\u003Ctd>Logistics\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>\u003Ca href=\"pharma-oos.md\">Pharma OOS\u003C/a>\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>\u003Cstrong>19\u003C/strong>\u003C/td>\u003Ctd>Pharma\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>\u003Ca href=\"consultant-delivery.md\">Consultant Delivery\u003C/a>\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>\u003Cstrong>17\u003C/strong>\u003C/td>\u003Ctd>Professional Services\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>\u003Ca href=\"batch-consistency.md\">Batch Consistency\u003C/a>\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>\u003Cstrong>18\u003C/strong>\u003C/td>\u003Ctd>Food / Chemical\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>13\u003C/td>\u003Ctd>\u003Ca href=\"lead-time-variation.md\">Lead Time Variation\u003C/a>\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>\u003Cstrong>19\u003C/strong>\u003C/td>\u003Ctd>Supply Chain\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"theme-groupings\">Theme Groupings\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#theme-groupings\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theme Groupings”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"drill-down-reveals-hidden-structure\">Drill-Down Reveals Hidden Structure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#drill-down-reveals-hidden-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill-Down Reveals Hidden Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use cases where averages mislead and stratification exposes the real story.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Use Case\u003C/th>\u003Cth>The Misleading Average\u003C/th>\u003Cth>What Drill-Down Reveals\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"supplier-performance.md\">Supplier Performance\u003C/a>\u003C/td>\u003Ctd>”All suppliers meet spec”\u003C/td>\u003Ctd>Supplier C fails dimension B; 80% of rejects from 2 suppliers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"copq-drilldown.md\">COPQ Drill-Down\u003C/a>\u003C/td>\u003Ctd>”Scrap is 3% overall”\u003C/td>\u003Ctd>Product X + Line 2 + Night shift = 52% of total COPQ\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"batch-consistency.md\">Batch Consistency\u003C/a>\u003C/td>\u003Ctd>”Same recipe, same result”\u003C/td>\u003Ctd>Vessel 2 + Supplier B raw material = poor batches\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"call-center-performance.md\">Call Center Performance\u003C/a>\u003C/td>\u003Ctd>”Average handle time meets target”\u003C/td>\u003Ctd>Agent C + Issue Type 3 = specific training gap\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-aggregation-trap\">The Aggregation Trap\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-aggregation-trap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Aggregation Trap”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use cases where the overall metric hides critical variation.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Use Case\u003C/th>\u003Cth>The Aggregated Metric\u003C/th>\u003Cth>What’s Hidden\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"bottleneck-analysis.md\">Assembly Bottleneck\u003C/a>\u003C/td>\u003Ctd>”Station 3 has highest average time”\u003C/td>\u003Ctd>Station 2 has 3x the variation — unpredictability is the bottleneck\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patient-wait-time.md\">Patient Wait Time\u003C/a>\u003C/td>\u003Ctd>”Average wait: 45 minutes”\u003C/td>\u003Ctd>Night shift: 95% utilization, 2-hour waits hidden by daytime lulls\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"lead-time-variation.md\">Lead Time Variation\u003C/a>\u003C/td>\u003Ctd>”Average lead time: 5 days”\u003C/td>\u003Ctd>Supplier X fine for small orders, wildly inconsistent for large ones\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"multi-channel-capability\">Multi-Channel Capability\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#multi-channel-capability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Multi-Channel Capability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use cases that leverage Performance Mode to compare parallel processes.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Use Case\u003C/th>\u003Cth>The Channels\u003C/th>\u003Cth>Key Metric\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"supplier-ppap.md\">Supplier PPAP\u003C/a>\u003C/td>\u003Ctd>Critical characteristics / cavities\u003C/td>\u003Ctd>Cpk per characteristic, worst-first ranking\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"pharma-oos.md\">Pharma OOS\u003C/a>\u003C/td>\u003Ctd>Batches / analysts / instruments\u003C/td>\u003Ctd>Cpk vs acceptance criteria\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"capability-vs-sla\">Capability vs SLA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#capability-vs-sla\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability vs SLA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use cases where process capability is measured against a service target.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Use Case\u003C/th>\u003Cth>The SLA\u003C/th>\u003Cth>Capability Question\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"on-time-delivery.md\">On-Time Delivery\u003C/a>\u003C/td>\u003Ctd>Deliver within 3 days\u003C/td>\u003Ctd>Which carrier/route/product fails the SLA?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"complaint-investigation.md\">Customer Complaint\u003C/a>\u003C/td>\u003Ctd>Product consistency\u003C/td>\u003Ctd>What changed during the complaint period?\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"education--adoption\">Education & Adoption\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#education--adoption\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Education & Adoption”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use cases focused on learning methodology and spreading tool adoption.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Use Case\u003C/th>\u003Cth>Entry Point\u003C/th>\u003Cth>Conversion Path\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"university-spc.md\">University SPC\u003C/a>\u003C/td>\u003Ctd>Course link / Google\u003C/td>\u003Ctd>Free PWA forever, case studies as assignments\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"consultant-delivery.md\">Consultant Delivery\u003C/a>\u003C/td>\u003Ctd>Client meeting demo\u003C/td>\u003Ctd>Free PWA for client, Azure App for team\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"content-phasing\">Content Phasing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#content-phasing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Content Phasing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-1--core-highest-seo-impact\">Phase 1 — Core, Highest SEO Impact\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-1--core-highest-seo-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 1 — Core, Highest SEO Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Use Case\u003C/th>\u003Cth>SEO Score\u003C/th>\u003Cth>Priority Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"supplier-performance.md\">Supplier Performance\u003C/a>\u003C/td>\u003Ctd>24\u003C/td>\u003Ctd>Massive keyword cluster, growing supply chain interest\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"university-spc.md\">University SPC\u003C/a>\u003C/td>\u003Ctd>24\u003C/td>\u003Ctd>Highest volume, direct PWA conversion\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"bottleneck-analysis.md\">Assembly Bottleneck\u003C/a>\u003C/td>\u003Ctd>22\u003C/td>\u003Ctd>Cross-industry appeal, compelling narrative\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"supplier-ppap.md\">Supplier PPAP\u003C/a>\u003C/td>\u003Ctd>22\u003C/td>\u003Ctd>High-intent automotive, buyers know what they need\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"copq-drilldown.md\">COPQ Drill-Down\u003C/a>\u003C/td>\u003Ctd>21\u003C/td>\u003Ctd>High-value keyword, universal manufacturing pain\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"complaint-investigation.md\">Customer Complaint\u003C/a>\u003C/td>\u003Ctd>21\u003C/td>\u003Ctd>Universal, every manufacturer searches this\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-2--founder-stories--services\">Phase 2 — Founder Stories & Services\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2--founder-stories--services\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2 — Founder Stories & Services”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Use Case\u003C/th>\u003Cth>SEO Score\u003C/th>\u003Cth>Priority Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"patient-wait-time.md\">Patient Wait Time\u003C/a>\u003C/td>\u003Ctd>18\u003C/td>\u003Ctd>Founder hospital experience, authentic stories\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"call-center-performance.md\">Call Center Performance\u003C/a>\u003C/td>\u003Ctd>18\u003C/td>\u003Ctd>Founder call center experience, credibility\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"on-time-delivery.md\">On-Time Delivery\u003C/a>\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Distinct logistics angle, OTD as universal KPI\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-3--niche--multiplier\">Phase 3 — Niche & Multiplier\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3--niche--multiplier\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3 — Niche & Multiplier”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Use Case\u003C/th>\u003Cth>SEO Score\u003C/th>\u003Cth>Priority Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"pharma-oos.md\">Pharma OOS\u003C/a>\u003C/td>\u003Ctd>19\u003C/td>\u003Ctd>High intent, regulated industry\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"consultant-delivery.md\">Consultant Delivery\u003C/a>\u003C/td>\u003Ctd>17\u003C/td>\u003Ctd>Multiplier effect — consultants bring VariScout to every client\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"batch-consistency.md\">Batch Consistency\u003C/a>\u003C/td>\u003Ctd>18\u003C/td>\u003Ctd>Broad manufacturing / food appeal\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"lead-time-variation.md\">Lead Time Variation\u003C/a>\u003C/td>\u003Ctd>19\u003C/td>\u003Ctd>Growing supply chain interest\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"industry-coverage\">Industry Coverage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#industry-coverage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Industry Coverage”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Industry\u003C/th>\u003Cth>Use Cases\u003C/th>\u003Cth>Count\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Manufacturing\u003C/td>\u003Ctd>Bottleneck, Batch Consistency\u003C/td>\u003Ctd>2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Supply Chain\u003C/td>\u003Ctd>Supplier Performance, Lead Time Variation\u003C/td>\u003Ctd>2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Automotive\u003C/td>\u003Ctd>Supplier PPAP\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pharma\u003C/td>\u003Ctd>Pharma OOS\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Education\u003C/td>\u003Ctd>University SPC\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Food / Chemical\u003C/td>\u003Ctd>Batch Consistency\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Healthcare\u003C/td>\u003Ctd>Patient Wait Time\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Service Operations\u003C/td>\u003Ctd>Call Center Performance\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Logistics\u003C/td>\u003Ctd>On-Time Delivery\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Professional Services\u003C/td>\u003Ctd>Consultant Delivery\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cross-industry\u003C/td>\u003Ctd>COPQ, Customer Complaint\u003C/td>\u003Ctd>2\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"relationship-to-personas\">Relationship to Personas\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#relationship-to-personas\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Relationship to Personas”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These use cases describe \u003Cstrong>problems\u003C/strong>; \u003Ca href=\"../personas/\">personas\u003C/a> describe \u003Cstrong>people\u003C/strong>. They work together:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Most Likely Use Cases\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Supplier Performance, COPQ, Bottleneck, Batch Consistency\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Bottleneck, Customer Complaint, Lead Time\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>University SPC\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>University SPC, Consultant Delivery\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>COPQ, Supplier PPAP, Multi-site (future)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Supplier Performance, Patient Wait Time, Call Center\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5098, + "localImagePaths": 5139, + "remoteImagePaths": 5140, + "frontmatter": 5141, + "imagePaths": 5142 + }, + [5099, 5100, 5103, 5106, 5109, 5112, 5115, 5118, 5121, 5124, 5127, 5130, 5133, 5136], + { "depth": 30, "slug": 907, "text": 908 }, + { "depth": 33, "slug": 5101, "text": 5102 }, + "seo-scoring", + "SEO Scoring", + { "depth": 33, "slug": 5104, "text": 5105 }, + "theme-groupings", + "Theme Groupings", + { "depth": 79, "slug": 5107, "text": 5108 }, + "drill-down-reveals-hidden-structure", + "Drill-Down Reveals Hidden Structure", + { "depth": 79, "slug": 5110, "text": 5111 }, + "the-aggregation-trap", + "The Aggregation Trap", + { "depth": 79, "slug": 5113, "text": 5114 }, + "multi-channel-capability", + "Multi-Channel Capability", + { "depth": 79, "slug": 5116, "text": 5117 }, + "capability-vs-sla", + "Capability vs SLA", + { "depth": 79, "slug": 5119, "text": 5120 }, + "education--adoption", + "Education & Adoption", + { "depth": 33, "slug": 5122, "text": 5123 }, + "content-phasing", + "Content Phasing", + { "depth": 79, "slug": 5125, "text": 5126 }, + "phase-1--core-highest-seo-impact", + "Phase 1 — Core, Highest SEO Impact", + { "depth": 79, "slug": 5128, "text": 5129 }, + "phase-2--founder-stories--services", + "Phase 2 — Founder Stories & Services", + { "depth": 79, "slug": 5131, "text": 5132 }, + "phase-3--niche--multiplier", + "Phase 3 — Niche & Multiplier", + { "depth": 33, "slug": 5134, "text": 5135 }, + "industry-coverage", + "Industry Coverage", + { "depth": 33, "slug": 5137, "text": 5138 }, + "relationship-to-personas", + "Relationship to Personas", + [], + [], + { "title": 908 }, + [], + "02-journeys/use-cases/lead-time-variation", + { "id": 5143, "data": 5145, "body": 5150, "filePath": 5151, "digest": 5152, "rendered": 5153 }, + { + "title": 5146, + "editUrl": 16, + "head": 5147, + "template": 18, + "sidebar": 5148, + "pagefind": 16, + "draft": 20 + }, + "Lead Time Variation Analysis", + [], + { "hidden": 20, "attrs": 5149 }, + {}, + "# Lead Time Variation Analysis\n\n## The Problem\n\nA Supply Chain or Procurement Analyst reports \"average lead time: 5 days\" to the planning team. Production schedules around it. But actual lead times range from 2 to 14 days, and nobody knows which suppliers, routes, or order sizes drive the unpredictability. Safety stock is set high to compensate — tying up capital. Late deliveries still happen because the average hides the tail.\n\nThe data is in the ERP — purchase orders with order date, promised date, received date, supplier, item category, order quantity. Reports show average lead time by supplier. Nobody asks \"what's the _variation_ in lead time, and what drives it?\"\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| -------------------- | --------------------- | --------------------------------------------------------------- | ---------------------------------- |\n| Supply Chain Analyst | Manufacturing, Retail | \"lead time variation analysis,\" \"supplier lead time comparison\" | ERP reports, Excel pivot tables |\n| Procurement Manager | Any | \"lead time reliability by supplier,\" \"lead time reduction\" | Supplier scorecards |\n| Production Planner | Manufacturing | \"lead time unpredictability,\" \"safety stock optimization\" | MRP system, average-based planning |\n\n## Keyword Cluster\n\n**Primary:**\n\n- lead time variation analysis\n- supplier lead time comparison\n- lead time reliability\n\n**Long-tail:**\n\n- how to analyze lead time variation by supplier\n- why lead times are unpredictable\n- lead time analysis for safety stock\n- supplier reliability beyond average lead time\n- purchase order lead time SPC\n\n**Related queries:**\n\n- supply chain variation analysis\n- supplier delivery reliability metrics\n- lead time distribution analysis\n- safety stock vs lead time variation\n- procurement analytics tools\n\n## The VariScout Journey\n\n1. **Paste PO data** — rows with Supplier, Item Category, Order Quantity, Order Date, Received Date, Lead Time Days columns\n2. **I-Chart** — lead time over time shows instability — periods of short and long lead times with no obvious calendar pattern\n3. **Boxplot by Supplier** — Supplier X has 3x the variation of Supplier Y despite similar averages. eta-squared: \"Supplier explains 26% of lead time variation\"\n4. **Drill-down: Supplier X** — boxplot by Order Size (small/medium/large). Large orders have dramatically longer and more variable lead times\n5. **Drill-down: Supplier X + Large orders** — boxplot by Item Category. Category A is fine; Category B lead times range from 5 to 18 days\n6. **Capability** — against \"within 7 days\" SLA: Supplier Y Cpk = 1.3, Supplier X overall = 0.7, Supplier X Large Category B = 0.1\n7. **Staged analysis** — before/after a recent contract renegotiation: did it actually improve lead time reliability?\n\n**Aha moment:** \"Supplier X's average lead time of 5.2 days looked almost identical to Supplier Y's 4.8 days. But Supplier X's large orders for Category B items range from 5-18 days — completely unpredictable. That's what's forcing our safety stock up and causing stockouts. The average told us they were 'about the same.' The variation tells a completely different story.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| ---------------------------------------------- | ---------------------------------------------------------- |\n| \"Average lead time: 5 days\" for all suppliers | Supplier X large Category B = 5-18 days (unpredictable) |\n| Safety stock based on average + buffer | Safety stock based on actual variation by supplier/item |\n| Supplier X \"about the same\" as Supplier Y | Supplier X incapable for large orders (Cpk = 0.1 vs SLA) |\n| Planning disrupted by \"unexpected\" late orders | Specific supplier + size + category combination identified |\n| No before/after for contract changes | Staged analysis validates whether improvements are real |\n\n## Website Content Map\n\n**Landing page:** `/solutions/lead-time-analysis`\n\n- Headline: \"Average lead time: 5 days. Actual range: 2 to 14 days. Find out what drives the spread.\"\n- Key message: Variation analysis reveals which suppliers are reliable and which are predictable only on average\n- Interactive demo: Purchase order dataset with supplier, order size, and item category\n\n**Case study:** Supply chain data — 5 suppliers, 3 order size classes, 4 item categories, 12 months\n\n- Narrative: \"Two suppliers had the same average lead time. One was reliable. One was chaos.\"\n- Capability against SLA per supplier/combination\n- Safety stock implications of addressing the variation\n\n**Blog posts:**\n\n- \"Lead Time Variation: Why Average Lead Time Is a Dangerous Metric\" (methodology)\n- \"Supplier Lead Time Reliability: Beyond Average to Capability\" (educational + tool)\n- \"How Lead Time Variation Drives Safety Stock — and How to Fix It\" (practical)\n\n**Social:**\n\n- LinkedIn: \"Two suppliers, same average lead time. One delivers in 4-6 days. The other: 2-14 days. Guess which one's costing you in safety stock? Here's the analysis that reveals the truth.\" (data story)\n- YouTube: \"Lead Time Variation Analysis\" — 4-minute demo with VariScout\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------ | ----------------------- | -------------------------------------------------------------------- |\n| One-off analysis | **PWA** (free) | Paste PO data, find the variation sources |\n| Ongoing monitoring | **Excel Add-in** (free) | Connect to ERP export, slicer by supplier/category/size |\n| Supply chain team | **Azure App** (paid) | Multiple analysts, Performance Mode across suppliers, trend tracking |", + "src/content/docs/02-journeys/use-cases/lead-time-variation.md", + "d9324ee2485e334a", + { "html": 5154, "metadata": 5155 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"lead-time-variation-analysis\">Lead Time Variation Analysis\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#lead-time-variation-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Lead Time Variation Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A Supply Chain or Procurement Analyst reports “average lead time: 5 days” to the planning team. Production schedules around it. But actual lead times range from 2 to 14 days, and nobody knows which suppliers, routes, or order sizes drive the unpredictability. Safety stock is set high to compensate — tying up capital. Late deliveries still happen because the average hides the tail.\u003C/p>\n\u003Cp>The data is in the ERP — purchase orders with order date, promised date, received date, supplier, item category, order quantity. Reports show average lead time by supplier. Nobody asks “what’s the \u003Cem>variation\u003C/em> in lead time, and what drives it?”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Supply Chain Analyst\u003C/td>\u003Ctd>Manufacturing, Retail\u003C/td>\u003Ctd>”lead time variation analysis,” “supplier lead time comparison”\u003C/td>\u003Ctd>ERP reports, Excel pivot tables\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Procurement Manager\u003C/td>\u003Ctd>Any\u003C/td>\u003Ctd>”lead time reliability by supplier,” “lead time reduction”\u003C/td>\u003Ctd>Supplier scorecards\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Production Planner\u003C/td>\u003Ctd>Manufacturing\u003C/td>\u003Ctd>”lead time unpredictability,” “safety stock optimization”\u003C/td>\u003Ctd>MRP system, average-based planning\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>lead time variation analysis\u003C/li>\n\u003Cli>supplier lead time comparison\u003C/li>\n\u003Cli>lead time reliability\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to analyze lead time variation by supplier\u003C/li>\n\u003Cli>why lead times are unpredictable\u003C/li>\n\u003Cli>lead time analysis for safety stock\u003C/li>\n\u003Cli>supplier reliability beyond average lead time\u003C/li>\n\u003Cli>purchase order lead time SPC\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>supply chain variation analysis\u003C/li>\n\u003Cli>supplier delivery reliability metrics\u003C/li>\n\u003Cli>lead time distribution analysis\u003C/li>\n\u003Cli>safety stock vs lead time variation\u003C/li>\n\u003Cli>procurement analytics tools\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Paste PO data\u003C/strong> — rows with Supplier, Item Category, Order Quantity, Order Date, Received Date, Lead Time Days columns\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — lead time over time shows instability — periods of short and long lead times with no obvious calendar pattern\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Supplier\u003C/strong> — Supplier X has 3x the variation of Supplier Y despite similar averages. eta-squared: “Supplier explains 26% of lead time variation”\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Supplier X\u003C/strong> — boxplot by Order Size (small/medium/large). Large orders have dramatically longer and more variable lead times\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Supplier X + Large orders\u003C/strong> — boxplot by Item Category. Category A is fine; Category B lead times range from 5 to 18 days\u003C/li>\n\u003Cli>\u003Cstrong>Capability\u003C/strong> — against “within 7 days” SLA: Supplier Y Cpk = 1.3, Supplier X overall = 0.7, Supplier X Large Category B = 0.1\u003C/li>\n\u003Cli>\u003Cstrong>Staged analysis\u003C/strong> — before/after a recent contract renegotiation: did it actually improve lead time reliability?\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “Supplier X’s average lead time of 5.2 days looked almost identical to Supplier Y’s 4.8 days. But Supplier X’s large orders for Category B items range from 5-18 days — completely unpredictable. That’s what’s forcing our safety stock up and causing stockouts. The average told us they were ‘about the same.’ The variation tells a completely different story.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Average lead time: 5 days” for all suppliers\u003C/td>\u003Ctd>Supplier X large Category B = 5-18 days (unpredictable)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Safety stock based on average + buffer\u003C/td>\u003Ctd>Safety stock based on actual variation by supplier/item\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Supplier X “about the same” as Supplier Y\u003C/td>\u003Ctd>Supplier X incapable for large orders (Cpk = 0.1 vs SLA)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Planning disrupted by “unexpected” late orders\u003C/td>\u003Ctd>Specific supplier + size + category combination identified\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No before/after for contract changes\u003C/td>\u003Ctd>Staged analysis validates whether improvements are real\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/lead-time-analysis\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Average lead time: 5 days. Actual range: 2 to 14 days. Find out what drives the spread.”\u003C/li>\n\u003Cli>Key message: Variation analysis reveals which suppliers are reliable and which are predictable only on average\u003C/li>\n\u003Cli>Interactive demo: Purchase order dataset with supplier, order size, and item category\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Supply chain data — 5 suppliers, 3 order size classes, 4 item categories, 12 months\u003C/p>\n\u003Cul>\n\u003Cli>Narrative: “Two suppliers had the same average lead time. One was reliable. One was chaos.”\u003C/li>\n\u003Cli>Capability against SLA per supplier/combination\u003C/li>\n\u003Cli>Safety stock implications of addressing the variation\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“Lead Time Variation: Why Average Lead Time Is a Dangerous Metric” (methodology)\u003C/li>\n\u003Cli>“Supplier Lead Time Reliability: Beyond Average to Capability” (educational + tool)\u003C/li>\n\u003Cli>“How Lead Time Variation Drives Safety Stock — and How to Fix It” (practical)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “Two suppliers, same average lead time. One delivers in 4-6 days. The other: 2-14 days. Guess which one’s costing you in safety stock? Here’s the analysis that reveals the truth.” (data story)\u003C/li>\n\u003Cli>YouTube: “Lead Time Variation Analysis” — 4-minute demo with VariScout\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>One-off analysis\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste PO data, find the variation sources\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Ongoing monitoring\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to ERP export, slicer by supplier/category/size\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Supply chain team\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Multiple analysts, Performance Mode across suppliers, trend tracking\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5156, + "localImagePaths": 5166, + "remoteImagePaths": 5167, + "frontmatter": 5168, + "imagePaths": 5169 + }, + [5157, 5159, 5160, 5161, 5162, 5163, 5164, 5165], + { "depth": 30, "slug": 5158, "text": 5146 }, + "lead-time-variation-analysis", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 5146 }, + [], + "02-journeys/use-cases/on-time-delivery", + { "id": 5170, "data": 5172, "body": 5177, "filePath": 5178, "digest": 5179, "rendered": 5180 }, + { + "title": 5173, + "editUrl": 16, + "head": 5174, + "template": 18, + "sidebar": 5175, + "pagefind": 16, + "draft": 20 + }, + "On-Time Delivery Analysis", + [], + { "hidden": 20, "attrs": 5176 }, + {}, + "# On-Time Delivery Analysis\n\n## The Problem\n\nA Fleet Manager or Logistics Coordinator tracks On-Time Delivery (OTD) as a key metric — \"92% on time this month.\" But the 8% late deliveries aren't random. Which carrier? Which route? Which product category? The monthly OTD percentage hides the structure, and the operations team can't target improvements because they don't know where the late deliveries concentrate.\n\nData is in the TMS or ERP — order dates, promised delivery dates, actual delivery dates, carrier, route, product type. Reports show a single OTD% number. Nobody asks \"is our delivery process _capable_ of meeting the SLA?\" — they just count late/on-time.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ------------------------- | ------------------------ | ------------------------------------------------------- | ------------------ |\n| Fleet / Logistics Manager | Logistics, Distribution | \"on-time delivery analysis,\" \"OTD improvement\" | TMS reports, Excel |\n| Supply Chain Analyst | Manufacturing, Retail | \"delivery performance by carrier,\" \"shipping variation\" | ERP dashboards |\n| Operations Manager | E-commerce, Distribution | \"delivery SLA analysis,\" \"OTIF improvement\" | Weekly KPI reports |\n\n## Keyword Cluster\n\n**Primary:**\n\n- on-time delivery analysis\n- OTD improvement methods\n- delivery performance by carrier\n\n**Long-tail:**\n\n- how to analyze delivery performance data\n- on-time delivery variation by route\n- delivery SLA capability analysis\n- which carrier is causing late deliveries\n- OTIF analysis by product and route\n\n**Related queries:**\n\n- supply chain reliability metrics\n- logistics performance analysis tool\n- delivery time SPC\n- carrier performance comparison\n- logistics Cpk (novel angle)\n\n## The VariScout Journey\n\n1. **Paste delivery data** — rows with Carrier, Route, Product Category, Weight Class, Promised Date, Actual Date, Lead Time Days columns\n2. **I-Chart** — lead time over time shows stability (or lack thereof). Nelson rules catch recent deterioration\n3. **Boxplot by Carrier** — Carrier B has 3x the spread of Carrier A. eta-squared: \"Carrier explains 29% of lead time variation\"\n4. **Drill-down: Carrier B** — boxplot by Route. Rural routes show massive variation; urban routes are fine\n5. **Drill-down: Carrier B + Rural** — boxplot by Weight Class. Heavy products on rural routes = late deliveries\n6. **Capability vs SLA** — against \"deliver within 3 days\" target: overall Cpk = 0.8, Carrier A Cpk = 1.5, Carrier B Rural Heavy = Cpk 0.2\n7. **Pareto** — late deliveries by combination: Carrier B + Rural + Heavy = 72% of all late deliveries\n\n**Aha moment:** \"Our OTD was 92% overall. The drill-down showed Carrier B is fine for urban small packages but can't handle heavy rural deliveries — that one combination accounts for 72% of our late deliveries. We rerouted heavy rural orders to Carrier C and OTD jumped to 97%.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| -------------------------------------------- | ------------------------------------------------------------- |\n| \"OTD is 92% — needs improvement\" | Carrier B + Rural + Heavy = 72% of late deliveries |\n| All carriers treated the same | Carrier-specific routing based on capability data |\n| SLA measured as pass/fail percentage | Capability analysis: Cpk against SLA per carrier/route |\n| Improvement efforts spread across all routes | Focused on the specific carrier + route + product combination |\n| No quantification of carrier impact | eta-squared: \"Carrier explains 29% of lead time variation\" |\n\n## Website Content Map\n\n**Landing page:** `/solutions/delivery-performance`\n\n- Headline: \"Your OTD is 92%. But 72% of late deliveries come from one combination. Find it.\"\n- Key message: Drill-down from overall OTD to carrier + route + product reveals where to focus\n- Interactive demo: Delivery dataset with carrier, route, and product factors\n\n**Case study:** Logistics company — 3 carriers, 4 routes, 3 weight classes, 6 months of deliveries\n\n- Narrative: \"We rerouted one product category and OTD jumped from 92% to 97%.\"\n- Capability vs SLA analysis — novel \"logistics Cpk\" angle\n- Pareto showing concentration of late deliveries\n\n**Blog posts:**\n\n- \"On-Time Delivery Analysis: Beyond the Percentage\" (methodology)\n- \"Logistics Cpk: Applying Process Capability to Delivery SLAs\" (novel methodology)\n- \"Which Carrier Is Really the Problem? A Data-Driven Approach\" (practical)\n\n**Social:**\n\n- LinkedIn: \"OTD was 92%. We found that 72% of late deliveries were one carrier + one route + one product type. One routing change: 97%. Here's the analysis that found it.\" (before/after)\n- YouTube: \"On-Time Delivery Drill-Down\" — 4-minute demo with VariScout\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------ | ----------------------- | ------------------------------------------------------------------- |\n| Investigation | **PWA** (free) | Paste TMS export, find the late delivery pattern |\n| Ongoing monitoring | **Excel Add-in** (free) | Connect to delivery data spreadsheet, slicer by carrier/route |\n| Logistics team | **Azure App** (paid) | Multiple analysts, Performance Mode across carriers, trend tracking |", + "src/content/docs/02-journeys/use-cases/on-time-delivery.md", + "c8a17304e189e93f", + { "html": 5181, "metadata": 5182 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"on-time-delivery-analysis\">On-Time Delivery Analysis\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#on-time-delivery-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “On-Time Delivery Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A Fleet Manager or Logistics Coordinator tracks On-Time Delivery (OTD) as a key metric — “92% on time this month.” But the 8% late deliveries aren’t random. Which carrier? Which route? Which product category? The monthly OTD percentage hides the structure, and the operations team can’t target improvements because they don’t know where the late deliveries concentrate.\u003C/p>\n\u003Cp>Data is in the TMS or ERP — order dates, promised delivery dates, actual delivery dates, carrier, route, product type. Reports show a single OTD% number. Nobody asks “is our delivery process \u003Cem>capable\u003C/em> of meeting the SLA?” — they just count late/on-time.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Fleet / Logistics Manager\u003C/td>\u003Ctd>Logistics, Distribution\u003C/td>\u003Ctd>”on-time delivery analysis,” “OTD improvement”\u003C/td>\u003Ctd>TMS reports, Excel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Supply Chain Analyst\u003C/td>\u003Ctd>Manufacturing, Retail\u003C/td>\u003Ctd>”delivery performance by carrier,” “shipping variation”\u003C/td>\u003Ctd>ERP dashboards\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Operations Manager\u003C/td>\u003Ctd>E-commerce, Distribution\u003C/td>\u003Ctd>”delivery SLA analysis,” “OTIF improvement”\u003C/td>\u003Ctd>Weekly KPI reports\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>on-time delivery analysis\u003C/li>\n\u003Cli>OTD improvement methods\u003C/li>\n\u003Cli>delivery performance by carrier\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to analyze delivery performance data\u003C/li>\n\u003Cli>on-time delivery variation by route\u003C/li>\n\u003Cli>delivery SLA capability analysis\u003C/li>\n\u003Cli>which carrier is causing late deliveries\u003C/li>\n\u003Cli>OTIF analysis by product and route\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>supply chain reliability metrics\u003C/li>\n\u003Cli>logistics performance analysis tool\u003C/li>\n\u003Cli>delivery time SPC\u003C/li>\n\u003Cli>carrier performance comparison\u003C/li>\n\u003Cli>logistics Cpk (novel angle)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Paste delivery data\u003C/strong> — rows with Carrier, Route, Product Category, Weight Class, Promised Date, Actual Date, Lead Time Days columns\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — lead time over time shows stability (or lack thereof). Nelson rules catch recent deterioration\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Carrier\u003C/strong> — Carrier B has 3x the spread of Carrier A. eta-squared: “Carrier explains 29% of lead time variation”\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Carrier B\u003C/strong> — boxplot by Route. Rural routes show massive variation; urban routes are fine\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Carrier B + Rural\u003C/strong> — boxplot by Weight Class. Heavy products on rural routes = late deliveries\u003C/li>\n\u003Cli>\u003Cstrong>Capability vs SLA\u003C/strong> — against “deliver within 3 days” target: overall Cpk = 0.8, Carrier A Cpk = 1.5, Carrier B Rural Heavy = Cpk 0.2\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong> — late deliveries by combination: Carrier B + Rural + Heavy = 72% of all late deliveries\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “Our OTD was 92% overall. The drill-down showed Carrier B is fine for urban small packages but can’t handle heavy rural deliveries — that one combination accounts for 72% of our late deliveries. We rerouted heavy rural orders to Carrier C and OTD jumped to 97%.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”OTD is 92% — needs improvement”\u003C/td>\u003Ctd>Carrier B + Rural + Heavy = 72% of late deliveries\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>All carriers treated the same\u003C/td>\u003Ctd>Carrier-specific routing based on capability data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SLA measured as pass/fail percentage\u003C/td>\u003Ctd>Capability analysis: Cpk against SLA per carrier/route\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Improvement efforts spread across all routes\u003C/td>\u003Ctd>Focused on the specific carrier + route + product combination\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No quantification of carrier impact\u003C/td>\u003Ctd>eta-squared: “Carrier explains 29% of lead time variation”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/delivery-performance\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Your OTD is 92%. But 72% of late deliveries come from one combination. Find it.”\u003C/li>\n\u003Cli>Key message: Drill-down from overall OTD to carrier + route + product reveals where to focus\u003C/li>\n\u003Cli>Interactive demo: Delivery dataset with carrier, route, and product factors\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Logistics company — 3 carriers, 4 routes, 3 weight classes, 6 months of deliveries\u003C/p>\n\u003Cul>\n\u003Cli>Narrative: “We rerouted one product category and OTD jumped from 92% to 97%.”\u003C/li>\n\u003Cli>Capability vs SLA analysis — novel “logistics Cpk” angle\u003C/li>\n\u003Cli>Pareto showing concentration of late deliveries\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“On-Time Delivery Analysis: Beyond the Percentage” (methodology)\u003C/li>\n\u003Cli>“Logistics Cpk: Applying Process Capability to Delivery SLAs” (novel methodology)\u003C/li>\n\u003Cli>“Which Carrier Is Really the Problem? A Data-Driven Approach” (practical)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “OTD was 92%. We found that 72% of late deliveries were one carrier + one route + one product type. One routing change: 97%. Here’s the analysis that found it.” (before/after)\u003C/li>\n\u003Cli>YouTube: “On-Time Delivery Drill-Down” — 4-minute demo with VariScout\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Investigation\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste TMS export, find the late delivery pattern\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Ongoing monitoring\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to delivery data spreadsheet, slicer by carrier/route\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Logistics team\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Multiple analysts, Performance Mode across carriers, trend tracking\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5183, + "localImagePaths": 5193, + "remoteImagePaths": 5194, + "frontmatter": 5195, + "imagePaths": 5196 + }, + [5184, 5186, 5187, 5188, 5189, 5190, 5191, 5192], + { "depth": 30, "slug": 5185, "text": 5173 }, + "on-time-delivery-analysis", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 5173 }, + [], + "02-journeys/use-cases/patient-wait-time", + { "id": 5197, "data": 5199, "body": 5204, "filePath": 5205, "digest": 5206, "rendered": 5207 }, + { + "title": 5200, + "editUrl": 16, + "head": 5201, + "template": 18, + "sidebar": 5202, + "pagefind": 16, + "draft": 20 + }, + "Patient Wait Time Variation", + [], + { "hidden": 20, "attrs": 5203 }, + {}, + "# Patient Wait Time Variation\n\n## The Problem\n\nA Hospital Operations Analyst or Clinic Manager reports \"average wait time: 45 minutes — within target.\" But patients complain about 2-hour waits, and staff on night shift are overwhelmed. The dashboard shows a daily average that hides massive variation between shifts, departments, days of the week, and patient acuity levels.\n\nThe data is in the hospital information system — thousands of rows with timestamps. But reports aggregate to daily or weekly averages, hiding the peaks that drive patient dissatisfaction and staff burnout. Nobody asks \"what's the _variation_ in wait times?\" — they only track the average.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ------------------------------ | ---------- | ----------------------------------------------------------- | ------------------------------- |\n| Hospital Operations Analyst | Healthcare | \"hospital wait time analysis,\" \"ED wait time variation\" | BI dashboards (averages), Excel |\n| Clinic / Department Manager | Healthcare | \"patient flow bottleneck,\" \"reduce patient wait times\" | Monthly reports, gut feel |\n| Healthcare Quality Coordinator | Healthcare | \"Lean Six Sigma hospital,\" \"healthcare quality improvement\" | Manual audits, patient surveys |\n\n## Keyword Cluster\n\n**Primary:**\n\n- hospital wait time analysis\n- patient wait time variation\n- ED wait time reduction\n\n**Long-tail:**\n\n- how to analyze patient wait time data\n- average hides variation in healthcare\n- patient flow bottleneck analysis\n- wait time by shift and department\n- healthcare operations analytics SPC\n\n**Related queries:**\n\n- Lean Six Sigma hospital examples\n- healthcare quality improvement tools\n- patient satisfaction wait time correlation\n- bed utilization analysis\n- emergency department throughput\n\n## The VariScout Journey\n\n1. **Paste wait time data** — rows with Department, Shift, Day-of-Week, Acuity Level, Wait Time, Service Time columns\n2. **I-Chart** — daily average wait times look \"okay\" but individual patient wait times show extreme outliers (some 3-4 hours)\n3. **Boxplot by Shift** — night shift median is 2x day shift. eta-squared: \"Shift explains 31% of wait time variation\"\n4. **Boxplot by Department** — Emergency has widest spread (expected), but Radiology has surprising peaks\n5. **Drill-down: Night shift** — boxplot by Day-of-Week reveals Monday and Friday nights are the worst\n6. **Drill-down: Night shift + Monday** — boxplot by Acuity. Low-acuity patients wait 3x longer than high-acuity (expected triage), but the _variation_ in low-acuity wait is enormous\n7. **Capability vs SLA** — against \"90% of patients seen within 60 minutes\" target: day shift Cpk = 1.2, night shift Cpk = 0.4\n\n**Aha moment:** \"Our overall average of 45 minutes met the target. But night shift is at 95% utilization with 2-hour waits that the daily average hides. The 'average is fine' reporting was masking a staffing crisis on specific shifts.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| ---------------------------------- | -------------------------------------------------------- |\n| \"Average wait: 45 min — on target\" | Night shift: 90 min average, Cpk = 0.4 vs SLA |\n| Patient complaints seem random | Monday/Friday night shift = predictable peaks |\n| Staffing based on daily averages | Staffing based on variation patterns by shift/day |\n| No quantification of shift impact | eta-squared: \"Shift explains 31% of wait time variation\" |\n| Dashboard hides the peaks | Boxplot shows the full distribution, not just the middle |\n\n## Website Content Map\n\n**Landing page:** `/solutions/healthcare-operations`\n\n- Headline: \"Your average wait time is fine. Your patients' experience isn't.\"\n- Key message: Averages hide the worst experiences. Variation analysis reveals where patients actually wait — and why.\n- Interactive demo: Hospital wait time dataset by shift and department\n\n**Case study:** Hospital operations data — 3 departments, 3 shifts, 7 days, 3 months\n\n- Narrative: \"The dashboard said 45 minutes. Monday night shift patients waited over 2 hours.\"\n- The aggregation trap in healthcare: daily averages hide shift-level crises\n- Capability against SLA showing shift-by-shift gap\n\n**Blog posts:**\n\n- \"The Aggregation Trap in Healthcare: Why Average Wait Time Is Misleading\" (methodology)\n- \"Using SPC for Hospital Operations: A Practical Guide\" (educational)\n- \"Patient Wait Time Variation: What the Dashboard Doesn't Show\" (problem awareness)\n\n**Social:**\n\n- LinkedIn: \"Average wait time: 45 min (within target). Night shift wait time: 2 hours (crisis hidden by the average). Here's how one hospital found the pattern.\" (data story)\n- YouTube: \"Healthcare Aggregation Trap\" — 3-minute explainer with VariScout demo\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------ | ----------------------- | ----------------------------------------------------------------------- |\n| Investigation | **PWA** (free) | Paste HIS export, find variation patterns instantly |\n| Ongoing monitoring | **Excel Add-in** (free) | Connect to operations spreadsheet, slicer by shift/department |\n| Operations team | **Azure App** (paid) | Multiple analysts, Performance Mode across departments, shared insights |", + "src/content/docs/02-journeys/use-cases/patient-wait-time.md", + "a34cd37692bdf580", + { "html": 5208, "metadata": 5209 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"patient-wait-time-variation\">Patient Wait Time Variation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#patient-wait-time-variation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Patient Wait Time Variation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A Hospital Operations Analyst or Clinic Manager reports “average wait time: 45 minutes — within target.” But patients complain about 2-hour waits, and staff on night shift are overwhelmed. The dashboard shows a daily average that hides massive variation between shifts, departments, days of the week, and patient acuity levels.\u003C/p>\n\u003Cp>The data is in the hospital information system — thousands of rows with timestamps. But reports aggregate to daily or weekly averages, hiding the peaks that drive patient dissatisfaction and staff burnout. Nobody asks “what’s the \u003Cem>variation\u003C/em> in wait times?” — they only track the average.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Hospital Operations Analyst\u003C/td>\u003Ctd>Healthcare\u003C/td>\u003Ctd>”hospital wait time analysis,” “ED wait time variation”\u003C/td>\u003Ctd>BI dashboards (averages), Excel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Clinic / Department Manager\u003C/td>\u003Ctd>Healthcare\u003C/td>\u003Ctd>”patient flow bottleneck,” “reduce patient wait times”\u003C/td>\u003Ctd>Monthly reports, gut feel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Healthcare Quality Coordinator\u003C/td>\u003Ctd>Healthcare\u003C/td>\u003Ctd>”Lean Six Sigma hospital,” “healthcare quality improvement”\u003C/td>\u003Ctd>Manual audits, patient surveys\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>hospital wait time analysis\u003C/li>\n\u003Cli>patient wait time variation\u003C/li>\n\u003Cli>ED wait time reduction\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to analyze patient wait time data\u003C/li>\n\u003Cli>average hides variation in healthcare\u003C/li>\n\u003Cli>patient flow bottleneck analysis\u003C/li>\n\u003Cli>wait time by shift and department\u003C/li>\n\u003Cli>healthcare operations analytics SPC\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Lean Six Sigma hospital examples\u003C/li>\n\u003Cli>healthcare quality improvement tools\u003C/li>\n\u003Cli>patient satisfaction wait time correlation\u003C/li>\n\u003Cli>bed utilization analysis\u003C/li>\n\u003Cli>emergency department throughput\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Paste wait time data\u003C/strong> — rows with Department, Shift, Day-of-Week, Acuity Level, Wait Time, Service Time columns\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — daily average wait times look “okay” but individual patient wait times show extreme outliers (some 3-4 hours)\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Shift\u003C/strong> — night shift median is 2x day shift. eta-squared: “Shift explains 31% of wait time variation”\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Department\u003C/strong> — Emergency has widest spread (expected), but Radiology has surprising peaks\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Night shift\u003C/strong> — boxplot by Day-of-Week reveals Monday and Friday nights are the worst\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Night shift + Monday\u003C/strong> — boxplot by Acuity. Low-acuity patients wait 3x longer than high-acuity (expected triage), but the \u003Cem>variation\u003C/em> in low-acuity wait is enormous\u003C/li>\n\u003Cli>\u003Cstrong>Capability vs SLA\u003C/strong> — against “90% of patients seen within 60 minutes” target: day shift Cpk = 1.2, night shift Cpk = 0.4\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “Our overall average of 45 minutes met the target. But night shift is at 95% utilization with 2-hour waits that the daily average hides. The ‘average is fine’ reporting was masking a staffing crisis on specific shifts.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Average wait: 45 min — on target”\u003C/td>\u003Ctd>Night shift: 90 min average, Cpk = 0.4 vs SLA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Patient complaints seem random\u003C/td>\u003Ctd>Monday/Friday night shift = predictable peaks\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Staffing based on daily averages\u003C/td>\u003Ctd>Staffing based on variation patterns by shift/day\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No quantification of shift impact\u003C/td>\u003Ctd>eta-squared: “Shift explains 31% of wait time variation”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Dashboard hides the peaks\u003C/td>\u003Ctd>Boxplot shows the full distribution, not just the middle\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/healthcare-operations\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Your average wait time is fine. Your patients’ experience isn’t.”\u003C/li>\n\u003Cli>Key message: Averages hide the worst experiences. Variation analysis reveals where patients actually wait — and why.\u003C/li>\n\u003Cli>Interactive demo: Hospital wait time dataset by shift and department\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Hospital operations data — 3 departments, 3 shifts, 7 days, 3 months\u003C/p>\n\u003Cul>\n\u003Cli>Narrative: “The dashboard said 45 minutes. Monday night shift patients waited over 2 hours.”\u003C/li>\n\u003Cli>The aggregation trap in healthcare: daily averages hide shift-level crises\u003C/li>\n\u003Cli>Capability against SLA showing shift-by-shift gap\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“The Aggregation Trap in Healthcare: Why Average Wait Time Is Misleading” (methodology)\u003C/li>\n\u003Cli>“Using SPC for Hospital Operations: A Practical Guide” (educational)\u003C/li>\n\u003Cli>“Patient Wait Time Variation: What the Dashboard Doesn’t Show” (problem awareness)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “Average wait time: 45 min (within target). Night shift wait time: 2 hours (crisis hidden by the average). Here’s how one hospital found the pattern.” (data story)\u003C/li>\n\u003Cli>YouTube: “Healthcare Aggregation Trap” — 3-minute explainer with VariScout demo\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Investigation\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste HIS export, find variation patterns instantly\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Ongoing monitoring\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to operations spreadsheet, slicer by shift/department\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Operations team\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Multiple analysts, Performance Mode across departments, shared insights\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5210, + "localImagePaths": 5220, + "remoteImagePaths": 5221, + "frontmatter": 5222, + "imagePaths": 5223 + }, + [5211, 5213, 5214, 5215, 5216, 5217, 5218, 5219], + { "depth": 30, "slug": 5212, "text": 5200 }, + "patient-wait-time-variation", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 5200 }, + [], + "02-journeys/use-cases/pharma-oos", + { "id": 5224, "data": 5226, "body": 5231, "filePath": 5232, "digest": 5233, "rendered": 5234 }, + { + "title": 5227, + "editUrl": 16, + "head": 5228, + "template": 18, + "sidebar": 5229, + "pagefind": 16, + "draft": 20 + }, + "Pharma OOS Investigation", + [], + { "hidden": 20, "attrs": 5230 }, + {}, + "# Pharma OOS Investigation\n\n## The Problem\n\nA QC Analyst or Quality Manager gets an Out-of-Specification (OOS) result on a batch release test. Is it a real process failure, a measurement artifact, or a lab error? FDA 21 CFR 211.192 requires a systematic investigation with documented evidence. The QM needs to answer: Was the process drifting? Is the analytical method reliable? Can we identify the assignable cause?\n\nThe data exists — batch results over time, multiple analysts, multiple instruments, multiple raw material lots. But it's scattered across LIMS reports and Excel files. The investigation typically takes days of manual data compilation before the actual analysis can begin.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| -------------------------- | ---------------------- | --------------------------------------------------------------- | ------------------------------------- |\n| QC Analyst | Pharma, Biotech | \"OOS investigation tools,\" \"out-of-specification investigation\" | LIMS reports, manual Excel analysis |\n| Quality Manager | Pharma | \"batch release analysis,\" \"OOS root cause investigation\" | Paper-based investigation forms |\n| Quality Assurance Director | Pharma, Medical Device | \"21 CFR 211.192 investigation tools,\" \"OOS trend analysis\" | Quality system with limited analytics |\n\n## Keyword Cluster\n\n**Primary:**\n\n- OOS investigation\n- out-of-specification investigation tools\n- batch release testing analysis\n\n**Long-tail:**\n\n- how to investigate out-of-specification result\n- OOS investigation procedure with data\n- batch trend analysis pharmaceutical\n- analyst-to-analyst variation testing\n- laboratory OOS root cause analysis\n\n**Related queries:**\n\n- FDA OOS guidance\n- 21 CFR 211.192 investigation\n- analytical method variation\n- batch-to-batch variation pharma\n- process capability pharmaceutical\n\n## The VariScout Journey\n\n1. **Paste batch test results** — rows with Batch, Analyst, Instrument, Material Lot, Test Date, Result columns\n2. **I-Chart** — batch results over time: was the process drifting toward the spec limit before the OOS? Nelson Rule 2 (trend) may show gradual shift\n3. **Staged analysis: before OOS / OOS batch / after correction** — quantify the magnitude of the shift\n4. **Boxplot by Analyst** — do different analysts get different results on the same batch? eta-squared quantifies analyst contribution\n5. **Boxplot by Material Lot** — did the OOS coincide with a new raw material lot? eta-squared: \"Material lot explains 44% of result variation\"\n6. **Boxplot by Instrument** — HPLC 2 consistently reads 0.3% lower than HPLC 1. Calibration issue?\n7. **Capability** — Cpk over recent batches shows the process was marginal (Cpk = 0.9) before the OOS — not a sudden failure but a chronic capability gap\n\n**Aha moment:** \"The OOS wasn't a random lab error. The I-Chart showed the process had been drifting for 15 batches. Material Lot 4872 pushed it over the edge. And the analyst boxplot revealed significant analyst-to-analyst variation — we need to address both the process drift and the method.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| ------------------------------------------- | --------------------------------------------------------------- |\n| 3-day manual data compilation | 30-minute paste-and-analyze |\n| \"Is it the lab or the process?\" — guesswork | Boxplot by analyst separates measurement from process variation |\n| Investigation report based on opinions | Visual evidence: I-Chart trend, boxplot by factor, capability |\n| No trend analysis before OOS | I-Chart shows the drift was visible for 15 batches |\n| Root cause identified by experience | eta-squared quantifies: \"Material lot = 44% of variation\" |\n\n## Website Content Map\n\n**Landing page:** `/solutions/pharma-investigation`\n\n- Headline: \"OOS result? Separate process failure from lab error in 30 minutes.\"\n- Key message: I-Chart shows drift, Boxplot by analyst tests the method, Boxplot by factor isolates the cause — with visual evidence for your investigation report\n- Interactive demo: Pharma batch release dataset with analyst and instrument factors\n\n**Case study:** Pharmaceutical batch data — 50 batches, 3 analysts, 2 instruments, 4 material lots\n\n- Narrative: \"The OOS investigation that usually takes a week was resolved in an afternoon.\"\n- I-Chart showing 15-batch drift before OOS\n- Boxplot revealing analyst-to-analyst variation\n- Boxplot by material lot identifying the specific lot\n\n**Blog posts:**\n\n- \"OOS Investigation with Data: A Visual Approach to Root Cause Analysis\" (methodology)\n- \"Analyst Variation in Lab Methods: Is Your Lab Test Reliable Enough?\" (educational)\n- \"Batch Trend Analysis: How to Spot OOS Before It Happens\" (preventive)\n\n**Social:**\n\n- LinkedIn: \"An OOS investigation that usually takes a week — resolved in 30 minutes with data analysis. Here's the approach we used.\" (efficiency story)\n- YouTube: \"Pharma OOS Investigation with VariScout\" — 6-minute walkthrough\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------------ | ----------------------- | ----------------------------------------------------------------------- |\n| Urgent OOS investigation | **PWA** (free) | Paste LIMS data, find root cause fast |\n| Routine batch monitoring | **Excel Add-in** (free) | Connect to batch results spreadsheet, trend monitoring |\n| QA team workflow | **Azure App** (paid) | Multiple analysts, Performance Mode across test parameters, audit trail |", + "src/content/docs/02-journeys/use-cases/pharma-oos.md", + "18daf8edbd8a9871", + { "html": 5235, "metadata": 5236 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"pharma-oos-investigation\">Pharma OOS Investigation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#pharma-oos-investigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pharma OOS Investigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A QC Analyst or Quality Manager gets an Out-of-Specification (OOS) result on a batch release test. Is it a real process failure, a measurement artifact, or a lab error? FDA 21 CFR 211.192 requires a systematic investigation with documented evidence. The QM needs to answer: Was the process drifting? Is the analytical method reliable? Can we identify the assignable cause?\u003C/p>\n\u003Cp>The data exists — batch results over time, multiple analysts, multiple instruments, multiple raw material lots. But it’s scattered across LIMS reports and Excel files. The investigation typically takes days of manual data compilation before the actual analysis can begin.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>QC Analyst\u003C/td>\u003Ctd>Pharma, Biotech\u003C/td>\u003Ctd>”OOS investigation tools,” “out-of-specification investigation”\u003C/td>\u003Ctd>LIMS reports, manual Excel analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quality Manager\u003C/td>\u003Ctd>Pharma\u003C/td>\u003Ctd>”batch release analysis,” “OOS root cause investigation”\u003C/td>\u003Ctd>Paper-based investigation forms\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quality Assurance Director\u003C/td>\u003Ctd>Pharma, Medical Device\u003C/td>\u003Ctd>”21 CFR 211.192 investigation tools,” “OOS trend analysis”\u003C/td>\u003Ctd>Quality system with limited analytics\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>OOS investigation\u003C/li>\n\u003Cli>out-of-specification investigation tools\u003C/li>\n\u003Cli>batch release testing analysis\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to investigate out-of-specification result\u003C/li>\n\u003Cli>OOS investigation procedure with data\u003C/li>\n\u003Cli>batch trend analysis pharmaceutical\u003C/li>\n\u003Cli>analyst-to-analyst variation testing\u003C/li>\n\u003Cli>laboratory OOS root cause analysis\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>FDA OOS guidance\u003C/li>\n\u003Cli>21 CFR 211.192 investigation\u003C/li>\n\u003Cli>analytical method variation\u003C/li>\n\u003Cli>batch-to-batch variation pharma\u003C/li>\n\u003Cli>process capability pharmaceutical\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Paste batch test results\u003C/strong> — rows with Batch, Analyst, Instrument, Material Lot, Test Date, Result columns\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — batch results over time: was the process drifting toward the spec limit before the OOS? Nelson Rule 2 (trend) may show gradual shift\u003C/li>\n\u003Cli>\u003Cstrong>Staged analysis: before OOS / OOS batch / after correction\u003C/strong> — quantify the magnitude of the shift\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Analyst\u003C/strong> — do different analysts get different results on the same batch? eta-squared quantifies analyst contribution\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Material Lot\u003C/strong> — did the OOS coincide with a new raw material lot? eta-squared: “Material lot explains 44% of result variation”\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Instrument\u003C/strong> — HPLC 2 consistently reads 0.3% lower than HPLC 1. Calibration issue?\u003C/li>\n\u003Cli>\u003Cstrong>Capability\u003C/strong> — Cpk over recent batches shows the process was marginal (Cpk = 0.9) before the OOS — not a sudden failure but a chronic capability gap\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “The OOS wasn’t a random lab error. The I-Chart showed the process had been drifting for 15 batches. Material Lot 4872 pushed it over the edge. And the analyst boxplot revealed significant analyst-to-analyst variation — we need to address both the process drift and the method.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>3-day manual data compilation\u003C/td>\u003Ctd>30-minute paste-and-analyze\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Is it the lab or the process?” — guesswork\u003C/td>\u003Ctd>Boxplot by analyst separates measurement from process variation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Investigation report based on opinions\u003C/td>\u003Ctd>Visual evidence: I-Chart trend, boxplot by factor, capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No trend analysis before OOS\u003C/td>\u003Ctd>I-Chart shows the drift was visible for 15 batches\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Root cause identified by experience\u003C/td>\u003Ctd>eta-squared quantifies: “Material lot = 44% of variation”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/pharma-investigation\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “OOS result? Separate process failure from lab error in 30 minutes.”\u003C/li>\n\u003Cli>Key message: I-Chart shows drift, Boxplot by analyst tests the method, Boxplot by factor isolates the cause — with visual evidence for your investigation report\u003C/li>\n\u003Cli>Interactive demo: Pharma batch release dataset with analyst and instrument factors\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Pharmaceutical batch data — 50 batches, 3 analysts, 2 instruments, 4 material lots\u003C/p>\n\u003Cul>\n\u003Cli>Narrative: “The OOS investigation that usually takes a week was resolved in an afternoon.”\u003C/li>\n\u003Cli>I-Chart showing 15-batch drift before OOS\u003C/li>\n\u003Cli>Boxplot revealing analyst-to-analyst variation\u003C/li>\n\u003Cli>Boxplot by material lot identifying the specific lot\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“OOS Investigation with Data: A Visual Approach to Root Cause Analysis” (methodology)\u003C/li>\n\u003Cli>“Analyst Variation in Lab Methods: Is Your Lab Test Reliable Enough?” (educational)\u003C/li>\n\u003Cli>“Batch Trend Analysis: How to Spot OOS Before It Happens” (preventive)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “An OOS investigation that usually takes a week — resolved in 30 minutes with data analysis. Here’s the approach we used.” (efficiency story)\u003C/li>\n\u003Cli>YouTube: “Pharma OOS Investigation with VariScout” — 6-minute walkthrough\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Urgent OOS investigation\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste LIMS data, find root cause fast\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Routine batch monitoring\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to batch results spreadsheet, trend monitoring\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>QA team workflow\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Multiple analysts, Performance Mode across test parameters, audit trail\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5237, + "localImagePaths": 5247, + "remoteImagePaths": 5248, + "frontmatter": 5249, + "imagePaths": 5250 + }, + [5238, 5240, 5241, 5242, 5243, 5244, 5245, 5246], + { "depth": 30, "slug": 5239, "text": 5227 }, + "pharma-oos-investigation", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 5227 }, + [], + "02-journeys/use-cases/supplier-performance", + { "id": 5251, "data": 5253, "body": 5258, "filePath": 5259, "digest": 5260, "rendered": 5261 }, + { + "title": 5254, + "editUrl": 16, + "head": 5255, + "template": 18, + "sidebar": 5256, + "pagefind": 16, + "draft": 20 + }, + "Supplier Performance Comparison", + [], + { "hidden": 20, "attrs": 5257 }, + {}, + "# Supplier Performance Comparison\n\n## The Problem\n\nA Supplier Quality Engineer manages 3-8 suppliers for the same part. Incoming inspection catches individual lot failures, but there's no systemic view — which supplier is actually capable? Which dimension is the weak point? Price negotiations and supplier development decisions are made on gut feel or recent memory rather than data.\n\nThe SQE has an Excel sheet with thousands of incoming inspection rows. They can filter by supplier and eyeball the numbers, but comparing suppliers across multiple dimensions simultaneously is manual and time-consuming. Minitab could do it, but the license sits with the quality lab — the SQE doesn't have access.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ------------------------------- | -------------------------------------- | ------------------------------------------------------ | ----------------------------------- |\n| Supplier Quality Engineer (SQE) | Manufacturing, Automotive, Electronics | \"supplier quality comparison,\" \"supplier Cpk analysis\" | Excel pivot tables, manual reports |\n| Procurement / Sourcing Analyst | Any manufacturing | \"vendor rating system,\" \"supplier performance metrics\" | Scorecards, ERP reports |\n| Quality Manager | Manufacturing | \"incoming inspection analysis,\" \"supplier capability\" | Paper-based or spreadsheet tracking |\n\n## Keyword Cluster\n\n**Primary:**\n\n- supplier quality analysis\n- supplier performance comparison\n- supplier Cpk comparison\n\n**Long-tail:**\n\n- how to compare supplier quality data\n- supplier capability analysis example\n- incoming inspection variation analysis\n- supplier quality rating with data\n- which supplier is best statistically\n\n**Related queries:**\n\n- Minitab supplier analysis alternative\n- free supplier quality tool\n- supplier quality dashboard\n- vendor rating SPC\n- incoming inspection trend analysis\n\n## The VariScout Journey\n\n1. **Paste incoming inspection data** — rows with Supplier, Dimension, Measurement, Lot, Date columns\n2. **I-Chart** — see measurement stability over time across all suppliers mixed together (often looks chaotic)\n3. **Boxplot by Supplier** — immediate visual: Supplier C has wider spread. eta-squared shows \"Supplier explains 38% of variation\"\n4. **Drill-down: Supplier C** — filter to worst supplier, boxplot by Dimension reveals Dimension B is the problem (other dimensions are fine)\n5. **Capability** — Cpk for each supplier-dimension combination. Supplier C Dimension B: Cpk = 0.62 (target: 1.33)\n6. **Pareto** — 80% of rejects come from 2 of 5 suppliers\n7. **Performance Mode** — if multiple dimensions: rank all supplier-dimension combinations by Cpk, worst first\n\n**Aha moment:** \"We thought Supplier C was 'about the same' as the others. Their average is fine — but their variation on Dimension B makes them incapable. We now have the data to drive a focused supplier development conversation.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| ------------------------------------ | --------------------------------------------------------- |\n| \"All suppliers meet spec on average\" | Specific supplier + dimension failures identified |\n| Gut-feel supplier ratings | eta-squared quantifies supplier contribution to variation |\n| Reactive: catch bad lots | Proactive: identify suppliers trending toward failure |\n| Negotiations lack data leverage | Cpk evidence for supplier development conversations |\n| Hours building Excel pivot charts | 30-second paste-and-analyze |\n\n## Website Content Map\n\n**Landing page:** `/solutions/supplier-quality`\n\n- Headline: \"Which supplier is really the problem? Find out in 30 seconds.\"\n- Key message: Paste your incoming inspection data, see supplier capability ranked instantly\n- Interactive demo with sample supplier comparison data\n\n**Case study:** Incoming inspection dataset — 5 suppliers, 3 dimensions, 200 lots\n\n- Walk through: average hides the problem → boxplot reveals → drill-down isolates\n- Show eta-squared quantifying supplier contribution\n- Performance Mode ranking across dimensions\n\n**Blog posts:**\n\n- \"How to Compare Supplier Quality Beyond Pass/Fail\" (educational)\n- \"Why Average Incoming Inspection Data Lies\" (methodology — aggregation trap)\n- \"Supplier Cpk: The Number Your Procurement Team Needs\" (tool + methodology)\n\n**Social:**\n\n- LinkedIn: \"We analyzed 2 years of incoming inspection data in 30 seconds. Here's what we found hiding in the averages.\" (before/after visual)\n- YouTube: 2-minute demo — paste supplier data, watch the story unfold\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------ | ----------------------- | ----------------------------------------------------------------------------------- |\n| Discovery | **PWA** (free) | Paste sample data or own data, see supplier comparison instantly |\n| Ongoing monitoring | **Excel Add-in** (free) | Connect to incoming inspection spreadsheet, live slicer-based filtering |\n| Team adoption | **Azure App** (paid) | Multiple SQEs sharing analysis, OneDrive sync, Performance Mode for multi-dimension |", + "src/content/docs/02-journeys/use-cases/supplier-performance.md", + "bb161b56bbe268bb", + { "html": 5262, "metadata": 5263 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"supplier-performance-comparison\">Supplier Performance Comparison\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#supplier-performance-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Supplier Performance Comparison”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A Supplier Quality Engineer manages 3-8 suppliers for the same part. Incoming inspection catches individual lot failures, but there’s no systemic view — which supplier is actually capable? Which dimension is the weak point? Price negotiations and supplier development decisions are made on gut feel or recent memory rather than data.\u003C/p>\n\u003Cp>The SQE has an Excel sheet with thousands of incoming inspection rows. They can filter by supplier and eyeball the numbers, but comparing suppliers across multiple dimensions simultaneously is manual and time-consuming. Minitab could do it, but the license sits with the quality lab — the SQE doesn’t have access.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Supplier Quality Engineer (SQE)\u003C/td>\u003Ctd>Manufacturing, Automotive, Electronics\u003C/td>\u003Ctd>”supplier quality comparison,” “supplier Cpk analysis”\u003C/td>\u003Ctd>Excel pivot tables, manual reports\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Procurement / Sourcing Analyst\u003C/td>\u003Ctd>Any manufacturing\u003C/td>\u003Ctd>”vendor rating system,” “supplier performance metrics”\u003C/td>\u003Ctd>Scorecards, ERP reports\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quality Manager\u003C/td>\u003Ctd>Manufacturing\u003C/td>\u003Ctd>”incoming inspection analysis,” “supplier capability”\u003C/td>\u003Ctd>Paper-based or spreadsheet tracking\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>supplier quality analysis\u003C/li>\n\u003Cli>supplier performance comparison\u003C/li>\n\u003Cli>supplier Cpk comparison\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to compare supplier quality data\u003C/li>\n\u003Cli>supplier capability analysis example\u003C/li>\n\u003Cli>incoming inspection variation analysis\u003C/li>\n\u003Cli>supplier quality rating with data\u003C/li>\n\u003Cli>which supplier is best statistically\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Minitab supplier analysis alternative\u003C/li>\n\u003Cli>free supplier quality tool\u003C/li>\n\u003Cli>supplier quality dashboard\u003C/li>\n\u003Cli>vendor rating SPC\u003C/li>\n\u003Cli>incoming inspection trend analysis\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Paste incoming inspection data\u003C/strong> — rows with Supplier, Dimension, Measurement, Lot, Date columns\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — see measurement stability over time across all suppliers mixed together (often looks chaotic)\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Supplier\u003C/strong> — immediate visual: Supplier C has wider spread. eta-squared shows “Supplier explains 38% of variation”\u003C/li>\n\u003Cli>\u003Cstrong>Drill-down: Supplier C\u003C/strong> — filter to worst supplier, boxplot by Dimension reveals Dimension B is the problem (other dimensions are fine)\u003C/li>\n\u003Cli>\u003Cstrong>Capability\u003C/strong> — Cpk for each supplier-dimension combination. Supplier C Dimension B: Cpk = 0.62 (target: 1.33)\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong> — 80% of rejects come from 2 of 5 suppliers\u003C/li>\n\u003Cli>\u003Cstrong>Performance Mode\u003C/strong> — if multiple dimensions: rank all supplier-dimension combinations by Cpk, worst first\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “We thought Supplier C was ‘about the same’ as the others. Their average is fine — but their variation on Dimension B makes them incapable. We now have the data to drive a focused supplier development conversation.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”All suppliers meet spec on average”\u003C/td>\u003Ctd>Specific supplier + dimension failures identified\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Gut-feel supplier ratings\u003C/td>\u003Ctd>eta-squared quantifies supplier contribution to variation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Reactive: catch bad lots\u003C/td>\u003Ctd>Proactive: identify suppliers trending toward failure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Negotiations lack data leverage\u003C/td>\u003Ctd>Cpk evidence for supplier development conversations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hours building Excel pivot charts\u003C/td>\u003Ctd>30-second paste-and-analyze\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/supplier-quality\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Which supplier is really the problem? Find out in 30 seconds.”\u003C/li>\n\u003Cli>Key message: Paste your incoming inspection data, see supplier capability ranked instantly\u003C/li>\n\u003Cli>Interactive demo with sample supplier comparison data\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Incoming inspection dataset — 5 suppliers, 3 dimensions, 200 lots\u003C/p>\n\u003Cul>\n\u003Cli>Walk through: average hides the problem → boxplot reveals → drill-down isolates\u003C/li>\n\u003Cli>Show eta-squared quantifying supplier contribution\u003C/li>\n\u003Cli>Performance Mode ranking across dimensions\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“How to Compare Supplier Quality Beyond Pass/Fail” (educational)\u003C/li>\n\u003Cli>“Why Average Incoming Inspection Data Lies” (methodology — aggregation trap)\u003C/li>\n\u003Cli>“Supplier Cpk: The Number Your Procurement Team Needs” (tool + methodology)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “We analyzed 2 years of incoming inspection data in 30 seconds. Here’s what we found hiding in the averages.” (before/after visual)\u003C/li>\n\u003Cli>YouTube: 2-minute demo — paste supplier data, watch the story unfold\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Discovery\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste sample data or own data, see supplier comparison instantly\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Ongoing monitoring\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to incoming inspection spreadsheet, live slicer-based filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Team adoption\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Multiple SQEs sharing analysis, OneDrive sync, Performance Mode for multi-dimension\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5264, + "localImagePaths": 5274, + "remoteImagePaths": 5275, + "frontmatter": 5276, + "imagePaths": 5277 + }, + [5265, 5267, 5268, 5269, 5270, 5271, 5272, 5273], + { "depth": 30, "slug": 5266, "text": 5254 }, + "supplier-performance-comparison", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 5254 }, + [], + "02-journeys/use-cases/supplier-ppap", + { "id": 5278, "data": 5280, "body": 5285, "filePath": 5286, "digest": 5287, "rendered": 5288 }, + { + "title": 5281, + "editUrl": 16, + "head": 5282, + "template": 18, + "sidebar": 5283, + "pagefind": 16, + "draft": 20 + }, + "Supplier PPAP Capability Studies", + [], + { "hidden": 20, "attrs": 5284 }, + {}, + "# Supplier PPAP Capability Studies\n\n## The Problem\n\nA Supplier Quality Engineer at an automotive OEM or Tier 1 receives PPAP (Production Part Approval Process) submissions from suppliers. The supplier claims Cpk > 1.67 for critical characteristics, but are those numbers real? The SQE needs to verify independently — and quickly, because there are 15 suppliers and 200+ characteristics to review this quarter.\n\nCurrently, the SQE opens each supplier's Excel file, manually calculates Cpk in a separate spreadsheet, and spots-checks a few characteristics. Multi-characteristic parts (20+ dimensions) mean hours of work per submission. There's no way to see all characteristics ranked worst-first.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ------------------------------- | ---------------------- | -------------------------------------------------------------- | -------------------------------------- |\n| Supplier Quality Engineer (SQE) | Automotive OEM, Tier 1 | \"PPAP capability study,\" \"Cpk 1.67 verification\" | Excel, Minitab (if available) |\n| Quality Engineer | Automotive, Aerospace | \"process capability analysis tool,\" \"multi-characteristic Cpk\" | Manual Excel calculations |\n| Supplier Development Engineer | Manufacturing | \"supplier qualification capability,\" \"PPAP data analysis\" | Supplier-provided reports (unverified) |\n\n## Keyword Cluster\n\n**Primary:**\n\n- PPAP capability study\n- Cpk 1.67 requirement\n- process capability analysis tool\n- supplier qualification Cpk\n\n**Long-tail:**\n\n- how to verify supplier Cpk data\n- multi-characteristic capability analysis\n- PPAP initial sample inspection report\n- Cpk calculation for multiple dimensions\n- supplier PPAP data analysis tool free\n\n**Related queries:**\n\n- AIAG PPAP requirements\n- process capability index automotive\n- Minitab Cpk analysis alternative\n- capability study template\n- supplier part approval process tools\n\n## The VariScout Journey\n\n1. **Paste supplier measurement data** — rows with Characteristic, Sample, Measurement (often 30+ samples per characteristic per PPAP requirement)\n2. **I-Chart** — first check: is the data stable? A Cpk calculated on unstable data is meaningless. Nelson rules flag any instability\n3. **Capability** — Cpk with histogram and spec limits overlaid. Immediate visual: is the distribution centered? How much margin to spec?\n4. **Performance Mode** — all characteristics ranked by Cpk, worst first. Red/amber/green coding against 1.67 threshold\n5. **Drill into worst characteristic** — Cpk = 0.98 (claimed 1.72 by supplier). I-Chart shows drift — supplier's data was cherry-picked from a good period\n6. **Staged analysis** — if supplier claims improvement: before/after comparison validates (or disputes) the claim\n\n**Aha moment:** \"The supplier reported Cpk = 1.72. Our independent analysis shows 0.98 — and the process isn't even stable. They measured during a good run. Performance Mode flagged it in 10 seconds across 25 characteristics.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| -------------------------------------- | --------------------------------------------- |\n| Trust supplier-reported Cpk values | Independent verification in seconds |\n| Check 3 of 25 characteristics manually | Performance Mode ranks all 25, worst first |\n| No stability check before capability | I-Chart + Nelson rules verify stability first |\n| Hours per PPAP review | Minutes per PPAP review |\n| Binary pass/fail per characteristic | Visual Cpk with histogram — see _how_ capable |\n\n## Website Content Map\n\n**Landing page:** `/solutions/ppap-capability`\n\n- Headline: \"Verify supplier capability in minutes, not hours.\"\n- Key message: Paste PPAP data, see all characteristics ranked by Cpk. Worst first. Stability verified.\n- Interactive demo: 25-characteristic PPAP dataset\n\n**Case study:** Automotive PPAP submission — 25 critical characteristics, 30 samples each\n\n- Narrative: \"The supplier said Cpk = 1.72. We found 0.98.\"\n- Show Performance Mode ranking across characteristics\n- Demonstrate stability check catching cherry-picked data\n\n**Blog posts:**\n\n- \"How to Verify Supplier Cpk Data Independently\" (educational + tool)\n- \"Why Capability Without Stability Is Meaningless\" (methodology)\n- \"PPAP Capability Analysis in 5 Minutes: A Step-by-Step Guide\" (practical)\n\n**Social:**\n\n- LinkedIn: \"We review 200+ PPAP characteristics per quarter. Here's how we cut review time from hours to minutes per submission.\" (efficiency story)\n- YouTube: \"PPAP Capability Review with VariScout\" — 5-minute demo of multi-characteristic analysis\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------ | ----------------------- | ---------------------------------------------------------------------- |\n| Quick verification | **PWA** (free) | Paste supplier data, verify Cpk for a few characteristics |\n| Full PPAP review | **Excel Add-in** (free) | Connect to PPAP measurement spreadsheet, slicer by characteristic |\n| SQE team workflow | **Azure App** (paid) | Performance Mode across all characteristics, team sharing, audit trail |", + "src/content/docs/02-journeys/use-cases/supplier-ppap.md", + "25010a850f1a4006", + { "html": 5289, "metadata": 5290 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"supplier-ppap-capability-studies\">Supplier PPAP Capability Studies\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#supplier-ppap-capability-studies\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Supplier PPAP Capability Studies”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A Supplier Quality Engineer at an automotive OEM or Tier 1 receives PPAP (Production Part Approval Process) submissions from suppliers. The supplier claims Cpk > 1.67 for critical characteristics, but are those numbers real? The SQE needs to verify independently — and quickly, because there are 15 suppliers and 200+ characteristics to review this quarter.\u003C/p>\n\u003Cp>Currently, the SQE opens each supplier’s Excel file, manually calculates Cpk in a separate spreadsheet, and spots-checks a few characteristics. Multi-characteristic parts (20+ dimensions) mean hours of work per submission. There’s no way to see all characteristics ranked worst-first.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Supplier Quality Engineer (SQE)\u003C/td>\u003Ctd>Automotive OEM, Tier 1\u003C/td>\u003Ctd>”PPAP capability study,” “Cpk 1.67 verification”\u003C/td>\u003Ctd>Excel, Minitab (if available)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quality Engineer\u003C/td>\u003Ctd>Automotive, Aerospace\u003C/td>\u003Ctd>”process capability analysis tool,” “multi-characteristic Cpk”\u003C/td>\u003Ctd>Manual Excel calculations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Supplier Development Engineer\u003C/td>\u003Ctd>Manufacturing\u003C/td>\u003Ctd>”supplier qualification capability,” “PPAP data analysis”\u003C/td>\u003Ctd>Supplier-provided reports (unverified)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>PPAP capability study\u003C/li>\n\u003Cli>Cpk 1.67 requirement\u003C/li>\n\u003Cli>process capability analysis tool\u003C/li>\n\u003Cli>supplier qualification Cpk\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>how to verify supplier Cpk data\u003C/li>\n\u003Cli>multi-characteristic capability analysis\u003C/li>\n\u003Cli>PPAP initial sample inspection report\u003C/li>\n\u003Cli>Cpk calculation for multiple dimensions\u003C/li>\n\u003Cli>supplier PPAP data analysis tool free\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>AIAG PPAP requirements\u003C/li>\n\u003Cli>process capability index automotive\u003C/li>\n\u003Cli>Minitab Cpk analysis alternative\u003C/li>\n\u003Cli>capability study template\u003C/li>\n\u003Cli>supplier part approval process tools\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Paste supplier measurement data\u003C/strong> — rows with Characteristic, Sample, Measurement (often 30+ samples per characteristic per PPAP requirement)\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — first check: is the data stable? A Cpk calculated on unstable data is meaningless. Nelson rules flag any instability\u003C/li>\n\u003Cli>\u003Cstrong>Capability\u003C/strong> — Cpk with histogram and spec limits overlaid. Immediate visual: is the distribution centered? How much margin to spec?\u003C/li>\n\u003Cli>\u003Cstrong>Performance Mode\u003C/strong> — all characteristics ranked by Cpk, worst first. Red/amber/green coding against 1.67 threshold\u003C/li>\n\u003Cli>\u003Cstrong>Drill into worst characteristic\u003C/strong> — Cpk = 0.98 (claimed 1.72 by supplier). I-Chart shows drift — supplier’s data was cherry-picked from a good period\u003C/li>\n\u003Cli>\u003Cstrong>Staged analysis\u003C/strong> — if supplier claims improvement: before/after comparison validates (or disputes) the claim\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “The supplier reported Cpk = 1.72. Our independent analysis shows 0.98 — and the process isn’t even stable. They measured during a good run. Performance Mode flagged it in 10 seconds across 25 characteristics.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Trust supplier-reported Cpk values\u003C/td>\u003Ctd>Independent verification in seconds\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Check 3 of 25 characteristics manually\u003C/td>\u003Ctd>Performance Mode ranks all 25, worst first\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No stability check before capability\u003C/td>\u003Ctd>I-Chart + Nelson rules verify stability first\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hours per PPAP review\u003C/td>\u003Ctd>Minutes per PPAP review\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Binary pass/fail per characteristic\u003C/td>\u003Ctd>Visual Cpk with histogram — see \u003Cem>how\u003C/em> capable\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/ppap-capability\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Verify supplier capability in minutes, not hours.”\u003C/li>\n\u003Cli>Key message: Paste PPAP data, see all characteristics ranked by Cpk. Worst first. Stability verified.\u003C/li>\n\u003Cli>Interactive demo: 25-characteristic PPAP dataset\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Automotive PPAP submission — 25 critical characteristics, 30 samples each\u003C/p>\n\u003Cul>\n\u003Cli>Narrative: “The supplier said Cpk = 1.72. We found 0.98.”\u003C/li>\n\u003Cli>Show Performance Mode ranking across characteristics\u003C/li>\n\u003Cli>Demonstrate stability check catching cherry-picked data\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“How to Verify Supplier Cpk Data Independently” (educational + tool)\u003C/li>\n\u003Cli>“Why Capability Without Stability Is Meaningless” (methodology)\u003C/li>\n\u003Cli>“PPAP Capability Analysis in 5 Minutes: A Step-by-Step Guide” (practical)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “We review 200+ PPAP characteristics per quarter. Here’s how we cut review time from hours to minutes per submission.” (efficiency story)\u003C/li>\n\u003Cli>YouTube: “PPAP Capability Review with VariScout” — 5-minute demo of multi-characteristic analysis\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Quick verification\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Paste supplier data, verify Cpk for a few characteristics\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Full PPAP review\u003C/td>\u003Ctd>\u003Cstrong>Excel Add-in\u003C/strong> (free)\u003C/td>\u003Ctd>Connect to PPAP measurement spreadsheet, slicer by characteristic\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SQE team workflow\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Performance Mode across all characteristics, team sharing, audit trail\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5291, + "localImagePaths": 5301, + "remoteImagePaths": 5302, + "frontmatter": 5303, + "imagePaths": 5304 + }, + [5292, 5294, 5295, 5296, 5297, 5298, 5299, 5300], + { "depth": 30, "slug": 5293, "text": 5281 }, + "supplier-ppap-capability-studies", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 5281 }, + [], + "02-journeys/use-cases/university-spc", + { "id": 5305, "data": 5307, "body": 5312, "filePath": 5313, "digest": 5314, "rendered": 5315 }, + { + "title": 5308, + "editUrl": 16, + "head": 5309, + "template": 18, + "sidebar": 5310, + "pagefind": 16, + "draft": 20 + }, + "University SPC Course", + [], + { "hidden": 20, "attrs": 5311 }, + {}, + "# University SPC Course\n\n## The Problem\n\nA university lecturer teaches SPC or quality management to Industrial Engineering, Business, or Food Science students. The curriculum covers control charts, capability indices, and variation analysis — but students learn formulas on paper and never apply them to real data. Minitab licenses cost the university thousands per year and the interface overwhelms beginners. Students need to _think_ about variation, not learn which menu to click.\n\nThe lecturer wants students to paste homework data and see results instantly, with built-in explanations of what the charts mean. After the course ends, students should still have access — not be locked out when the license expires.\n\n## Target Searcher\n\n| Role | Industry | Searches for | Current tool |\n| ------------------------------- | ----------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------ |\n| University Lecturer / Professor | Higher Education (IE, Business, Food Sci) | \"free SPC software for students,\" \"control chart tool for teaching\" | Minitab (expensive), Excel (manual), hand calculations |\n| LSS Student / Trainee | Education, Corporate training | \"free Cpk calculator,\" \"how to read a control chart\" | YouTube, textbook examples, nothing interactive |\n| Teaching Assistant | Higher Education | \"SPC tutorial with examples,\" \"process capability calculator\" | Whatever the professor assigns |\n\n## Keyword Cluster\n\n**Primary:**\n\n- free SPC software for students\n- control chart tutorial\n- process capability calculator online\n- SPC training tool\n\n**Long-tail:**\n\n- free control chart maker with explanation\n- how to interpret a control chart step by step\n- Cpk calculator with histogram\n- boxplot vs control chart when to use which\n- SPC software without login\n\n**Related queries:**\n\n- Minitab alternative free\n- SPC practice problems with data\n- quality management tools for teaching\n- how to teach SPC effectively\n- variation analysis for beginners\n\n## The VariScout Journey\n\n1. **Arrive from course link or Google** — no login, no install, no license key\n2. **Explore sample dataset** — Coffee quality case study: familiar, engaging, real data\n3. **I-Chart** — see process stability, learn to spot out-of-control signals\n4. **Boxplot by factor** — \"Oh, the variation _between_ roasters is bigger than _within_\" — eta-squared quantifies it\n5. **Capability** — connect the histogram to Cp/Cpk, see what \"capable\" actually means visually\n6. **Glossary** — click any statistical term, get a plain-language definition\n7. **Paste homework data** — copy from course spreadsheet, analyze in seconds\n8. **Four Lenses** — learn the systematic framework: Change, Failure, Flow, Value\n\n**Aha moment:** \"I finally _see_ what Cpk means. The textbook formula made no sense until I saw the histogram with spec limits overlaid. And I can show my friends — they just open the link.\"\n\n## Before / After\n\n| Before VariScout | After VariScout |\n| ------------------------------------------------ | ------------------------------------------------------ |\n| Students memorize formulas, forget after exam | Interactive exploration builds intuitive understanding |\n| Minitab license: $1,000+/year for lab | Free forever, no license management |\n| Students lose access after course | Bookmark the PWA, use it in their careers |\n| Homework: hand-calculate Cpk from 10 values | Paste 200 rows, see capability instantly |\n| \"Click File > Stat > Quality Tools > Capability\" | Guided workflow teaches the _thinking_, not the menus |\n| No glossary in the tool | Every term explained in context |\n\n## Website Content Map\n\n**Landing page:** `/solutions/education`\n\n- Headline: \"Free SPC software for students and educators. No license. No login. Forever.\"\n- Key message: Built-in case studies, glossary, Four Lenses methodology — designed to teach thinking, not button-clicking\n- CTA: \"Try the Coffee Quality Case Study\" (direct link to PWA with sample data)\n\n**Case study:** Coffee quality dataset (already exists in `packages/data`)\n\n- Guided walkthrough: \"Find the answer\" format — guided frustration that builds understanding\n- Step-by-step: paste data → I-Chart → Boxplot → Capability → interpretation\n- Curriculum alignment: maps to common SPC course objectives\n\n**Blog posts:**\n\n- \"Teaching SPC Without Minitab: A Free Alternative\" (competitive + educational)\n- \"Why Students Should Learn Variation Thinking, Not Software Menus\" (methodology)\n- \"5 SPC Exercises You Can Run in a Browser — No Install Required\" (practical)\n\n**Social:**\n\n- LinkedIn: \"I stopped requiring Minitab for my SPC course. Here's what I use instead — and it's free.\" (professor testimonial angle)\n- YouTube: 5-minute demo — \"Analyze a dataset in VariScout: from paste to interpretation\"\n\n## Platform Fit\n\n| Stage | Product | Why |\n| ------------------- | ---------------------- | --------------------------------------------------------------------------- |\n| Course delivery | **PWA** (free forever) | No license, no install, works on student laptops and phones |\n| Advanced projects | **PWA** (free) | Regression, ANOVA cover Green Belt curriculum |\n| Department adoption | **Azure App** (paid) | Research groups, shared datasets, Performance Mode for multi-factor studies |", + "src/content/docs/02-journeys/use-cases/university-spc.md", + "caade43453b6f723", + { "html": 5316, "metadata": 5317 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"university-spc-course\">University SPC Course\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#university-spc-course\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “University SPC Course”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem\">The Problem\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A university lecturer teaches SPC or quality management to Industrial Engineering, Business, or Food Science students. The curriculum covers control charts, capability indices, and variation analysis — but students learn formulas on paper and never apply them to real data. Minitab licenses cost the university thousands per year and the interface overwhelms beginners. Students need to \u003Cem>think\u003C/em> about variation, not learn which menu to click.\u003C/p>\n\u003Cp>The lecturer wants students to paste homework data and see results instantly, with built-in explanations of what the charts mean. After the course ends, students should still have access — not be locked out when the license expires.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-searcher\">Target Searcher\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-searcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Searcher”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Searches for\u003C/th>\u003Cth>Current tool\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>University Lecturer / Professor\u003C/td>\u003Ctd>Higher Education (IE, Business, Food Sci)\u003C/td>\u003Ctd>“free SPC software for students,” “control chart tool for teaching”\u003C/td>\u003Ctd>Minitab (expensive), Excel (manual), hand calculations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LSS Student / Trainee\u003C/td>\u003Ctd>Education, Corporate training\u003C/td>\u003Ctd>”free Cpk calculator,” “how to read a control chart”\u003C/td>\u003Ctd>YouTube, textbook examples, nothing interactive\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Teaching Assistant\u003C/td>\u003Ctd>Higher Education\u003C/td>\u003Ctd>”SPC tutorial with examples,” “process capability calculator”\u003C/td>\u003Ctd>Whatever the professor assigns\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyword-cluster\">Keyword Cluster\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-cluster\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Cluster”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Primary:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>free SPC software for students\u003C/li>\n\u003Cli>control chart tutorial\u003C/li>\n\u003Cli>process capability calculator online\u003C/li>\n\u003Cli>SPC training tool\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Long-tail:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>free control chart maker with explanation\u003C/li>\n\u003Cli>how to interpret a control chart step by step\u003C/li>\n\u003Cli>Cpk calculator with histogram\u003C/li>\n\u003Cli>boxplot vs control chart when to use which\u003C/li>\n\u003Cli>SPC software without login\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Related queries:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Minitab alternative free\u003C/li>\n\u003Cli>SPC practice problems with data\u003C/li>\n\u003Cli>quality management tools for teaching\u003C/li>\n\u003Cli>how to teach SPC effectively\u003C/li>\n\u003Cli>variation analysis for beginners\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-variscout-journey\">The VariScout Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-variscout-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The VariScout Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Arrive from course link or Google\u003C/strong> — no login, no install, no license key\u003C/li>\n\u003Cli>\u003Cstrong>Explore sample dataset\u003C/strong> — Coffee quality case study: familiar, engaging, real data\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> — see process stability, learn to spot out-of-control signals\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by factor\u003C/strong> — “Oh, the variation \u003Cem>between\u003C/em> roasters is bigger than \u003Cem>within\u003C/em>” — eta-squared quantifies it\u003C/li>\n\u003Cli>\u003Cstrong>Capability\u003C/strong> — connect the histogram to Cp/Cpk, see what “capable” actually means visually\u003C/li>\n\u003Cli>\u003Cstrong>Glossary\u003C/strong> — click any statistical term, get a plain-language definition\u003C/li>\n\u003Cli>\u003Cstrong>Paste homework data\u003C/strong> — copy from course spreadsheet, analyze in seconds\u003C/li>\n\u003Cli>\u003Cstrong>Four Lenses\u003C/strong> — learn the systematic framework: Change, Failure, Flow, Value\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Aha moment:\u003C/strong> “I finally \u003Cem>see\u003C/em> what Cpk means. The textbook formula made no sense until I saw the histogram with spec limits overlaid. And I can show my friends — they just open the link.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"before--after\">Before / After\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before / After”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Before VariScout\u003C/th>\u003Cth>After VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Students memorize formulas, forget after exam\u003C/td>\u003Ctd>Interactive exploration builds intuitive understanding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Minitab license: $1,000+/year for lab\u003C/td>\u003Ctd>Free forever, no license management\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Students lose access after course\u003C/td>\u003Ctd>Bookmark the PWA, use it in their careers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Homework: hand-calculate Cpk from 10 values\u003C/td>\u003Ctd>Paste 200 rows, see capability instantly\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Click File > Stat > Quality Tools > Capability”\u003C/td>\u003Ctd>Guided workflow teaches the \u003Cem>thinking\u003C/em>, not the menus\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No glossary in the tool\u003C/td>\u003Ctd>Every term explained in context\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-content-map\">Website Content Map\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Landing page:\u003C/strong> \u003Ccode dir=\"auto\">/solutions/education\u003C/code>\u003C/p>\n\u003Cul>\n\u003Cli>Headline: “Free SPC software for students and educators. No license. No login. Forever.”\u003C/li>\n\u003Cli>Key message: Built-in case studies, glossary, Four Lenses methodology — designed to teach thinking, not button-clicking\u003C/li>\n\u003Cli>CTA: “Try the Coffee Quality Case Study” (direct link to PWA with sample data)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Case study:\u003C/strong> Coffee quality dataset (already exists in \u003Ccode dir=\"auto\">packages/data\u003C/code>)\u003C/p>\n\u003Cul>\n\u003Cli>Guided walkthrough: “Find the answer” format — guided frustration that builds understanding\u003C/li>\n\u003Cli>Step-by-step: paste data → I-Chart → Boxplot → Capability → interpretation\u003C/li>\n\u003Cli>Curriculum alignment: maps to common SPC course objectives\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Blog posts:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“Teaching SPC Without Minitab: A Free Alternative” (competitive + educational)\u003C/li>\n\u003Cli>“Why Students Should Learn Variation Thinking, Not Software Menus” (methodology)\u003C/li>\n\u003Cli>“5 SPC Exercises You Can Run in a Browser — No Install Required” (practical)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Social:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>LinkedIn: “I stopped requiring Minitab for my SPC course. Here’s what I use instead — and it’s free.” (professor testimonial angle)\u003C/li>\n\u003Cli>YouTube: 5-minute demo — “Analyze a dataset in VariScout: from paste to interpretation”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Product\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Course delivery\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free forever)\u003C/td>\u003Ctd>No license, no install, works on student laptops and phones\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Advanced projects\u003C/td>\u003Ctd>\u003Cstrong>PWA\u003C/strong> (free)\u003C/td>\u003Ctd>Regression, ANOVA cover Green Belt curriculum\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Department adoption\u003C/td>\u003Ctd>\u003Cstrong>Azure App\u003C/strong> (paid)\u003C/td>\u003Ctd>Research groups, shared datasets, Performance Mode for multi-factor studies\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5318, + "localImagePaths": 5328, + "remoteImagePaths": 5329, + "frontmatter": 5330, + "imagePaths": 5331 + }, + [5319, 5321, 5322, 5323, 5324, 5325, 5326, 5327], + { "depth": 30, "slug": 5320, "text": 5308 }, + "university-spc-course", + { "depth": 33, "slug": 4918, "text": 4919 }, + { "depth": 33, "slug": 4921, "text": 4922 }, + { "depth": 33, "slug": 4924, "text": 4925 }, + { "depth": 33, "slug": 4927, "text": 4928 }, + { "depth": 33, "slug": 4930, "text": 4931 }, + { "depth": 33, "slug": 4933, "text": 4934 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + [], + [], + { "title": 5308 }, + [], + "01-vision/evaluations/bottleneck-flow-map", + { "id": 5332, "data": 5334, "body": 5339, "filePath": 5340, "digest": 5341, "rendered": 5342 }, + { + "title": 5335, + "editUrl": 16, + "head": 5336, + "template": 18, + "sidebar": 5337, + "pagefind": 16, + "draft": 20 + }, + "Investigation Flow Map: Bottleneck Detection", + [], + { "hidden": 20, "attrs": 5338 }, + {}, + "# Investigation Flow Map: Bottleneck Detection\n\n> A step-by-step walkthrough of a complete variation investigation using the Bottleneck dataset, documenting what exists at each step, what guidance the analyst receives, and where gaps remain. Follows the [Pizza Delivery flow map](investigation-flow-map.md) format.\n\n---\n\n## Dataset: Process Step Bottleneck\n\n- **Source**: `packages/data/src/samples/bottleneck.ts`\n- **Outcome**: `Cycle_Time_sec` (target: 40s)\n- **Factors**: Step (Step 1–5), Shift (Morning, Afternoon)\n- **Data generation**: 150 observations = 5 steps x 2 shifts x 5 days x 3 reps. Step 2: mean=40, std=10 (the hidden bottleneck — high variance). Step 3: mean=45, std=2 (the decoy — high average, low variance). Steps 1, 4, 5: means=32, 34, 30, std=2. All clamped [15, 60].\n- **Expected story**: Step dominates variation. Step 2 is the real bottleneck (high variance starves downstream). Step 3 is the misdirection (highest average, but stable). The analyst must learn that variation matters more than location.\n\n---\n\n## Step 1: Data Loaded — Dashboard Shows Four Lenses\n\nThe analyst loads the Bottleneck sample via the home screen card or `/?sample=bottleneck`. The Dashboard renders the Four Lenses: I-Chart, Boxplot, Pareto, and Stats Panel.\n\n**What the analyst sees:**\n\n- **I-Chart**: 150 cycle times plotted sequentially. The pattern is noisy because all five steps are mixed together. Control limits are wide (~15–60s range). No clear trend — the mixed population masks structure.\n- **Boxplot**: Five groups for Step (the first factor). Step 3's box is shifted highest (~45s median). Step 2's box is dramatically wider than all others (IQR ~13s vs ~3s). Steps 1, 4, 5 cluster low and tight.\n- **Pareto**: Ranked by out-of-spec frequency against the 40s target.\n- **Stats Panel**: Overall mean ~36s, std dev ~7–8s, n=150. With the 40s target, Cpk is modest.\n\n**Existing guidance at this step:**\n\n- Boxplot shows **\"↓ drill here\"** label on the group with the highest contribution to variation (likely Step 2, since its spread dominates Total SS).\n- VariationBar at the top shows total variation scope.\n- No other suggestions unless the analyst interacts.\n\n**Gap — the Boxplot draws the eye to the wrong place:**\nStep 3 has the highest median, which is the most visually prominent feature in a boxplot (the center line). A first-time analyst will likely fixate on Step 3's position rather than Step 2's width. The \"↓ drill here\" label correctly points to the highest-variation step, but there is no teaching callout explaining _why_ a wide box matters more than a high box. The insight \"variation > location\" is the entire pedagogical point of this dataset, yet the product provides no guidance at this critical moment.\n\n---\n\n## Step 2: Boxplot Reveals the Misdirection\n\nThe analyst studies the Boxplot more carefully. Five groups are visible. Step 3 is the tallest (highest median ~45s). But Step 2 has a dramatically wider box — its IQR spans roughly 13 seconds while other steps span ~3 seconds.\n\n**What the analyst sees:**\n\n- Step 3 median is the highest — it looks like the \"worst\" step.\n- Step 2's box extends much further above and below its median (~40s). Whiskers reach from low 20s to high 50s.\n- Steps 1, 4, 5 are compact and low — clearly not the problem.\n- The \"↓ drill here\" label appears on Step 2 (highest contribution %), correctly identifying the high-variation step.\n- Contribution percentages are visible on the label, showing Step's dominance.\n\n**Existing guidance at this step:**\n\n- The \"↓ drill here\" label with contribution % on Step 2 is the key navigation cue.\n- ANOVA (visible in maximized boxplot view) shows Step is a significant factor with high F-statistic and low p-value.\n\n**Gap — no \"variation vs mean\" teaching moment:**\nThis is the critical decision point. The analyst must choose: drill into Step 3 (highest average — the intuitive choice) or Step 2 (highest variation — the correct choice). The \"↓ drill here\" label guides correctly but doesn't explain _why_. There is no callout like \"Step 2 has 3x the spread of Step 3 — inconsistency causes more downstream disruption than consistently slow operation.\" The product silently guides correctly but misses the teaching opportunity that makes this dataset valuable.\n\n---\n\n## Step 3: Click Step 2 — First Drill\n\nThe analyst clicks the Step 2 group in the Boxplot. The dashboard filters to only Step 2 observations.\n\n**What the analyst sees:**\n\n- **I-Chart**: 30 data points (Step 2 only). Wild scatter — values ranging from low 20s to high 50s. No stable pattern. Control limits are very wide, confirming high inherent variation.\n- **Boxplot**: Now shows Shift groups within Step 2 (Morning, Afternoon). Both boxes are wide.\n- **Pareto**: Shift-level ranking within Step 2.\n- **Stats Panel**: Mean ~40s, std dev ~10s, n=30. The standard deviation is the key number — it's 3–5x higher than other steps.\n- **FilterBreadcrumb**: A chip appears: **\"Step: Step 2 XX%\"** — showing Step 2's contribution to total variation. The percentage is high, confirming this is the dominant source.\n- **VariationBar**: Updates to show cumulative explained variation.\n\n**Existing guidance at this step:**\n\n- Filter chip with contribution % badge confirms this is a meaningful filter.\n- Boxplot \"↓ drill here\" appears on one of the Shift groups.\n- VariationBar shows progress in the investigation.\n\n**Gap — no \"you found the problem\" confirmation:**\nThe analyst has correctly identified the high-variation step, but nothing in the UI celebrates or confirms this. The I-Chart's wild scatter is the visual proof, and the std dev ~10 is the numeric proof, but there's no explicit comparison to other steps. The analyst would need to mentally recall that other steps had std ~2–3 to appreciate the 3–5x difference. A side-by-side comparison or \"Step 2's variation is 3x the average of other steps\" callout would reinforce the finding.\n\n---\n\n## Step 4: Shift within Step 2 — Not the Cause\n\nThe analyst examines the Boxplot showing Morning vs Afternoon shifts within Step 2.\n\n**What the analyst sees:**\n\n- **Boxplot**: Two boxes (Morning, Afternoon) with similar medians (~40s) and similarly wide spread. Neither shift is dramatically different from the other.\n- **\"↓ drill here\"** may appear on one shift, but the contribution % is low.\n- **ANOVA** (if checked): Shift within Step 2 has a low F-statistic and high p-value. Shift explains negligible variation within Step 2.\n\n**Existing guidance at this step:**\n\n- Low contribution % on the Shift label signals this factor isn't important within the current filter.\n- ANOVA confirms Shift is not significant.\n\n**Gap — no \"dead end\" signal:**\nThe analyst has reached a dead end — Shift doesn't explain Step 2's variation. The problem is the step's process itself, not when it runs. But nothing in the UI explicitly says \"this factor doesn't help.\" The analyst must interpret the similar-looking boxes and low contribution % themselves. A prompt like \"Shift explains \u003C5% of remaining variation — the variability is inherent to Step 2's process\" would close the loop and redirect the analyst's attention.\n\n---\n\n## Step 5: Backtrack, Click Step 3 — The Contrast\n\nThe analyst removes the Step 2 filter (clicks the X on the filter chip) to return to the full dataset, then clicks Step 3 in the Boxplot.\n\n**What the analyst sees:**\n\n- **I-Chart**: 30 data points (Step 3 only). Remarkably stable — values cluster tightly around 45s. Very narrow control limits. A textbook example of an in-control process.\n- **Boxplot**: Shows Shift groups within Step 3, both tight.\n- **Stats Panel**: Mean ~45s (higher than Step 2!), std dev ~2s (5x lower than Step 2). The contrast is stark.\n- **FilterBreadcrumb**: \"Step: Step 3 XX%\".\n\n**Existing guidance at this step:**\n\n- The stats panel clearly shows the low std dev.\n- Filter chip shows contribution %.\n\n**Gap — no comparison context from the previous drill:**\nThis is where the pedagogical payoff should happen: Step 2 (mean ~40, std ~10) vs Step 3 (mean ~45, std ~2). But the analyst has to remember Step 2's numbers from memory. The sequential drill-down loses the comparison context — each filter shows its own stats in isolation. There is no \"compared to Step 2, this step has 5x less variation\" callout. No side-by-side view of drill results. The \"slow but predictable vs fast but chaotic\" insight requires the analyst to hold two mental models simultaneously.\n\n---\n\n## Step 6: Return to Full View\n\nThe analyst removes the Step 3 filter to return to the full 150-point dataset.\n\n**What the analyst sees:**\n\n- Overall stats restored: mean ~36s, std dev ~7–8s, n=150.\n- ANOVA (in maximized boxplot view) confirms Step is statistically significant with high F-statistic and low p-value.\n- The Boxplot shows all five steps again, with Step 2's wide spread and Step 3's high position clearly visible.\n\n**Existing guidance at this step:**\n\n- ANOVA provides the statistical confirmation.\n- The Boxplot's visual structure tells the whole story if the analyst knows how to read it.\n- Contribution % on the \"↓ drill here\" label quantifies Step's importance.\n\n**Gap — no investigation summary:**\nThe analyst has now drilled into Step 2 (chaotic), drilled into Step 3 (stable), and returned to the overview. But there's no record of this journey and no synthesis. The breadcrumbs are gone (filters removed). The investigation exists only in the analyst's memory. There is no \"You investigated 2 of 5 steps and found that Step 2's variation (std=10) dominates the process\" summary.\n\n---\n\n## Step 7: Investigation Complete — Aha Moment\n\nThe investigation concludes with the core insight: **\"The bottleneck isn't where the average is highest — it's where the variation is highest.\"**\n\n**What the analyst should take away:**\n\n- Step 3 has the highest average cycle time (45s) but is stable and predictable.\n- Step 2 has a lower average (40s) but 3–5x the variation — it's unpredictable.\n- Unpredictable process times cause waiting, buffer starvation, and cascading delays downstream. A consistently slow step can be planned around; an inconsistent step cannot.\n- Investing in Step 3 equipment (the management assumption) would not solve the problem.\n- Step 2 needs investigation: operator training, equipment standardization, or process redesign.\n\n**Existing guidance at this step:**\n\n- None — the product provides no investigation conclusion or narrative summary.\n\n**Gap — no narrative wrap-up:**\nThe entire teaching arc depends on the analyst constructing the \"variation > mean\" narrative themselves. For Green Belt Gary, this is manageable. For Student Sara or Curious Carlos encountering this concept for the first time, the product misses the opportunity to make the lesson explicit. There is no \"what you found\" summary, no suggested action, no connection between the statistical finding and the operational implication.\n\n---\n\n## Summary: Guidance Coverage by Step\n\n| Step | Description | Existing Guidance | Gaps |\n| ---- | ---------------------------- | -------------------------------------------- | ---------------------------------------------------------- |\n| 1 | Data loaded | Boxplot \"↓ drill here\", VariationBar | Eye drawn to Step 3's high median, not Step 2's wide box |\n| 2 | Boxplot reveals misdirection | \"↓ drill here\" on Step 2 with contribution % | No teaching callout: \"variation matters more than average\" |\n| 3 | Drill into Step 2 | Filter chip with %, I-Chart shows scatter | No confirmation: \"you found the high-variation step\" |\n| 4 | Shift within Step 2 | Low contribution %, ANOVA not significant | No \"dead end\" signal to redirect investigation |\n| 5 | Backtrack, drill Step 3 | Stats show low std dev | No comparison to Step 2 — sequential drills lose context |\n| 6 | Return to full view | ANOVA confirms Step is significant | No investigation summary or journey record |\n| 7 | Investigation complete | (none) | No narrative conclusion or teaching wrap-up |\n\n---\n\n## Key Takeaways for Design\n\n1. **The Boxplot is the hero chart for this dataset** — its visual encoding of both location (median) and spread (box width, whiskers) makes the Step 2 vs Step 3 contrast visible at a glance. But the product relies on the analyst knowing how to read spread, not just position.\n\n2. **The \"↓ drill here\" label is correct but unexplained** — it points to the right step (Step 2, highest variation) but doesn't teach _why_ variation matters more than the average. This is the single highest-impact guidance gap for this dataset.\n\n3. **Sequential drilling loses comparison context** — the analyst drills Step 2, sees std=10, then drills Step 3, sees std=2. But these are separate screens with no side-by-side view. The \"3x the variation\" insight requires mental arithmetic across drill states.\n\n4. **No teaching callout for the \"variation > mean\" principle** — this is the core lesson of the Bottleneck case study, the ESTIEM training narrative, and the use case page promise. Yet the product provides no explicit guidance at the moment the analyst needs it.\n\n5. **The Mindmap would capture the investigation trail** — if the analyst used the Mindmap panel, drill history would be preserved. But the Mindmap doesn't currently surface the \"variation comparison\" insight either.\n\n---\n\n## Related Documents\n\n- [Bottleneck Case Study](../../04-cases/bottleneck/index.md) — Teaching narrative and dataset description\n- [Bottleneck Analysis Use Case](../../02-journeys/use-cases/bottleneck-analysis.md) — Use case promise and SEO strategy\n- [Pizza Delivery Flow Map](investigation-flow-map.md) — Template this document follows\n- [Hospital Ward Flow Map](hospital-ward-flow-map.md) — Companion flow map demonstrating the aggregation trap", + "src/content/docs/01-vision/evaluations/bottleneck-flow-map.md", + "3925d31712cf6316", + { "html": 5343, "metadata": 5344 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"investigation-flow-map-bottleneck-detection\">Investigation Flow Map: Bottleneck Detection\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-flow-map-bottleneck-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation Flow Map: Bottleneck Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>A step-by-step walkthrough of a complete variation investigation using the Bottleneck dataset, documenting what exists at each step, what guidance the analyst receives, and where gaps remain. Follows the \u003Ca href=\"investigation-flow-map.md\">Pizza Delivery flow map\u003C/a> format.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dataset-process-step-bottleneck\">Dataset: Process Step Bottleneck\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dataset-process-step-bottleneck\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dataset: Process Step Bottleneck”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Source\u003C/strong>: \u003Ccode dir=\"auto\">packages/data/src/samples/bottleneck.ts\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Outcome\u003C/strong>: \u003Ccode dir=\"auto\">Cycle_Time_sec\u003C/code> (target: 40s)\u003C/li>\n\u003Cli>\u003Cstrong>Factors\u003C/strong>: Step (Step 1–5), Shift (Morning, Afternoon)\u003C/li>\n\u003Cli>\u003Cstrong>Data generation\u003C/strong>: 150 observations = 5 steps x 2 shifts x 5 days x 3 reps. Step 2: mean=40, std=10 (the hidden bottleneck — high variance). Step 3: mean=45, std=2 (the decoy — high average, low variance). Steps 1, 4, 5: means=32, 34, 30, std=2. All clamped [15, 60].\u003C/li>\n\u003Cli>\u003Cstrong>Expected story\u003C/strong>: Step dominates variation. Step 2 is the real bottleneck (high variance starves downstream). Step 3 is the misdirection (highest average, but stable). The analyst must learn that variation matters more than location.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-1-data-loaded--dashboard-shows-four-lenses\">Step 1: Data Loaded — Dashboard Shows Four Lenses\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-data-loaded--dashboard-shows-four-lenses\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Data Loaded — Dashboard Shows Four Lenses”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst loads the Bottleneck sample via the home screen card or \u003Ccode dir=\"auto\">/?sample=bottleneck\u003C/code>. The Dashboard renders the Four Lenses: I-Chart, Boxplot, Pareto, and Stats Panel.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: 150 cycle times plotted sequentially. The pattern is noisy because all five steps are mixed together. Control limits are wide (~15–60s range). No clear trend — the mixed population masks structure.\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Five groups for Step (the first factor). Step 3’s box is shifted highest (~45s median). Step 2’s box is dramatically wider than all others (IQR ~13s vs ~3s). Steps 1, 4, 5 cluster low and tight.\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong>: Ranked by out-of-spec frequency against the 40s target.\u003C/li>\n\u003Cli>\u003Cstrong>Stats Panel\u003C/strong>: Overall mean ~36s, std dev ~7–8s, n=150. With the 40s target, Cpk is modest.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Boxplot shows \u003Cstrong>”↓ drill here”\u003C/strong> label on the group with the highest contribution to variation (likely Step 2, since its spread dominates Total SS).\u003C/li>\n\u003Cli>VariationBar at the top shows total variation scope.\u003C/li>\n\u003Cli>No other suggestions unless the analyst interacts.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — the Boxplot draws the eye to the wrong place:\u003C/strong>\nStep 3 has the highest median, which is the most visually prominent feature in a boxplot (the center line). A first-time analyst will likely fixate on Step 3’s position rather than Step 2’s width. The ”↓ drill here” label correctly points to the highest-variation step, but there is no teaching callout explaining \u003Cem>why\u003C/em> a wide box matters more than a high box. The insight “variation > location” is the entire pedagogical point of this dataset, yet the product provides no guidance at this critical moment.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-2-boxplot-reveals-the-misdirection\">Step 2: Boxplot Reveals the Misdirection\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-boxplot-reveals-the-misdirection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Boxplot Reveals the Misdirection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst studies the Boxplot more carefully. Five groups are visible. Step 3 is the tallest (highest median ~45s). But Step 2 has a dramatically wider box — its IQR spans roughly 13 seconds while other steps span ~3 seconds.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Step 3 median is the highest — it looks like the “worst” step.\u003C/li>\n\u003Cli>Step 2’s box extends much further above and below its median (~40s). Whiskers reach from low 20s to high 50s.\u003C/li>\n\u003Cli>Steps 1, 4, 5 are compact and low — clearly not the problem.\u003C/li>\n\u003Cli>The ”↓ drill here” label appears on Step 2 (highest contribution %), correctly identifying the high-variation step.\u003C/li>\n\u003Cli>Contribution percentages are visible on the label, showing Step’s dominance.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>The ”↓ drill here” label with contribution % on Step 2 is the key navigation cue.\u003C/li>\n\u003Cli>ANOVA (visible in maximized boxplot view) shows Step is a significant factor with high F-statistic and low p-value.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no “variation vs mean” teaching moment:\u003C/strong>\nThis is the critical decision point. The analyst must choose: drill into Step 3 (highest average — the intuitive choice) or Step 2 (highest variation — the correct choice). The ”↓ drill here” label guides correctly but doesn’t explain \u003Cem>why\u003C/em>. There is no callout like “Step 2 has 3x the spread of Step 3 — inconsistency causes more downstream disruption than consistently slow operation.” The product silently guides correctly but misses the teaching opportunity that makes this dataset valuable.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-3-click-step-2--first-drill\">Step 3: Click Step 2 — First Drill\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-click-step-2--first-drill\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Click Step 2 — First Drill”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst clicks the Step 2 group in the Boxplot. The dashboard filters to only Step 2 observations.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: 30 data points (Step 2 only). Wild scatter — values ranging from low 20s to high 50s. No stable pattern. Control limits are very wide, confirming high inherent variation.\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Now shows Shift groups within Step 2 (Morning, Afternoon). Both boxes are wide.\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong>: Shift-level ranking within Step 2.\u003C/li>\n\u003Cli>\u003Cstrong>Stats Panel\u003C/strong>: Mean ~40s, std dev ~10s, n=30. The standard deviation is the key number — it’s 3–5x higher than other steps.\u003C/li>\n\u003Cli>\u003Cstrong>FilterBreadcrumb\u003C/strong>: A chip appears: \u003Cstrong>“Step: Step 2 XX%”\u003C/strong> — showing Step 2’s contribution to total variation. The percentage is high, confirming this is the dominant source.\u003C/li>\n\u003Cli>\u003Cstrong>VariationBar\u003C/strong>: Updates to show cumulative explained variation.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Filter chip with contribution % badge confirms this is a meaningful filter.\u003C/li>\n\u003Cli>Boxplot ”↓ drill here” appears on one of the Shift groups.\u003C/li>\n\u003Cli>VariationBar shows progress in the investigation.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no “you found the problem” confirmation:\u003C/strong>\nThe analyst has correctly identified the high-variation step, but nothing in the UI celebrates or confirms this. The I-Chart’s wild scatter is the visual proof, and the std dev ~10 is the numeric proof, but there’s no explicit comparison to other steps. The analyst would need to mentally recall that other steps had std ~2–3 to appreciate the 3–5x difference. A side-by-side comparison or “Step 2’s variation is 3x the average of other steps” callout would reinforce the finding.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-4-shift-within-step-2--not-the-cause\">Step 4: Shift within Step 2 — Not the Cause\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-shift-within-step-2--not-the-cause\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Shift within Step 2 — Not the Cause”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst examines the Boxplot showing Morning vs Afternoon shifts within Step 2.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Two boxes (Morning, Afternoon) with similar medians (~40s) and similarly wide spread. Neither shift is dramatically different from the other.\u003C/li>\n\u003Cli>\u003Cstrong>”↓ drill here”\u003C/strong> may appear on one shift, but the contribution % is low.\u003C/li>\n\u003Cli>\u003Cstrong>ANOVA\u003C/strong> (if checked): Shift within Step 2 has a low F-statistic and high p-value. Shift explains negligible variation within Step 2.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Low contribution % on the Shift label signals this factor isn’t important within the current filter.\u003C/li>\n\u003Cli>ANOVA confirms Shift is not significant.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no “dead end” signal:\u003C/strong>\nThe analyst has reached a dead end — Shift doesn’t explain Step 2’s variation. The problem is the step’s process itself, not when it runs. But nothing in the UI explicitly says “this factor doesn’t help.” The analyst must interpret the similar-looking boxes and low contribution % themselves. A prompt like “Shift explains <5% of remaining variation — the variability is inherent to Step 2’s process” would close the loop and redirect the analyst’s attention.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-5-backtrack-click-step-3--the-contrast\">Step 5: Backtrack, Click Step 3 — The Contrast\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-backtrack-click-step-3--the-contrast\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Backtrack, Click Step 3 — The Contrast”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst removes the Step 2 filter (clicks the X on the filter chip) to return to the full dataset, then clicks Step 3 in the Boxplot.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: 30 data points (Step 3 only). Remarkably stable — values cluster tightly around 45s. Very narrow control limits. A textbook example of an in-control process.\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Shows Shift groups within Step 3, both tight.\u003C/li>\n\u003Cli>\u003Cstrong>Stats Panel\u003C/strong>: Mean ~45s (higher than Step 2!), std dev ~2s (5x lower than Step 2). The contrast is stark.\u003C/li>\n\u003Cli>\u003Cstrong>FilterBreadcrumb\u003C/strong>: “Step: Step 3 XX%”.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>The stats panel clearly shows the low std dev.\u003C/li>\n\u003Cli>Filter chip shows contribution %.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no comparison context from the previous drill:\u003C/strong>\nThis is where the pedagogical payoff should happen: Step 2 (mean ~40, std ~10) vs Step 3 (mean ~45, std ~2). But the analyst has to remember Step 2’s numbers from memory. The sequential drill-down loses the comparison context — each filter shows its own stats in isolation. There is no “compared to Step 2, this step has 5x less variation” callout. No side-by-side view of drill results. The “slow but predictable vs fast but chaotic” insight requires the analyst to hold two mental models simultaneously.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-6-return-to-full-view\">Step 6: Return to Full View\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-6-return-to-full-view\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 6: Return to Full View”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst removes the Step 3 filter to return to the full 150-point dataset.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Overall stats restored: mean ~36s, std dev ~7–8s, n=150.\u003C/li>\n\u003Cli>ANOVA (in maximized boxplot view) confirms Step is statistically significant with high F-statistic and low p-value.\u003C/li>\n\u003Cli>The Boxplot shows all five steps again, with Step 2’s wide spread and Step 3’s high position clearly visible.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>ANOVA provides the statistical confirmation.\u003C/li>\n\u003Cli>The Boxplot’s visual structure tells the whole story if the analyst knows how to read it.\u003C/li>\n\u003Cli>Contribution % on the ”↓ drill here” label quantifies Step’s importance.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no investigation summary:\u003C/strong>\nThe analyst has now drilled into Step 2 (chaotic), drilled into Step 3 (stable), and returned to the overview. But there’s no record of this journey and no synthesis. The breadcrumbs are gone (filters removed). The investigation exists only in the analyst’s memory. There is no “You investigated 2 of 5 steps and found that Step 2’s variation (std=10) dominates the process” summary.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-7-investigation-complete--aha-moment\">Step 7: Investigation Complete — Aha Moment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-7-investigation-complete--aha-moment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 7: Investigation Complete — Aha Moment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The investigation concludes with the core insight: \u003Cstrong>“The bottleneck isn’t where the average is highest — it’s where the variation is highest.”\u003C/strong>\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst should take away:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Step 3 has the highest average cycle time (45s) but is stable and predictable.\u003C/li>\n\u003Cli>Step 2 has a lower average (40s) but 3–5x the variation — it’s unpredictable.\u003C/li>\n\u003Cli>Unpredictable process times cause waiting, buffer starvation, and cascading delays downstream. A consistently slow step can be planned around; an inconsistent step cannot.\u003C/li>\n\u003Cli>Investing in Step 3 equipment (the management assumption) would not solve the problem.\u003C/li>\n\u003Cli>Step 2 needs investigation: operator training, equipment standardization, or process redesign.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>None — the product provides no investigation conclusion or narrative summary.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no narrative wrap-up:\u003C/strong>\nThe entire teaching arc depends on the analyst constructing the “variation > mean” narrative themselves. For Green Belt Gary, this is manageable. For Student Sara or Curious Carlos encountering this concept for the first time, the product misses the opportunity to make the lesson explicit. There is no “what you found” summary, no suggested action, no connection between the statistical finding and the operational implication.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"summary-guidance-coverage-by-step\">Summary: Guidance Coverage by Step\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#summary-guidance-coverage-by-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Summary: Guidance Coverage by Step”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Step\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Existing Guidance\u003C/th>\u003Cth>Gaps\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Data loaded\u003C/td>\u003Ctd>Boxplot ”↓ drill here”, VariationBar\u003C/td>\u003Ctd>Eye drawn to Step 3’s high median, not Step 2’s wide box\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Boxplot reveals misdirection\u003C/td>\u003Ctd>”↓ drill here” on Step 2 with contribution %\u003C/td>\u003Ctd>No teaching callout: “variation matters more than average”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Drill into Step 2\u003C/td>\u003Ctd>Filter chip with %, I-Chart shows scatter\u003C/td>\u003Ctd>No confirmation: “you found the high-variation step”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Shift within Step 2\u003C/td>\u003Ctd>Low contribution %, ANOVA not significant\u003C/td>\u003Ctd>No “dead end” signal to redirect investigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Backtrack, drill Step 3\u003C/td>\u003Ctd>Stats show low std dev\u003C/td>\u003Ctd>No comparison to Step 2 — sequential drills lose context\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Return to full view\u003C/td>\u003Ctd>ANOVA confirms Step is significant\u003C/td>\u003Ctd>No investigation summary or journey record\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>Investigation complete\u003C/td>\u003Ctd>(none)\u003C/td>\u003Ctd>No narrative conclusion or teaching wrap-up\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-takeaways-for-design\">Key Takeaways for Design\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-takeaways-for-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Takeaways for Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>The Boxplot is the hero chart for this dataset\u003C/strong> — its visual encoding of both location (median) and spread (box width, whiskers) makes the Step 2 vs Step 3 contrast visible at a glance. But the product relies on the analyst knowing how to read spread, not just position.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>The ”↓ drill here” label is correct but unexplained\u003C/strong> — it points to the right step (Step 2, highest variation) but doesn’t teach \u003Cem>why\u003C/em> variation matters more than the average. This is the single highest-impact guidance gap for this dataset.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Sequential drilling loses comparison context\u003C/strong> — the analyst drills Step 2, sees std=10, then drills Step 3, sees std=2. But these are separate screens with no side-by-side view. The “3x the variation” insight requires mental arithmetic across drill states.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>No teaching callout for the “variation > mean” principle\u003C/strong> — this is the core lesson of the Bottleneck case study, the ESTIEM training narrative, and the use case page promise. Yet the product provides no explicit guidance at the moment the analyst needs it.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>The Mindmap would capture the investigation trail\u003C/strong> — if the analyst used the Mindmap panel, drill history would be preserved. But the Mindmap doesn’t currently surface the “variation comparison” insight either.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documents\">Related Documents\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documents\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documents”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../04-cases/bottleneck/index.md\">Bottleneck Case Study\u003C/a> — Teaching narrative and dataset description\u003C/li>\n\u003Cli>\u003Ca href=\"../../02-journeys/use-cases/bottleneck-analysis.md\">Bottleneck Analysis Use Case\u003C/a> — Use case promise and SEO strategy\u003C/li>\n\u003Cli>\u003Ca href=\"investigation-flow-map.md\">Pizza Delivery Flow Map\u003C/a> — Template this document follows\u003C/li>\n\u003Cli>\u003Ca href=\"hospital-ward-flow-map.md\">Hospital Ward Flow Map\u003C/a> — Companion flow map demonstrating the aggregation trap\u003C/li>\n\u003C/ul>", + { + "headings": 5345, + "localImagePaths": 5379, + "remoteImagePaths": 5380, + "frontmatter": 5381, + "imagePaths": 5382 + }, + [5346, 5348, 5351, 5354, 5357, 5360, 5363, 5366, 5369, 5372, 5375, 5378], + { "depth": 30, "slug": 5347, "text": 5335 }, + "investigation-flow-map-bottleneck-detection", + { "depth": 33, "slug": 5349, "text": 5350 }, + "dataset-process-step-bottleneck", + "Dataset: Process Step Bottleneck", + { "depth": 33, "slug": 5352, "text": 5353 }, + "step-1-data-loaded--dashboard-shows-four-lenses", + "Step 1: Data Loaded — Dashboard Shows Four Lenses", + { "depth": 33, "slug": 5355, "text": 5356 }, + "step-2-boxplot-reveals-the-misdirection", + "Step 2: Boxplot Reveals the Misdirection", + { "depth": 33, "slug": 5358, "text": 5359 }, + "step-3-click-step-2--first-drill", + "Step 3: Click Step 2 — First Drill", + { "depth": 33, "slug": 5361, "text": 5362 }, + "step-4-shift-within-step-2--not-the-cause", + "Step 4: Shift within Step 2 — Not the Cause", + { "depth": 33, "slug": 5364, "text": 5365 }, + "step-5-backtrack-click-step-3--the-contrast", + "Step 5: Backtrack, Click Step 3 — The Contrast", + { "depth": 33, "slug": 5367, "text": 5368 }, + "step-6-return-to-full-view", + "Step 6: Return to Full View", + { "depth": 33, "slug": 5370, "text": 5371 }, + "step-7-investigation-complete--aha-moment", + "Step 7: Investigation Complete — Aha Moment", + { "depth": 33, "slug": 5373, "text": 5374 }, + "summary-guidance-coverage-by-step", + "Summary: Guidance Coverage by Step", + { "depth": 33, "slug": 5376, "text": 5377 }, + "key-takeaways-for-design", + "Key Takeaways for Design", + { "depth": 33, "slug": 4342, "text": 4343 }, + [], + [], + { "title": 5335 }, + [], + "01-vision/evaluations/design-brief-guided-investigation", + { "id": 5383, "data": 5385, "body": 5390, "filePath": 5391, "digest": 5392, "rendered": 5393 }, + { + "title": 5386, + "editUrl": 16, + "head": 5387, + "template": 18, + "sidebar": 5388, + "pagefind": 16, + "draft": 20 + }, + "Design Brief: Guided Investigation", + [], + { "hidden": 20, "attrs": 5389 }, + {}, + "# Design Brief: Guided Investigation\n\n> **Historical document** — this design brief led to the Investigation Mindmap (Phases A-D).\n> See [design-spec-investigation-mindmap.md](./design-spec-investigation-mindmap.md) for final spec.\n\n> Synthesis document bridging competitive intelligence, existing codebase capabilities, and design questions for the Factor Suggestion (Phase 1) and Interaction Heatmap (Phase 2) features.\n\n---\n\n## 1. Statistical Methodology\n\nThe guided investigation features build on two distinct statistical engines already present in `@variscout/core`. This section resolves which engine serves which purpose.\n\n### Main Effects: Eta-Squared (Drill-Down Ranking)\n\nThe drill-down workflow uses one-way ANOVA eta-squared (η² = SS_between / SS_total) to rank factors by explanatory power. This is the correct metric for the \"which factor next?\" question because it quantifies how much of the outcome's total variation is attributable to group membership.\n\n| Capability | Implementation | Location | Status |\n| ------------------------- | ----------------------------------------- | --------------------------------------------- | ------ |\n| Single-factor η² | `getEtaSquared(data, factor, outcome)` | `packages/core/src/stats.ts:177` | Exists |\n| Per-category contribution | `useVariationTracking` → `filterChipData` | `packages/hooks/src/useVariationTracking.ts` | Exists |\n| Cumulative η² tracking | `useVariationTracking` → running sum | `packages/hooks/src/useVariationTracking.ts` | Exists |\n| Factor ranking by η² | `VariationFunnel` → `optimalFactors` | `apps/pwa/src/components/VariationFunnel.tsx` | Exists |\n\n**Key property**: η² values are computed per-factor against the current filtered subset, so they update dynamically as the analyst drills down. This is the foundation for factor suggestion — the highest η² among remaining (unfiltered) factors is the suggested next step.\n\n### Interactions: Multiple Regression / GLM\n\nInteraction detection uses the multiple regression engine, which already supports categorical predictors (dummy-encoded) and two-way interaction terms.\n\n| Capability | Implementation | Location | Status |\n| ----------------------------- | ------------------------------------------------------------------------------- | -------------------------------------- | --------------------- |\n| Interaction term fitting | `calculateMultipleRegression(data, y, [x1, x2], { includeInteractions: true })` | `packages/core/src/stats.ts:1886` | Exists |\n| Categorical × categorical | Dummy encoding with interaction columns | `packages/core/src/stats.ts:1644–1682` | Exists |\n| Standardized coefficients | `CoefficientResult.standardizedBeta` | `packages/core/src/types.ts:598` | Exists |\n| Significance testing | `CoefficientResult.tStatistic`, `CoefficientResult.pValue` | `packages/core/src/types.ts:593–596` | Exists |\n| Interaction term type flag | `RegressionTerm.type: 'interaction'` | `packages/core/src/types.ts:575` | Exists |\n| Interaction effect size (ΔR²) | Compare R² of model with and without interaction terms | — | **Needs thin helper** |\n\n**The ΔR² helper**: To quantify how much additional variation an interaction explains beyond the main effects, run `calculateMultipleRegression` twice — once with `includeInteractions: false`, once with `includeInteractions: true` — and compute ΔR² = R²_full − R²_main. This is a ~10-line utility function, not a new statistical engine. The individual interaction term standardized betas (already returned) provide the ranking; ΔR² provides the aggregate \"are interactions worth investigating?\" signal.\n\n### When to Use Which\n\n| Question | Engine | Metric |\n| ------------------------------------------------ | ------------------- | -------------------------------------------------- |\n| \"Which factor explains the most variation?\" | η² (one-way ANOVA) | `getEtaSquared()` value |\n| \"What should I drill into next?\" | η² ranking | Highest η² among remaining factors |\n| \"Do any factor pairs interact?\" | Multiple regression | ΔR² > threshold (e.g., 0.05) |\n| \"Which interaction is strongest?\" | Multiple regression | Largest \\|standardized β\\| among interaction terms |\n| \"Is this interaction statistically significant?\" | Multiple regression | p-value \u003C 0.05 on interaction coefficient |\n| \"How much variation have I explained so far?\" | Cumulative η² | `useVariationTracking` running sum |\n\n**Design principle**: η² is the primary navigation metric. Regression is the supplementary \"look deeper\" engine. The analyst follows η² to drill down; the interaction heatmap uses regression to surface cross-factor patterns that η² (being a one-at-a-time metric) cannot detect.\n\n---\n\n## 2. Existing Suggestion UI Audit\n\nVariScout already contains 10+ guidance elements scattered across the PWA and (partially) the Azure app. These exist organically from different development phases and are not yet unified into a coherent \"guided investigation\" experience.\n\n### High Prominence (Always Visible)\n\n| Element | Location | What It Does | Platform |\n| ------------------------------ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------- |\n| **Boxplot \"↓ drill here\"** | `packages/charts/src/Boxplot.tsx:389` | Red text label on the highest-η² bar in the Boxplot | PWA, Azure |\n| **Filter chip contribution %** | `packages/ui/src/components/FilterBreadcrumb/FilterBreadcrumb.tsx:272–297` | Badge on each active filter showing its contribution to total variation (color-coded: ≥50% green, ≥30% amber, \u003C30% blue) | PWA, Azure |\n| **VariationBar** | `packages/ui/src/components/VariationBar/` | Horizontal bar showing cumulative explained variation | PWA, Azure |\n\n### Moderate Prominence (Visible in Funnel Panel)\n\n| Element | Location | What It Does | Platform |\n| ----------------------------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |\n| **Factor ranking list** | `apps/pwa/src/components/VariationFunnel.tsx:96` | Ranked list of factors by η², with visual bars and cumulative tracking. \"Helps users identify the optimal 1-3 filter settings that explain ~70% of variation.\" | PWA only |\n| **\"Highest impact\" label + Drill button** | `apps/pwa/src/components/VariationFunnel.tsx:635–647` | Per-factor row showing best value with a \"Drill →\" action button | PWA only |\n| **\"Worst\" label** | `apps/pwa/src/components/VariationFunnel.tsx:727–728` | Red label on the category with highest contribution to variation (>20%) | PWA only |\n| **Inline Cpk badge** | `apps/pwa/src/components/VariationFunnel.tsx:737–767` | Shows Cpk improvement potential when removing the worst category | PWA only |\n| **Combined explained summary** | `apps/pwa/src/components/VariationFunnel.tsx:267–283` | Cumulative explained variation for selected factors, tracking toward 70% target | PWA only |\n\n### Low Prominence (Contextual / On-Demand)\n\n| Element | Location | What It Does | Platform |\n| ----------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------- |\n| **InteractionGuidance** | `apps/pwa/src/components/InteractionGuidance.tsx:26` | Educational prompt shown when 2+ factors are in the drill stack. Guides to Regression Panel with \"Include interactions\" | PWA only |\n| **WhatIfSimulator** | `apps/pwa/src/components/WhatIfSimulator.tsx`, `apps/azure/src/components/WhatIfSimulator.tsx` | Scenario modeling: \"what if we removed the worst category?\" | PWA, Azure |\n| **FunnelWindow** | `apps/pwa/src/components/FunnelWindow.tsx` | Pop-out window for the Variation Funnel (opens in separate window) | PWA only |\n\n### Azure Gaps\n\nThe Azure app is missing several guidance elements that exist in the PWA:\n\n| Missing in Azure | Impact |\n| --------------------------------- | ---------------------------------------------- |\n| VariationFunnel / FunnelPanel | No factor ranking view, no cumulative tracking |\n| InteractionGuidance | No interaction awareness prompt |\n| FunnelWindow (pop-out) | No companion overview window |\n| Inline Cpk badges | No improvement potential indicators |\n| Cumulative explained target (70%) | No stopping signal |\n\nThe Azure app has the Boxplot \"↓ drill here\", FilterBreadcrumb with contribution %, VariationBar, and WhatIfSimulator — the high-prominence and lowest-prominence elements. The entire middle tier (the Funnel Panel ecosystem) is absent.\n\n### Audit Summary\n\nThe existing guidance elements are **individually well-designed** but suffer from three problems:\n\n1. **Scattered placement**: Guidance appears in the Boxplot (chart layer), FilterBreadcrumb (navigation layer), and Funnel Panel (slide-out panel). No single view shows the investigation state.\n2. **Hidden depth**: The richest guidance (factor ranking, Cpk badges, cumulative target) lives in the Funnel Panel, which requires explicit opening. First-time users never find it.\n3. **Platform inconsistency**: The PWA has 10+ elements; Azure has 4. Professional users paying from €99/month have less guidance than free PWA users.\n\n---\n\n## 3. Competitive Design Principles\n\nDistilled from the six competitor benchmarks ([Minitab](competitive/minitab-benchmark.md), [JMP](competitive/jmp-benchmark.md), [Tableau](competitive/tableau-benchmark.md), [Power BI](competitive/powerbi-benchmark.md), [SigmaXL](competitive/minor-competitors.md), [EDAScout](competitive/edascout-benchmark.md)).\n\n### Do\n\n| Principle | Evidence | Application |\n| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |\n| **Rank by statistical importance** | JMP Effect Summary ranks by LogWorth; Minitab stepwise sorts by p-value | Factor suggestions should rank by η² with the value visible (not hidden behind a label) |\n| **Make suggestions optional** | EDAScout's AI guidance was rolled back (v6→v7) because it was too aggressive; restored in v9 with instrumentation | Suggestions must be dismissible, toggleable, and never block the workflow |\n| **Integrate into the analysis flow** | Minitab's multi-vari is a separate menu item users must know to seek; Tableau filter suggestions require consulting a separate \"Ask Data\" panel | Suggestions should appear inline, in context, at the moment the analyst needs them — not in a separate mode or panel |\n| **Show the statistics, not just the recommendation** | JMP shows p-values and effect sizes alongside rankings | The η² value, not just \"drill here\", should be visible so the analyst learns why a factor is recommended |\n| **Use color and size for importance** | Power BI Key Influencers sizes bars by importance; JMP Effect Summary uses bar length | Visual weight (color saturation, size, position) should encode statistical importance |\n\n### Don't\n\n| Anti-Pattern | Evidence | Avoidance |\n| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |\n| **Require model-first analysis** | JMP Fit Model requires specifying all terms before seeing results; Minitab DOE requires pre-defined experimental structure | VariScout's suggestions should emerge from the data as-loaded, not require the analyst to configure a model first |\n| **Separate seeing from acting** | Tableau and Power BI filter panels are detached from the charts they affect; the analyst must mentally link sidebar selections to chart changes | Factor suggestions should appear on or adjacent to the chart where the analyst will act (the Boxplot), not in a separate panel |\n| **Use AI mediation** | EDAScout's \"Socratic Analyst\" chatbot added a conversational layer between the data and the analyst; the v6→v7 rollback shows this created more friction than value | VariScout's guidance should be statistical and transparent, not AI-generated prose |\n| **Present all options equally** | Tableau and Power BI present all filter values as equal checkboxes; no visual hierarchy of importance | Factor suggestions should create clear visual hierarchy — the recommended next factor should be visually distinct from alternatives |\n| **Hide the investigation state** | Minitab's Session Window logs analysis history as text but doesn't visualize investigation progress; no competitor shows cumulative explained variation | The analyst should always know where they are in the investigation (how much variation is explained, how many factors explored) |\n\n---\n\n## 4. Enhancement vs. New Design\n\n### Enhancement: Unify and Surface Existing Guidance\n\nThese elements already exist and work correctly. The design task is making them more discoverable and consistent across platforms:\n\n| Element | Current State | Design Need |\n| -------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------- |\n| Boxplot \"↓ drill here\" | Works but is a single red label; no context about why | Add η² value, make it a tappable suggestion chip |\n| Filter chip contribution % | Color-coded badge, well-implemented | Consider making it more prominent or adding a \"cumulative\" view |\n| VariationFunnel ranking | Rich but hidden in slide-out panel | Surface key information (next factor suggestion, cumulative %) in the main view |\n| InteractionGuidance | Only triggers at 2+ factors; text-only | Integrate with the interaction heatmap (Phase 2) for visual backing |\n| WhatIfSimulator | Present in both PWA and Azure | No changes needed for Phase 1 |\n\n### New Design: Investigation Overview Components\n\nThese don't exist yet and require design work:\n\n| Component | Purpose | Phase |\n| ------------------------------------ | -------------------------------------------------------------------------------------- | ------- |\n| **Factor Suggestion chip/banner** | Inline prompt near the Boxplot: \"Try Store next — explains 45% of remaining variation\" | Phase 1 |\n| **Investigation progress indicator** | Persistent bar showing cumulative explained variation and suggesting when to stop | Phase 1 |\n| **Interaction heatmap** | Compact matrix showing factor-pair interaction strength (ΔR² or \\|β\\|) | Phase 2 |\n| **Investigation Mindmap** | Companion view showing factors as nodes, drill path as trail, interactions as edges | Phase 3 |\n| **Investigation Narrative** | Presentation mode transforming the mindmap into a stakeholder-ready visual story | Phase 3 |\n\n---\n\n## 5. Design Questions\n\nThese questions should be resolved during the UI/UX design phase. They are ordered by implementation phase.\n\n### Phase 1: Factor Suggestion\n\n1. **Placement**: Where does the \"suggested next factor\" prompt appear? Options: (a) on the Boxplot directly (extending the existing \"↓ drill here\"), (b) as a banner above the Four Lenses, (c) as a floating chip that follows the analyst's focus. The competitive principle says \"integrate into the analysis flow\" — but the Boxplot label is small and the banner competes with chart space.\n\n2. **Progressive disclosure**: Should the suggestion appear immediately on data load, or only after the first drill? First-time users need a \"start here\" nudge; returning analysts may find it patronizing. A possible rule: show on first visit per dataset, hide after first interaction.\n\n3. **Pedagogy toggle**: Should Trainer Tina be able to disable suggestions for training exercises? If so, where does the toggle live — settings panel, a toolbar button, or a per-session toggle? The competitive principle says \"make suggestions optional.\"\n\n4. **Funnel surfacing**: The richest guidance lives in the Funnel Panel. Should key metrics (next factor, cumulative %, stopping signal) be surfaced in the main view even when the Funnel is closed? If so, how much dashboard space can they occupy?\n\n5. **Azure parity**: The Azure app is missing the entire Funnel Panel ecosystem. Should Phase 1 include porting the Funnel Panel to Azure, or is a lighter-weight \"suggested next factor\" chip sufficient for the first iteration?\n\n### Phase 2: Interaction Heatmap\n\n6. **Trigger**: When does the interaction scan run? Options: (a) on data load (pre-compute all pairs), (b) on demand (analyst clicks \"check interactions\"), (c) after the first drill (when the analyst has demonstrated interest in multi-factor analysis). Option (a) adds latency on load for datasets with many factors; option (c) is the most contextually appropriate but may feel late.\n\n7. **Integration with InteractionGuidance**: The existing `InteractionGuidance` component shows a text prompt when 2+ factors are drilled. Should the interaction heatmap replace this prompt, extend it with visual data, or coexist as separate elements?\n\n8. **Heatmap placement**: The heatmap is a small matrix (~4×4 cells). Where does it sit? Options: (a) below the Boxplot, (b) in a collapsible section of the Funnel Panel, (c) as a tooltip/popover triggered by an \"interactions\" button. The competitive principle says \"don't separate seeing from acting\" — a popover risks being ignored.\n\n### Phase 3: Investigation Overview\n\n9. **Mindmap window model**: The Investigation Mindmap (see [pattern evaluation](patterns/investigation-mindmap.md)) opens as a companion view. Should it be: (a) a pop-out window (like the existing FunnelWindow), (b) a split-pane alongside the main dashboard, (c) a full-screen mode that replaces the dashboard temporarily? Each has different implications for state synchronization and mobile support.\n\n10. **Narrative export format**: The Investigation Narrative (see [pattern evaluation](patterns/investigation-narrative.md)) targets stakeholder presentations. Should it export as: (a) a static PNG/SVG image, (b) an interactive HTML page, (c) a PDF report, (d) copy-to-clipboard for pasting into slides? The Azure audience (Olivia's team) likely wants PowerPoint-compatible output.\n\n---\n\n## 6. Demo Dataset Validation\n\nThe guided investigation features need datasets with 3+ categorical factors and meaningful interaction effects to demonstrate effectively. The following datasets from `packages/data/src/samples/` are candidates:\n\n| Dataset | Factors | Outcome | η² Spread | Interaction Potential | Status |\n| ------------------ | --------------------------------- | ------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------ |\n| **Pizza Delivery** | Store (3), Time_Slot (3), Day (7) | Delivery_Time_min | Store dominates (South has higher mean+variance); Time_Slot moderate (Dinner rush); Day weak | Store × Time_Slot plausible (South may be worse during Dinner rush due to driver experience) | **Primary demo dataset** |\n| **Oven Zones** | Zone, Shift, (others) | Temperature | Likely zone-dominated | Zone × Shift plausible | Good candidate |\n| **Coffee** | Various process factors | Cup quality metrics | Well-distributed | Unknown interaction strength | Good candidate |\n| **Avocado** | Region, variety, season | Quality/ripeness | Regional dominance likely | Region × Season likely (climate interaction) | Good candidate |\n\n### Validation Needed\n\nThe interaction effects in the sample datasets have **not yet been empirically validated**. The data generation functions in `packages/data/src/samples/*.ts` use additive models (base mean + factor adjustments) — interactions exist only if the generation code explicitly creates them (e.g., Store South × Dinner having a super-additive penalty). Before the design phase, each candidate dataset should be tested:\n\n1. Run `calculateMultipleRegression` with `includeInteractions: true` on each dataset\n2. Check if any interaction terms have significant coefficients (p \u003C 0.05)\n3. Compute ΔR² to confirm interaction effect size is large enough to demonstrate the heatmap\n4. If no dataset has meaningful interactions, modify one data generation function to include an explicit interaction effect (e.g., make Store South's Dinner rush penalty 12 minutes instead of the standard 5)\n\nThis validation is a prerequisite for the Investigation Flow Map ([Concept 2](investigation-flow-map.md)) to include realistic interaction examples.\n\n---\n\n## Related Documents\n\n- [Investigation Flow Map](investigation-flow-map.md) — Step-by-step scenario walkthrough using the Pizza dataset\n- [Investigation Mindmap](patterns/investigation-mindmap.md) — Pattern evaluation for the companion visualization\n- [Investigation Narrative](patterns/investigation-narrative.md) — Pattern evaluation for presentation mode\n- [Factor Suggestion](patterns/factor-suggestion.md) — Phase 1 pattern evaluation\n- [Interaction Heatmap](patterns/interaction-heatmap.md) — Phase 2 pattern evaluation\n- [Factor Map](patterns/factor-map.md) — Related Phase 3 pattern (deferred)\n- [EDAScout Benchmark](competitive/edascout-benchmark.md) — AI guidance rollback arc\n- [Minitab Benchmark](competitive/minitab-benchmark.md) — Menu-driven factor analysis\n- [JMP Benchmark](competitive/jmp-benchmark.md) — Effect Summary and model-first paradigm\n- [Tableau Benchmark](competitive/tableau-benchmark.md) — Sidebar filter anti-pattern\n- [Power BI Benchmark](competitive/powerbi-benchmark.md) — Key Influencers visual", + "src/content/docs/01-vision/evaluations/design-brief-guided-investigation.md", + "a14cb2b993bd3fb0", + { "html": 5394, "metadata": 5395 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"design-brief-guided-investigation\">Design Brief: Guided Investigation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#design-brief-guided-investigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Brief: Guided Investigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Historical document\u003C/strong> — this design brief led to the Investigation Mindmap (Phases A-D).\nSee \u003Ca href=\"./design-spec-investigation-mindmap.md\">design-spec-investigation-mindmap.md\u003C/a> for final spec.\u003C/p>\n\u003C/blockquote>\n\u003Cblockquote>\n\u003Cp>Synthesis document bridging competitive intelligence, existing codebase capabilities, and design questions for the Factor Suggestion (Phase 1) and Interaction Heatmap (Phase 2) features.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"1-statistical-methodology\">1. Statistical Methodology\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#1-statistical-methodology\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Statistical Methodology”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The guided investigation features build on two distinct statistical engines already present in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>. This section resolves which engine serves which purpose.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"main-effects-eta-squared-drill-down-ranking\">Main Effects: Eta-Squared (Drill-Down Ranking)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#main-effects-eta-squared-drill-down-ranking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Main Effects: Eta-Squared (Drill-Down Ranking)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The drill-down workflow uses one-way ANOVA eta-squared (η² = SS_between / SS_total) to rank factors by explanatory power. This is the correct metric for the “which factor next?” question because it quantifies how much of the outcome’s total variation is attributable to group membership.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>Implementation\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Single-factor η²\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getEtaSquared(data, factor, outcome)\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/stats.ts:177\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Per-category contribution\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code> → \u003Ccode dir=\"auto\">filterChipData\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/hooks/src/useVariationTracking.ts\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cumulative η² tracking\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code> → running sum\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/hooks/src/useVariationTracking.ts\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Factor ranking by η²\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">VariationFunnel\u003C/code> → \u003Ccode dir=\"auto\">optimalFactors\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/VariationFunnel.tsx\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key property\u003C/strong>: η² values are computed per-factor against the current filtered subset, so they update dynamically as the analyst drills down. This is the foundation for factor suggestion — the highest η² among remaining (unfiltered) factors is the suggested next step.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interactions-multiple-regression--glm\">Interactions: Multiple Regression / GLM\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interactions-multiple-regression--glm\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interactions: Multiple Regression / GLM”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Interaction detection uses the multiple regression engine, which already supports categorical predictors (dummy-encoded) and two-way interaction terms.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>Implementation\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Interaction term fitting\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">calculateMultipleRegression(data, y, [x1, x2], { includeInteractions: true })\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/stats.ts:1886\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Categorical × categorical\u003C/td>\u003Ctd>Dummy encoding with interaction columns\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/stats.ts:1644–1682\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Standardized coefficients\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">CoefficientResult.standardizedBeta\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/types.ts:598\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Significance testing\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">CoefficientResult.tStatistic\u003C/code>, \u003Ccode dir=\"auto\">CoefficientResult.pValue\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/types.ts:593–596\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Interaction term type flag\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">RegressionTerm.type: 'interaction'\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/types.ts:575\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Interaction effect size (ΔR²)\u003C/td>\u003Ctd>Compare R² of model with and without interaction terms\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>\u003Cstrong>Needs thin helper\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>The ΔR² helper\u003C/strong>: To quantify how much additional variation an interaction explains beyond the main effects, run \u003Ccode dir=\"auto\">calculateMultipleRegression\u003C/code> twice — once with \u003Ccode dir=\"auto\">includeInteractions: false\u003C/code>, once with \u003Ccode dir=\"auto\">includeInteractions: true\u003C/code> — and compute ΔR² = R²_full − R²_main. This is a ~10-line utility function, not a new statistical engine. The individual interaction term standardized betas (already returned) provide the ranking; ΔR² provides the aggregate “are interactions worth investigating?” signal.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"when-to-use-which\">When to Use Which\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-use-which\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Use Which”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Question\u003C/th>\u003Cth>Engine\u003C/th>\u003Cth>Metric\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Which factor explains the most variation?“\u003C/td>\u003Ctd>η² (one-way ANOVA)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getEtaSquared()\u003C/code> value\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”What should I drill into next?“\u003C/td>\u003Ctd>η² ranking\u003C/td>\u003Ctd>Highest η² among remaining factors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Do any factor pairs interact?”\u003C/td>\u003Ctd>Multiple regression\u003C/td>\u003Ctd>ΔR² > threshold (e.g., 0.05)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>“Which interaction is strongest?”\u003C/td>\u003Ctd>Multiple regression\u003C/td>\u003Ctd>Largest |standardized β| among interaction terms\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Is this interaction statistically significant?”\u003C/td>\u003Ctd>Multiple regression\u003C/td>\u003Ctd>p-value < 0.05 on interaction coefficient\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”How much variation have I explained so far?”\u003C/td>\u003Ctd>Cumulative η²\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code> running sum\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Design principle\u003C/strong>: η² is the primary navigation metric. Regression is the supplementary “look deeper” engine. The analyst follows η² to drill down; the interaction heatmap uses regression to surface cross-factor patterns that η² (being a one-at-a-time metric) cannot detect.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"2-existing-suggestion-ui-audit\">2. Existing Suggestion UI Audit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#2-existing-suggestion-ui-audit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Existing Suggestion UI Audit”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout already contains 10+ guidance elements scattered across the PWA and (partially) the Azure app. These exist organically from different development phases and are not yet unified into a coherent “guided investigation” experience.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"high-prominence-always-visible\">High Prominence (Always Visible)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#high-prominence-always-visible\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “High Prominence (Always Visible)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>What It Does\u003C/th>\u003Cth>Platform\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Boxplot ”↓ drill here”\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/charts/src/Boxplot.tsx:389\u003C/code>\u003C/td>\u003Ctd>Red text label on the highest-η² bar in the Boxplot\u003C/td>\u003Ctd>PWA, Azure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Filter chip contribution %\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/FilterBreadcrumb/FilterBreadcrumb.tsx:272–297\u003C/code>\u003C/td>\u003Ctd>Badge on each active filter showing its contribution to total variation (color-coded: ≥50% green, ≥30% amber, <30% blue)\u003C/td>\u003Ctd>PWA, Azure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>VariationBar\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/VariationBar/\u003C/code>\u003C/td>\u003Ctd>Horizontal bar showing cumulative explained variation\u003C/td>\u003Ctd>PWA, Azure\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"moderate-prominence-visible-in-funnel-panel\">Moderate Prominence (Visible in Funnel Panel)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#moderate-prominence-visible-in-funnel-panel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Moderate Prominence (Visible in Funnel Panel)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>What It Does\u003C/th>\u003Cth>Platform\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Factor ranking list\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/VariationFunnel.tsx:96\u003C/code>\u003C/td>\u003Ctd>Ranked list of factors by η², with visual bars and cumulative tracking. “Helps users identify the optimal 1-3 filter settings that explain ~70% of variation.”\u003C/td>\u003Ctd>PWA only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>”Highest impact” label + Drill button\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/VariationFunnel.tsx:635–647\u003C/code>\u003C/td>\u003Ctd>Per-factor row showing best value with a “Drill →” action button\u003C/td>\u003Ctd>PWA only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>”Worst” label\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/VariationFunnel.tsx:727–728\u003C/code>\u003C/td>\u003Ctd>Red label on the category with highest contribution to variation (>20%)\u003C/td>\u003Ctd>PWA only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Inline Cpk badge\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/VariationFunnel.tsx:737–767\u003C/code>\u003C/td>\u003Ctd>Shows Cpk improvement potential when removing the worst category\u003C/td>\u003Ctd>PWA only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Combined explained summary\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/VariationFunnel.tsx:267–283\u003C/code>\u003C/td>\u003Ctd>Cumulative explained variation for selected factors, tracking toward 70% target\u003C/td>\u003Ctd>PWA only\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"low-prominence-contextual--on-demand\">Low Prominence (Contextual / On-Demand)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#low-prominence-contextual--on-demand\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Low Prominence (Contextual / On-Demand)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>What It Does\u003C/th>\u003Cth>Platform\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>InteractionGuidance\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/InteractionGuidance.tsx:26\u003C/code>\u003C/td>\u003Ctd>Educational prompt shown when 2+ factors are in the drill stack. Guides to Regression Panel with “Include interactions”\u003C/td>\u003Ctd>PWA only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>WhatIfSimulator\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/WhatIfSimulator.tsx\u003C/code>, \u003Ccode dir=\"auto\">apps/azure/src/components/WhatIfSimulator.tsx\u003C/code>\u003C/td>\u003Ctd>Scenario modeling: “what if we removed the worst category?”\u003C/td>\u003Ctd>PWA, Azure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>FunnelWindow\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/FunnelWindow.tsx\u003C/code>\u003C/td>\u003Ctd>Pop-out window for the Variation Funnel (opens in separate window)\u003C/td>\u003Ctd>PWA only\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-gaps\">Azure Gaps\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-gaps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Gaps”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure app is missing several guidance elements that exist in the PWA:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Missing in Azure\u003C/th>\u003Cth>Impact\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>VariationFunnel / FunnelPanel\u003C/td>\u003Ctd>No factor ranking view, no cumulative tracking\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>InteractionGuidance\u003C/td>\u003Ctd>No interaction awareness prompt\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>FunnelWindow (pop-out)\u003C/td>\u003Ctd>No companion overview window\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Inline Cpk badges\u003C/td>\u003Ctd>No improvement potential indicators\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cumulative explained target (70%)\u003C/td>\u003Ctd>No stopping signal\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The Azure app has the Boxplot ”↓ drill here”, FilterBreadcrumb with contribution %, VariationBar, and WhatIfSimulator — the high-prominence and lowest-prominence elements. The entire middle tier (the Funnel Panel ecosystem) is absent.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"audit-summary\">Audit Summary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#audit-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Audit Summary”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The existing guidance elements are \u003Cstrong>individually well-designed\u003C/strong> but suffer from three problems:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Scattered placement\u003C/strong>: Guidance appears in the Boxplot (chart layer), FilterBreadcrumb (navigation layer), and Funnel Panel (slide-out panel). No single view shows the investigation state.\u003C/li>\n\u003Cli>\u003Cstrong>Hidden depth\u003C/strong>: The richest guidance (factor ranking, Cpk badges, cumulative target) lives in the Funnel Panel, which requires explicit opening. First-time users never find it.\u003C/li>\n\u003Cli>\u003Cstrong>Platform inconsistency\u003C/strong>: The PWA has 10+ elements; Azure has 4. Professional users paying from €99/month have less guidance than free PWA users.\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"3-competitive-design-principles\">3. Competitive Design Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#3-competitive-design-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Competitive Design Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Distilled from the six competitor benchmarks (\u003Ca href=\"competitive/minitab-benchmark.md\">Minitab\u003C/a>, \u003Ca href=\"competitive/jmp-benchmark.md\">JMP\u003C/a>, \u003Ca href=\"competitive/tableau-benchmark.md\">Tableau\u003C/a>, \u003Ca href=\"competitive/powerbi-benchmark.md\">Power BI\u003C/a>, \u003Ca href=\"competitive/minor-competitors.md\">SigmaXL\u003C/a>, \u003Ca href=\"competitive/edascout-benchmark.md\">EDAScout\u003C/a>).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"do\">Do\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#do\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Do”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Principle\u003C/th>\u003Cth>Evidence\u003C/th>\u003Cth>Application\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Rank by statistical importance\u003C/strong>\u003C/td>\u003Ctd>JMP Effect Summary ranks by LogWorth; Minitab stepwise sorts by p-value\u003C/td>\u003Ctd>Factor suggestions should rank by η² with the value visible (not hidden behind a label)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Make suggestions optional\u003C/strong>\u003C/td>\u003Ctd>EDAScout’s AI guidance was rolled back (v6→v7) because it was too aggressive; restored in v9 with instrumentation\u003C/td>\u003Ctd>Suggestions must be dismissible, toggleable, and never block the workflow\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Integrate into the analysis flow\u003C/strong>\u003C/td>\u003Ctd>Minitab’s multi-vari is a separate menu item users must know to seek; Tableau filter suggestions require consulting a separate “Ask Data” panel\u003C/td>\u003Ctd>Suggestions should appear inline, in context, at the moment the analyst needs them — not in a separate mode or panel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Show the statistics, not just the recommendation\u003C/strong>\u003C/td>\u003Ctd>JMP shows p-values and effect sizes alongside rankings\u003C/td>\u003Ctd>The η² value, not just “drill here”, should be visible so the analyst learns why a factor is recommended\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Use color and size for importance\u003C/strong>\u003C/td>\u003Ctd>Power BI Key Influencers sizes bars by importance; JMP Effect Summary uses bar length\u003C/td>\u003Ctd>Visual weight (color saturation, size, position) should encode statistical importance\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"dont\">Don’t\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#dont\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Don’t”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Anti-Pattern\u003C/th>\u003Cth>Evidence\u003C/th>\u003Cth>Avoidance\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Require model-first analysis\u003C/strong>\u003C/td>\u003Ctd>JMP Fit Model requires specifying all terms before seeing results; Minitab DOE requires pre-defined experimental structure\u003C/td>\u003Ctd>VariScout’s suggestions should emerge from the data as-loaded, not require the analyst to configure a model first\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Separate seeing from acting\u003C/strong>\u003C/td>\u003Ctd>Tableau and Power BI filter panels are detached from the charts they affect; the analyst must mentally link sidebar selections to chart changes\u003C/td>\u003Ctd>Factor suggestions should appear on or adjacent to the chart where the analyst will act (the Boxplot), not in a separate panel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Use AI mediation\u003C/strong>\u003C/td>\u003Ctd>EDAScout’s “Socratic Analyst” chatbot added a conversational layer between the data and the analyst; the v6→v7 rollback shows this created more friction than value\u003C/td>\u003Ctd>VariScout’s guidance should be statistical and transparent, not AI-generated prose\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Present all options equally\u003C/strong>\u003C/td>\u003Ctd>Tableau and Power BI present all filter values as equal checkboxes; no visual hierarchy of importance\u003C/td>\u003Ctd>Factor suggestions should create clear visual hierarchy — the recommended next factor should be visually distinct from alternatives\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Hide the investigation state\u003C/strong>\u003C/td>\u003Ctd>Minitab’s Session Window logs analysis history as text but doesn’t visualize investigation progress; no competitor shows cumulative explained variation\u003C/td>\u003Ctd>The analyst should always know where they are in the investigation (how much variation is explained, how many factors explored)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-enhancement-vs-new-design\">4. Enhancement vs. New Design\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-enhancement-vs-new-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Enhancement vs. New Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"enhancement-unify-and-surface-existing-guidance\">Enhancement: Unify and Surface Existing Guidance\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#enhancement-unify-and-surface-existing-guidance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Enhancement: Unify and Surface Existing Guidance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These elements already exist and work correctly. The design task is making them more discoverable and consistent across platforms:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Current State\u003C/th>\u003Cth>Design Need\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Boxplot ”↓ drill here”\u003C/td>\u003Ctd>Works but is a single red label; no context about why\u003C/td>\u003Ctd>Add η² value, make it a tappable suggestion chip\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filter chip contribution %\u003C/td>\u003Ctd>Color-coded badge, well-implemented\u003C/td>\u003Ctd>Consider making it more prominent or adding a “cumulative” view\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>VariationFunnel ranking\u003C/td>\u003Ctd>Rich but hidden in slide-out panel\u003C/td>\u003Ctd>Surface key information (next factor suggestion, cumulative %) in the main view\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>InteractionGuidance\u003C/td>\u003Ctd>Only triggers at 2+ factors; text-only\u003C/td>\u003Ctd>Integrate with the interaction heatmap (Phase 2) for visual backing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>WhatIfSimulator\u003C/td>\u003Ctd>Present in both PWA and Azure\u003C/td>\u003Ctd>No changes needed for Phase 1\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"new-design-investigation-overview-components\">New Design: Investigation Overview Components\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#new-design-investigation-overview-components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “New Design: Investigation Overview Components”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These don’t exist yet and require design work:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Phase\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Factor Suggestion chip/banner\u003C/strong>\u003C/td>\u003Ctd>Inline prompt near the Boxplot: “Try Store next — explains 45% of remaining variation”\u003C/td>\u003Ctd>Phase 1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Investigation progress indicator\u003C/strong>\u003C/td>\u003Ctd>Persistent bar showing cumulative explained variation and suggesting when to stop\u003C/td>\u003Ctd>Phase 1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Interaction heatmap\u003C/strong>\u003C/td>\u003Ctd>Compact matrix showing factor-pair interaction strength (ΔR² or |β|)\u003C/td>\u003Ctd>Phase 2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Investigation Mindmap\u003C/strong>\u003C/td>\u003Ctd>Companion view showing factors as nodes, drill path as trail, interactions as edges\u003C/td>\u003Ctd>Phase 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Investigation Narrative\u003C/strong>\u003C/td>\u003Ctd>Presentation mode transforming the mindmap into a stakeholder-ready visual story\u003C/td>\u003Ctd>Phase 3\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"5-design-questions\">5. Design Questions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#5-design-questions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Design Questions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These questions should be resolved during the UI/UX design phase. They are ordered by implementation phase.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-1-factor-suggestion\">Phase 1: Factor Suggestion\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-1-factor-suggestion\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 1: Factor Suggestion”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Placement\u003C/strong>: Where does the “suggested next factor” prompt appear? Options: (a) on the Boxplot directly (extending the existing ”↓ drill here”), (b) as a banner above the Four Lenses, (c) as a floating chip that follows the analyst’s focus. The competitive principle says “integrate into the analysis flow” — but the Boxplot label is small and the banner competes with chart space.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Progressive disclosure\u003C/strong>: Should the suggestion appear immediately on data load, or only after the first drill? First-time users need a “start here” nudge; returning analysts may find it patronizing. A possible rule: show on first visit per dataset, hide after first interaction.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Pedagogy toggle\u003C/strong>: Should Trainer Tina be able to disable suggestions for training exercises? If so, where does the toggle live — settings panel, a toolbar button, or a per-session toggle? The competitive principle says “make suggestions optional.”\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Funnel surfacing\u003C/strong>: The richest guidance lives in the Funnel Panel. Should key metrics (next factor, cumulative %, stopping signal) be surfaced in the main view even when the Funnel is closed? If so, how much dashboard space can they occupy?\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Azure parity\u003C/strong>: The Azure app is missing the entire Funnel Panel ecosystem. Should Phase 1 include porting the Funnel Panel to Azure, or is a lighter-weight “suggested next factor” chip sufficient for the first iteration?\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-2-interaction-heatmap\">Phase 2: Interaction Heatmap\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-interaction-heatmap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2: Interaction Heatmap”\u003C/span>\u003C/a>\u003C/div>\n\u003Col start=\"6\">\n\u003Cli>\n\u003Cp>\u003Cstrong>Trigger\u003C/strong>: When does the interaction scan run? Options: (a) on data load (pre-compute all pairs), (b) on demand (analyst clicks “check interactions”), (c) after the first drill (when the analyst has demonstrated interest in multi-factor analysis). Option (a) adds latency on load for datasets with many factors; option (c) is the most contextually appropriate but may feel late.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Integration with InteractionGuidance\u003C/strong>: The existing \u003Ccode dir=\"auto\">InteractionGuidance\u003C/code> component shows a text prompt when 2+ factors are drilled. Should the interaction heatmap replace this prompt, extend it with visual data, or coexist as separate elements?\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Heatmap placement\u003C/strong>: The heatmap is a small matrix (~4×4 cells). Where does it sit? Options: (a) below the Boxplot, (b) in a collapsible section of the Funnel Panel, (c) as a tooltip/popover triggered by an “interactions” button. The competitive principle says “don’t separate seeing from acting” — a popover risks being ignored.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-3-investigation-overview\">Phase 3: Investigation Overview\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3-investigation-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3: Investigation Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Col start=\"9\">\n\u003Cli>\n\u003Cp>\u003Cstrong>Mindmap window model\u003C/strong>: The Investigation Mindmap (see \u003Ca href=\"patterns/investigation-mindmap.md\">pattern evaluation\u003C/a>) opens as a companion view. Should it be: (a) a pop-out window (like the existing FunnelWindow), (b) a split-pane alongside the main dashboard, (c) a full-screen mode that replaces the dashboard temporarily? Each has different implications for state synchronization and mobile support.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Narrative export format\u003C/strong>: The Investigation Narrative (see \u003Ca href=\"patterns/investigation-narrative.md\">pattern evaluation\u003C/a>) targets stakeholder presentations. Should it export as: (a) a static PNG/SVG image, (b) an interactive HTML page, (c) a PDF report, (d) copy-to-clipboard for pasting into slides? The Azure audience (Olivia’s team) likely wants PowerPoint-compatible output.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"6-demo-dataset-validation\">6. Demo Dataset Validation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#6-demo-dataset-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Demo Dataset Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The guided investigation features need datasets with 3+ categorical factors and meaningful interaction effects to demonstrate effectively. The following datasets from \u003Ccode dir=\"auto\">packages/data/src/samples/\u003C/code> are candidates:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dataset\u003C/th>\u003Cth>Factors\u003C/th>\u003Cth>Outcome\u003C/th>\u003Cth>η² Spread\u003C/th>\u003Cth>Interaction Potential\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Pizza Delivery\u003C/strong>\u003C/td>\u003Ctd>Store (3), Time_Slot (3), Day (7)\u003C/td>\u003Ctd>Delivery_Time_min\u003C/td>\u003Ctd>Store dominates (South has higher mean+variance); Time_Slot moderate (Dinner rush); Day weak\u003C/td>\u003Ctd>Store × Time_Slot plausible (South may be worse during Dinner rush due to driver experience)\u003C/td>\u003Ctd>\u003Cstrong>Primary demo dataset\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Oven Zones\u003C/strong>\u003C/td>\u003Ctd>Zone, Shift, (others)\u003C/td>\u003Ctd>Temperature\u003C/td>\u003Ctd>Likely zone-dominated\u003C/td>\u003Ctd>Zone × Shift plausible\u003C/td>\u003Ctd>Good candidate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Coffee\u003C/strong>\u003C/td>\u003Ctd>Various process factors\u003C/td>\u003Ctd>Cup quality metrics\u003C/td>\u003Ctd>Well-distributed\u003C/td>\u003Ctd>Unknown interaction strength\u003C/td>\u003Ctd>Good candidate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Avocado\u003C/strong>\u003C/td>\u003Ctd>Region, variety, season\u003C/td>\u003Ctd>Quality/ripeness\u003C/td>\u003Ctd>Regional dominance likely\u003C/td>\u003Ctd>Region × Season likely (climate interaction)\u003C/td>\u003Ctd>Good candidate\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"validation-needed\">Validation Needed\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#validation-needed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Validation Needed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The interaction effects in the sample datasets have \u003Cstrong>not yet been empirically validated\u003C/strong>. The data generation functions in \u003Ccode dir=\"auto\">packages/data/src/samples/*.ts\u003C/code> use additive models (base mean + factor adjustments) — interactions exist only if the generation code explicitly creates them (e.g., Store South × Dinner having a super-additive penalty). Before the design phase, each candidate dataset should be tested:\u003C/p>\n\u003Col>\n\u003Cli>Run \u003Ccode dir=\"auto\">calculateMultipleRegression\u003C/code> with \u003Ccode dir=\"auto\">includeInteractions: true\u003C/code> on each dataset\u003C/li>\n\u003Cli>Check if any interaction terms have significant coefficients (p < 0.05)\u003C/li>\n\u003Cli>Compute ΔR² to confirm interaction effect size is large enough to demonstrate the heatmap\u003C/li>\n\u003Cli>If no dataset has meaningful interactions, modify one data generation function to include an explicit interaction effect (e.g., make Store South’s Dinner rush penalty 12 minutes instead of the standard 5)\u003C/li>\n\u003C/ol>\n\u003Cp>This validation is a prerequisite for the Investigation Flow Map (\u003Ca href=\"investigation-flow-map.md\">Concept 2\u003C/a>) to include realistic interaction examples.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documents\">Related Documents\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documents\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documents”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"investigation-flow-map.md\">Investigation Flow Map\u003C/a> — Step-by-step scenario walkthrough using the Pizza dataset\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/investigation-mindmap.md\">Investigation Mindmap\u003C/a> — Pattern evaluation for the companion visualization\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/investigation-narrative.md\">Investigation Narrative\u003C/a> — Pattern evaluation for presentation mode\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/factor-suggestion.md\">Factor Suggestion\u003C/a> — Phase 1 pattern evaluation\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/interaction-heatmap.md\">Interaction Heatmap\u003C/a> — Phase 2 pattern evaluation\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/factor-map.md\">Factor Map\u003C/a> — Related Phase 3 pattern (deferred)\u003C/li>\n\u003Cli>\u003Ca href=\"competitive/edascout-benchmark.md\">EDAScout Benchmark\u003C/a> — AI guidance rollback arc\u003C/li>\n\u003Cli>\u003Ca href=\"competitive/minitab-benchmark.md\">Minitab Benchmark\u003C/a> — Menu-driven factor analysis\u003C/li>\n\u003Cli>\u003Ca href=\"competitive/jmp-benchmark.md\">JMP Benchmark\u003C/a> — Effect Summary and model-first paradigm\u003C/li>\n\u003Cli>\u003Ca href=\"competitive/tableau-benchmark.md\">Tableau Benchmark\u003C/a> — Sidebar filter anti-pattern\u003C/li>\n\u003Cli>\u003Ca href=\"competitive/powerbi-benchmark.md\">Power BI Benchmark\u003C/a> — Key Influencers visual\u003C/li>\n\u003C/ul>", + { + "headings": 5396, + "localImagePaths": 5466, + "remoteImagePaths": 5467, + "frontmatter": 5468, + "imagePaths": 5469 + }, + [ + 5397, 5399, 5402, 5405, 5408, 5411, 5414, 5417, 5420, 5423, 5426, 5429, 5432, 5435, 5438, 5441, + 5444, 5447, 5450, 5453, 5456, 5459, 5462, 5465 + ], + { "depth": 30, "slug": 5398, "text": 5386 }, + "design-brief-guided-investigation", + { "depth": 33, "slug": 5400, "text": 5401 }, + "1-statistical-methodology", + "1. Statistical Methodology", + { "depth": 79, "slug": 5403, "text": 5404 }, + "main-effects-eta-squared-drill-down-ranking", + "Main Effects: Eta-Squared (Drill-Down Ranking)", + { "depth": 79, "slug": 5406, "text": 5407 }, + "interactions-multiple-regression--glm", + "Interactions: Multiple Regression / GLM", + { "depth": 79, "slug": 5409, "text": 5410 }, + "when-to-use-which", + "When to Use Which", + { "depth": 33, "slug": 5412, "text": 5413 }, + "2-existing-suggestion-ui-audit", + "2. Existing Suggestion UI Audit", + { "depth": 79, "slug": 5415, "text": 5416 }, + "high-prominence-always-visible", + "High Prominence (Always Visible)", + { "depth": 79, "slug": 5418, "text": 5419 }, + "moderate-prominence-visible-in-funnel-panel", + "Moderate Prominence (Visible in Funnel Panel)", + { "depth": 79, "slug": 5421, "text": 5422 }, + "low-prominence-contextual--on-demand", + "Low Prominence (Contextual / On-Demand)", + { "depth": 79, "slug": 5424, "text": 5425 }, + "azure-gaps", + "Azure Gaps", + { "depth": 79, "slug": 5427, "text": 5428 }, + "audit-summary", + "Audit Summary", + { "depth": 33, "slug": 5430, "text": 5431 }, + "3-competitive-design-principles", + "3. Competitive Design Principles", + { "depth": 79, "slug": 5433, "text": 5434 }, + "do", + "Do", + { "depth": 79, "slug": 5436, "text": 5437 }, + "dont", + "Don’t", + { "depth": 33, "slug": 5439, "text": 5440 }, + "4-enhancement-vs-new-design", + "4. Enhancement vs. New Design", + { "depth": 79, "slug": 5442, "text": 5443 }, + "enhancement-unify-and-surface-existing-guidance", + "Enhancement: Unify and Surface Existing Guidance", + { "depth": 79, "slug": 5445, "text": 5446 }, + "new-design-investigation-overview-components", + "New Design: Investigation Overview Components", + { "depth": 33, "slug": 5448, "text": 5449 }, + "5-design-questions", + "5. Design Questions", + { "depth": 79, "slug": 5451, "text": 5452 }, + "phase-1-factor-suggestion", + "Phase 1: Factor Suggestion", + { "depth": 79, "slug": 5454, "text": 5455 }, + "phase-2-interaction-heatmap", + "Phase 2: Interaction Heatmap", + { "depth": 79, "slug": 5457, "text": 5458 }, + "phase-3-investigation-overview", + "Phase 3: Investigation Overview", + { "depth": 33, "slug": 5460, "text": 5461 }, + "6-demo-dataset-validation", + "6. Demo Dataset Validation", + { "depth": 79, "slug": 5463, "text": 5464 }, + "validation-needed", + "Validation Needed", + { "depth": 33, "slug": 4342, "text": 4343 }, + [], + [], + { "title": 5386 }, + [], + "01-vision/evaluations/design-spec-investigation-mindmap", + { "id": 5470, "data": 5472, "body": 5477, "filePath": 5478, "digest": 5479, "rendered": 5480 }, + { + "title": 5473, + "editUrl": 16, + "head": 5474, + "template": 18, + "sidebar": 5475, + "pagefind": 16, + "draft": 20 + }, + "Design Spec: Investigation Mindmap", + [], + { "hidden": 20, "attrs": 5476 }, + {}, + "# Design Spec: Investigation Mindmap\n\n> Authoritative design specification for the Mindmap-first investigation UX. Consolidates four concept documents into a three-layer architecture that replaces the Funnel Panel ecosystem with one spatial view.\n\n---\n\n## 1. Three-Layer Architecture\n\nThe investigation UX consolidates into three layers with clear boundaries. No layer depends on the others being visible — each works independently but they compose into a coherent whole.\n\n| Layer | Visibility | Components | Role |\n| ----------------------- | -------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------- |\n| **Chart Layer** | Always visible | Boxplot \"↓ drill here\", Pareto ranking, I-Chart patterns, Stats Panel | Primary workspace — the analyst reads data and acts on it |\n| **Navigation Layer** | Always visible | FilterBreadcrumb (contribution %), VariationBar (cumulative %) | Filter state — the analyst sees where they are in the investigation |\n| **Investigation Layer** | On demand | Investigation Mindmap (slide-out panel or pop-out window) | Strategic overview — the analyst plans next steps and reviews progress |\n\n### Layer Boundaries\n\n- **Chart Layer** owns the data visualization. Charts accept data via props and render the current filtered view. The Boxplot's \"↓ drill here\" label (`Boxplot.tsx:389`) is the Chart Layer's only guidance element — it points to the highest-η² bar.\n- **Navigation Layer** owns filter state display. FilterBreadcrumb shows active filters with contribution % badges (color-coded: ≥50% green, ≥30% amber, \u003C30% blue). VariationBar shows cumulative explained variation as a horizontal bar. These components exist today and require no changes.\n- **Investigation Layer** owns the strategic overview. The Investigation Mindmap replaces the Funnel Panel as the on-demand companion view. It shows all factors spatially, the drill trail, and interaction relationships — information that the Chart and Navigation layers cannot convey because they show one factor at a time.\n\nThe three-layer architecture reduces the current PWA from 20+ guidance surfaces to three clearly scoped layers. The analyst knows where to look: charts for data, breadcrumbs for filter state, mindmap for investigation strategy.\n\n---\n\n## 2. Investigation Mindmap — Three Modes\n\nThe Mindmap has three switchable modes that share the same node layout but show different information. A mode toggle (segmented control) at the top of the mindmap switches between modes. Nodes stay fixed during transitions; only edges, annotations, and layout direction change.\n\n### Mode Progressive Disclosure\n\nModes unlock progressively as the investigation progresses. The segmented control always shows all three modes, but unavailable modes are muted with a tooltip explaining the requirement.\n\n| Mode | Available When | Disabled Reason Tooltip |\n| --------------- | ---------------------------------------------------- | ------------------------------------------------- |\n| **Drilldown** | Always | (never disabled) |\n| **Interaction** | 2+ factors in the dataset AND n >= 5 after filtering | \"Requires 2+ factors with at least 5 data points\" |\n| **Narrative** | 1+ drill applied (at least one filter active) | \"Apply a filter to start building the timeline\" |\n\nThis is a mode-level progressive disclosure: the analyst cannot switch to Interaction Mode until the data supports pairwise regression, and cannot switch to Narrative Mode until there is at least one drill step to narrate. The gating prevents empty-state confusion.\n\n### Drilldown Mode\n\nThe default mode. Shows the factor landscape and investigation path.\n\n- **Factor nodes**: All categorical factors appear as nodes. Node size is proportional to η² (computed by `getEtaSquared()` in `stats.ts:177` against the current filtered subset). The factor explaining the most remaining variation is the largest node.\n- **Node color encodes filter state**:\n - **Active filter** (e.g., Store = South): Solid fill, bright color. The filtered value appears as a label below the node.\n - **Available** (not yet filtered): Outlined, neutral fill. Hovering shows the η² value.\n - **Exhausted** (filtered, negligible remaining η²): Dimmed/grayed. Signals diminishing returns.\n- **Drill trail**: A highlighted path connects nodes in drill order (Start → Store → Time_Slot). The path is the visual record of the investigation sequence.\n- **Suggested-next node**: The factor with the highest η² among remaining (unfiltered) factors has a pulsing glow or \"suggested\" badge. This is the spatial equivalent of the Boxplot's \"↓ drill here\" label.\n- **Click node → filter dropdown**: Clicking a node opens a popover listing that factor's category values with their contribution percentages. Selecting a value applies the filter. The main dashboard updates simultaneously.\n- **Cumulative progress footer**: A persistent bar at the bottom shows cumulative explained variation (e.g., \"58% of variation explained\") with a 70% target marker. Source: `useVariationTracking` running sum.\n\n### Interaction Mode\n\nSame factor nodes in the same positions. Edges appear showing interaction relationships.\n\n- **Edges between nodes**: Thickness proportional to interaction strength (ΔR² — the difference in R² between a model with and without the interaction term, computed by running `calculateMultipleRegression()` at `stats.ts:1886` twice).\n- **Edge color encodes significance**: Bright/saturated for p \u003C 0.05, muted/translucent for p \u003C 0.10, absent for p ≥ 0.10.\n- **Hover edge → tooltip**: Shows ΔR², standardized β, p-value, and a plain-language description (e.g., \"Store and Time_Slot interact — the Dinner rush effect is stronger at Store South\").\n- **Click edge → multi-select**: Selects both connected factors for combined analysis in the Regression Panel.\n- **No edges visible** is itself informative: \"Your factors don't interact significantly — the sequential drill-down captured the main effects.\"\n- **Computation**: Interaction scan runs on demand when the analyst switches to Interaction Mode (not on data load). For N factors, this is N×(N−1)/2 regression pairs. For the typical 3–5 factor dataset, this is 3–10 pairs — fast enough for interactive use.\n\n### Narrative Mode\n\nThe spatial layout reorganizes into a linear timeline for stakeholder communication.\n\n- **Timeline layout**: Nodes appear sequentially (horizontal on desktop, vertical on mobile) in drill order. Each node is a \"step\" in the investigation story.\n- **Step annotations**: Each step shows key findings from that drill point:\n - Factor name and filtered value (e.g., \"Step 1: Store = South\")\n - Variation explained (η² from `useVariationTracking`)\n - Key statistic change (mean shift, Cpk change from before/after `calculateStats`)\n - Cumulative explained variation at that point\n- **Interaction cross-connections**: If significant interactions were detected, they appear as cross-links between timeline steps (e.g., a dashed arc between Store and Time_Slot steps).\n- **Cumulative progress**: A running bar along the timeline shows explained variation building at each step.\n- **Conclusion panel**: At the end of the timeline, a summary: \"Two factors explain 60% of delivery time variation.\"\n- **Export**: PNG/SVG image export. The analyst can paste the image into slides or reports. This is the MVP export format.\n- **Annotations**: The analyst can optionally add text notes to each step (e.g., \"Store South uses contract drivers\"). Annotations are stored locally and included in exports.\n\n### Mode Switch Interaction\n\n| From | To | Transition |\n| ----------------------- | ---------------------------------------------------------- | ------------------------------------------------------------ |\n| Drilldown → Interaction | Nodes stay fixed; edges fade in | Analyst wants to check factor-pair relationships |\n| Drilldown → Narrative | Nodes reorganize into timeline; trail becomes the sequence | Analyst is done investigating, wants to communicate findings |\n| Interaction → Drilldown | Edges fade out; nodes regain drill-state coloring | Analyst returns to investigation after checking interactions |\n| Interaction → Narrative | Edges fade, nodes reorganize into timeline | Analyst wants to include interaction findings in the story |\n| Narrative → Drilldown | Timeline collapses back to spatial layout | Analyst wants to resume investigating |\n\n---\n\n## 3. What the Mindmap Replaces\n\nThe Funnel Panel ecosystem (`VariationFunnel.tsx` — 965 lines, `FunnelPanel.tsx`, `FunnelWindow.tsx`, `InteractionGuidance.tsx`) currently provides investigation guidance through dense, everything-at-once presentation. The Mindmap replaces this with progressive disclosure.\n\n### Element-by-Element Replacement Map\n\n| Current Funnel Element | Location | Mindmap Equivalent | How It Improves |\n| --------------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------- |\n| **Factor ranking list** (η² bars, sorted) | `VariationFunnel.tsx:96–123` | Node size encodes η² ranking spatially | Spatial layout is scannable at a glance; no scrolling through a list |\n| **Factor selection checkboxes** | `VariationFunnel.tsx:126–129, 288–298` | Click node → filter dropdown | Direct manipulation replaces checkbox+apply two-step |\n| **\"Highest impact\" label + Drill button** | `VariationFunnel.tsx:635–647` | Suggested-next node (pulsing glow) | Spatial emphasis is more visible than a text label in a list |\n| **\"Worst\" red label** | `VariationFunnel.tsx:727–728` | Red-tinted category in click-popover; contribution % visible | On-demand detail replaces always-visible label |\n| **Inline Cpk badge** (improvement projection) | `VariationFunnel.tsx:737–767` | Removed — moves to WhatIfSimulator (separate page) | Cpk projection is a \"what if\" scenario, not an investigation guidance element |\n| **Cumulative explained summary** | `VariationFunnel.tsx:267–283` | Cumulative progress footer in all three modes | Always visible at bottom of mindmap, not buried in a list header |\n| **Category-level μ/σ/% density table** | `VariationFunnel.tsx:183–189` (expanded rows) | Available on hover/click in Drilldown Mode popover | Progressive disclosure: shown when requested, not always |\n| **WhatIfSimulator** (embedded) | `VariationFunnel.tsx:25–28, 139–143` | Moves to separate page (see Section 4) | Separated mental modes: investigation ≠ scenario modeling |\n| **InteractionGuidance** (text prompt) | `InteractionGuidance.tsx:26` | Interaction Mode replaces text with visual evidence | Edges show _whether_ interactions exist, not just _that they might_ |\n| **Pop-out window sync** | `FunnelWindow.tsx` (localStorage + postMessage) | Reused for Mindmap pop-out window | Same bidirectional sync pattern, new content |\n| **Slide-out panel shell** | `FunnelPanel.tsx` (backdrop, escape-to-close) | Reused for Mindmap slide-out panel | Same panel infrastructure, new content |\n\n### What Gets Explicitly Removed\n\nThese Funnel elements are not replicated in the Mindmap because they contribute to the density problem:\n\n| Removed Element | Why |\n| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Dual checkboxes** (select factor + select category) | The Funnel required selecting which factors to include, then expanding to select categories. The Mindmap shows all factors by default (nodes) and uses click-to-drill for categories. No two-step selection needed. |\n| **Inline Cpk badges** on category rows | Cpk projection per-category is a scenario modeling feature (what if we removed this category?). This belongs in the WhatIfSimulator, not in the investigation overview. |\n| **Category-level μ/σ/% always-visible density** | In the Funnel, expanding a factor showed a table of every category with mean, std dev, and % of data. This is useful but dense. The Mindmap's click-popover shows category contribution % (the actionable metric) on demand. Full stats remain available in the Stats Panel. |\n| **\"Standardize to best\" presets** | These WhatIfSimulator presets generated from category stats move with the simulator to its own page. |\n| **Excluded-category tracking** | The Funnel allowed checking/unchecking categories to see projected stats. This is WhatIfSimulator territory. |\n\n### Net Effect\n\nThe Funnel Panel presents ~15 interactive elements per factor row (checkbox, expand button, category checkboxes, drill button, Cpk badge, worst label, μ/σ/% per category). For 3 factors with 3–7 categories each, this is **60–150 interactive elements** in a 320px-wide panel.\n\nThe Mindmap presents 3–5 factor nodes with hover tooltips and click-popovers. The default view has **3–5 interactive elements** plus the mode toggle and progress footer. Detail is available on demand, not by default.\n\n---\n\n## 4. WhatIfSimulator as Separate Page\n\nThe WhatIfSimulator (`WhatIfSimulator.tsx` — currently embedded in the Funnel Panel and available standalone in Azure) moves to its own page/view, accessible from the Settings menu or a dedicated route.\n\n### Rationale\n\nInvestigation and scenario modeling are distinct mental modes:\n\n- **Investigation** (Mindmap): \"What is causing the variation?\" — exploratory, analytical, drilling into data to identify root causes. The analyst is _reading_ the process.\n- **Scenario modeling** (WhatIfSimulator): \"What if we fixed it?\" — projective, hypothetical, adjusting parameters to estimate improvement. The analyst is _imagining_ a different process.\n\nEmbedding the WhatIfSimulator inside the Funnel Panel conflated these modes. The analyst would drill into a factor, see the \"worst\" category, then immediately see a Cpk projection for removing it — before finishing the investigation. The separate page enforces a natural workflow: investigate first, then model improvements.\n\n### Access Pattern\n\n- **Route**: `/whatif` or equivalent in-app navigation\n- **Entry points**: (1) Settings/tools menu, (2) \"Model improvements\" button at the end of a Narrative Mode timeline, (3) direct link from FilterBreadcrumb context menu\n- **Data flow**: The WhatIfSimulator receives the current process statistics (mean, stdDev, Cpk) and spec limits from the DataContext. It does not need the investigation state — it operates on the filtered data as-is.\n- **Presets**: The \"Exclude worst category\" and \"Standardize to best\" presets (currently generated in `VariationFunnel.tsx:192–265`) move to the WhatIfSimulator page. They are generated from the current filtered data, not from the mindmap state.\n\n---\n\n## 5. Statistical Foundation\n\nThe Mindmap's three modes are powered by two statistical engines already present in `@variscout/core`, plus one new infrastructure requirement.\n\n### Existing: η² for Node Sizing and Drill Ranking\n\n`getEtaSquared(data, factor, outcome)` at `stats.ts:177` computes one-way ANOVA eta-squared (η² = SS_between / SS_total). This is the primary metric for:\n\n- **Node size**: Larger η² → larger node. The visual hierarchy directly encodes statistical importance.\n- **Suggested-next**: The factor with the highest η² among unfiltered factors gets the pulsing suggestion.\n- **Cumulative tracking**: `useVariationTracking` (in `packages/hooks/src/useVariationTracking.ts`) maintains the running cumulative η² that powers the progress footer.\n\nη² values are computed per-factor against the current filtered subset, so they update dynamically as the analyst drills. This is the existing behavior — no changes needed.\n\n### Existing: Regression for Interaction Edges\n\n`calculateMultipleRegression(data, outcome, [factor1, factor2], { includeInteractions: true })` at `stats.ts:1886` computes interaction effects. The returned `CoefficientResult` objects include `standardizedBeta`, `tStatistic`, and `pValue` for each interaction term.\n\nFor Interaction Mode edges:\n\n- **Edge thickness**: ΔR² = R²_full − R²_main (run `calculateMultipleRegression` twice — once with `includeInteractions: false`, once with `true`). This is a ~10-line utility function (see [Design Brief §1](design-brief-guided-investigation.md#1-statistical-methodology) for specification).\n- **Edge color**: Based on the interaction term's p-value from the full model.\n- **Tooltip content**: ΔR², largest |standardized β| among interaction terms, p-value.\n\n### New Infrastructure: Drill-Path Recording\n\nAll three Mindmap modes require a recorded sequence of drill steps. This does not exist today — the current filter stack (`useFilterNavigation`) tracks _what_ is filtered but not the _order_ or _statistics at each step_.\n\nThe drill-path recording system needs to capture, for each drill step:\n\n| Field | Source | Used By |\n| ------------------------- | ----------------------------------------- | --------------------------------------------------------------- |\n| Factor name | Filter action | All three modes |\n| Filtered value(s) | Filter action | Drilldown Mode (node labels), Narrative Mode (step annotations) |\n| η² at time of drill | `getEtaSquared()` on pre-drill data | Narrative Mode (step annotations) |\n| Cumulative η² after drill | `useVariationTracking` | Narrative Mode (progress bar) |\n| Mean before/after | `calculateStats()` on pre/post-drill data | Narrative Mode (statistic change) |\n| Cpk before/after | `calculateStats()` on pre/post-drill data | Narrative Mode (capability change) |\n| Timestamp | System clock | Narrative Mode (ordering) |\n\nThis recording can be built as a new hook (`useDrillPath`) or as an extension to `useFilterNavigation`. The data is ephemeral (session-only) and lightweight (~100 bytes per drill step). Implementation detail is deferred to the coding phase.\n\n---\n\n## 6. Platform Strategy — PWA and Azure Only\n\nThe Investigation Mindmap is a **PWA + Azure feature only**. The Excel Add-in has a fundamentally different interaction model (native Excel slicers) and doesn't use the progressive drill-down workflow that the Mindmap visualizes.\n\n### PWA\n\n- **Panel model**: Slide-out panel from the right side, occupying the same slot as the current Funnel Panel. Reuses the `FunnelPanel.tsx` shell (backdrop, escape-to-close, outside-click-to-close).\n- **Pop-out window**: Available as an option. Reuses the `FunnelWindow.tsx` bidirectional sync pattern (localStorage + postMessage). The analyst can drag the Mindmap to a second monitor while the main dashboard stays on the primary screen.\n- **Modes available**: Drilldown Mode (full), Interaction Mode (full), Narrative Mode (view only — PNG export limited to screenshot).\n- **Trigger**: Labelled \"Investigation\" button (Network icon + text) in the header. Replaces the previous unlabelled icon toggle.\n- **First-drill prompt**: A one-time callout (`InvestigationPrompt`) appears when the user applies their first filter, pointing them to the Investigation panel. Dismissed per session via sessionStorage.\n- **VariationBar gateway**: The VariationBar accepts an optional `onClick` prop, allowing it to serve as an additional entry point to the Investigation panel.\n- **Export**: Copy-to-clipboard, PNG download, and SVG download available in all three modes (Drilldown, Interactions, Narrative).\n\n### Azure\n\n- **Panel model**: Same slide-out panel as PWA.\n- **Split-pane option**: On desktop (viewport > 1280px), the Mindmap can open as a persistent side panel alongside the dashboard. This is appropriate for Azure's desktop-oriented professional workflow.\n- **Pop-out window**: Same as PWA.\n- **Modes available**: All three modes with full functionality.\n- **Trigger**: Labelled \"Investigation\" button (Network icon + text), same as PWA.\n- **First-drill prompt**: Same `InvestigationPrompt` callout as PWA (same default color scheme).\n- **VariationBar gateway**: Same clickable VariationBar as PWA.\n- **Export**: Copy-to-clipboard, PNG download, and SVG download available in all three modes. SVG export is Azure-only. Annotations are saved with the project (OneDrive sync).\n\n### Excel Add-in — Explicitly Excluded\n\nThe Excel Add-in uses native Excel slicers for filtering. There is no progressive drill-down workflow, no filter breadcrumbs, no cumulative η² tracking. The Mindmap concept does not apply to the slicer interaction model. The Excel Add-in's investigation workflow is: set slicer values → read chart → adjust slicers. This is fundamentally different from the PWA/Azure drill-down-and-refine workflow.\n\n### Export by Platform\n\nExport (copy-to-clipboard, PNG, SVG) is available in all three modes, not only Narrative.\n\n| Capability | PWA (free) | Azure (paid) |\n| ---------------------- | ---------------------------------------- | ---------------------------------------- |\n| Export modes | All (Drilldown, Interactions, Narrative) | All (Drilldown, Interactions, Narrative) |\n| Copy to clipboard | Yes | Yes |\n| PNG export | Yes (high-resolution render) | Yes (high-resolution render) |\n| SVG export | No | Yes |\n| Annotations | Session-only (not saved) | Saved with project (OneDrive) |\n| Template customization | No | Future (post-MVP) |\n\n---\n\n## 7. Progressive Disclosure Design\n\nThe Mindmap's core design principle is progressive disclosure — the answer to the Funnel Panel's density problem. The Funnel showed everything simultaneously; the Mindmap shows information in layers activated by user intent.\n\n### Disclosure Levels\n\n| Level | Trigger | What Appears | Cognitive Load |\n| --------------------- | --------------- | ----------------------------------------------------------------------------------- | --------------------------------------- |\n| **Default view** | Panel opens | Factor nodes + drill trail + progress footer | Low — 3–5 nodes, one trail, one bar |\n| **Hover** | Mouse over node | Factor name, η² value, current filter value (if active) | Low — single tooltip |\n| **Click** | Click on node | Popover with category values, contribution % per category, \"drill\" action per value | Moderate — one factor's detail |\n| **Mode switch** | Toggle control | Drilldown ↔ Interaction ↔ Narrative (gated — see below) | Moderate — changes the information lens |\n| **Interaction hover** | Mouse over edge | ΔR², p-value, plain-language description | Moderate — single interaction detail |\n\n**Mode-level gating**: Modes themselves are gated by progressive disclosure. Interactions mode requires 2+ factors AND n >= 5 after filtering. Narrative mode requires at least 1 drill applied. Disabled modes appear muted in the segmented control with a tooltip explaining what is needed to unlock them. This prevents the analyst from encountering empty or meaningless views.\n\n### What Is Never Shown Simultaneously\n\nThe following information was shown simultaneously in the Funnel Panel and is now gated behind progressive disclosure:\n\n- All category statistics (μ, σ, %) for all factors — only shown for one factor at a time, on click\n- Dual checkboxes (factor-level + category-level) — eliminated entirely\n- Inline Cpk badges per category — moved to WhatIfSimulator\n- \"Worst\" labels on every category row — replaced by contribution % color-coding in click-popover\n- WhatIfSimulator presets — moved to separate page\n\n### Visual Hierarchy\n\nIn Drilldown Mode, the visual hierarchy is:\n\n1. **Node size** — the dominant signal. Largest node = most variation explained. Scannable in \u003C1 second.\n2. **Node color/fill** — active (filled) vs. available (outlined) vs. exhausted (dimmed). Filter state at a glance.\n3. **Drill trail** — the path through the nodes. Investigation history visible as a highlighted line.\n4. **Suggested-next pulse** — draws attention to the recommended next factor. Subtle but discoverable.\n5. **Progress footer** — cumulative %. Always visible but not competing with the spatial layout.\n\nIn Interaction Mode, the hierarchy shifts:\n\n1. **Edge thickness** — the dominant signal. Thickest edge = strongest interaction.\n2. **Edge color** — significance encoding. Bright = statistically significant.\n3. **Node size** — secondary context (η² for main effects).\n\nIn Narrative Mode, the hierarchy is temporal:\n\n1. **Timeline position** — left-to-right sequence of drill steps.\n2. **Step annotations** — findings at each step.\n3. **Cumulative progress bar** — building total along the timeline.\n\n---\n\n## 8. Demo Walkthrough — Pizza Delivery with Mindmap UX\n\nThis walkthrough uses the Pizza Delivery dataset (`packages/data/src/samples/pizza.ts`) — 252 observations, 3 factors (Store, Time_Slot, Day), outcome Delivery_Time_min. It revises the [Investigation Flow Map](investigation-flow-map.md) walkthrough to show the Mindmap-first UX.\n\n### Step 1: Data Loaded\n\n**Chart Layer**: I-Chart shows delivery times with control limits. Boxplot shows Store groups — Store South's box is wider and higher. \"↓ drill here\" appears on Store South. Pareto ranks out-of-spec frequency by Store.\n\n**Navigation Layer**: No active filters. VariationBar shows 0% explained.\n\n**Investigation Layer (if opened)**: Three factor nodes — Store (large, ~40% η²), Time_Slot (medium, ~20% η²), Day (small, ~3% η²). Store node pulses as suggested-next. No drill trail. Progress footer: \"0% explained.\"\n\n_Compared to Flow Map Step 1_: The Mindmap immediately shows the factor landscape — three nodes with visual hierarchy. The analyst sees that Store dominates before touching anything. Previously, this required opening the hidden Funnel Panel.\n\n### Step 2: Analyst Drills Store South\n\nThe analyst clicks the Store node in the Mindmap → popover shows: North (15%), Central (12%), South (45%). Analyst clicks \"South\" → filter applied.\n\n**Chart Layer**: I-Chart filters to Store South. Boxplot now shows Time_Slot groups. \"↓ drill here\" on Dinner.\n\n**Navigation Layer**: FilterBreadcrumb shows \"Store: South 45%\". VariationBar shows ~40%.\n\n**Investigation Layer**: Store node fills solid (active). Trail: Start → Store. Time_Slot node is now the largest remaining (highest η² on filtered data). Time_Slot pulses as suggested-next. Day remains small. Progress footer: \"40% explained.\"\n\n_Compared to Flow Map Step 2_: The analyst can drill from the Mindmap or the Boxplot — both paths are valid. The Mindmap shows Time_Slot as the clear next candidate without requiring the analyst to open the Funnel Panel.\n\n### Step 3: Analyst Drills Time_Slot Dinner\n\nThe analyst clicks the Time_Slot node → popover shows: Lunch (8%), Dinner (25%), Late Night (5%). Analyst clicks \"Dinner.\"\n\n**Chart Layer**: I-Chart filters to Store South + Dinner. Boxplot shows Day groups (roughly even).\n\n**Navigation Layer**: Two chips: \"Store: South 45%\" and \"Time_Slot: Dinner 25%\". VariationBar shows ~58%.\n\n**Investigation Layer**: Store and Time_Slot nodes filled. Trail: Start → Store → Time_Slot. Day node is small and dimmed (low η², ~3%). No suggestion pulse (remaining factors are weak). Progress footer: \"58% explained.\"\n\n_Compared to Flow Map Step 3_: Previously, the analyst would open the Funnel Panel to see the investigation state. Now the Mindmap shows the same information spatially — two filled nodes, one dimmed, trail visible.\n\n### Step 4: Analyst Checks Interactions\n\nCurious whether Store and Time_Slot interact, the analyst toggles to Interaction Mode.\n\n**Investigation Layer**: Same three nodes. An edge appears between Store and Time_Slot — medium thickness (moderate ΔR²), bright color (p \u003C 0.05). No significant edges for Store–Day or Time_Slot–Day. Hovering the edge: \"Store × Time_Slot: ΔR² = 0.05, p = 0.02. The Dinner rush effect is stronger at Store South.\"\n\n_Compared to Flow Map Steps 4 + 6_: Previously, the analyst saw a text-only InteractionGuidance prompt, then had to navigate to the Regression Panel, configure it, and read coefficient tables. Now the interaction is visible as a single edge — one glance instead of a multi-step workflow.\n\n### Step 5: Analyst Decides to Stop\n\nBack in Drilldown Mode, the analyst sees: 58% explained, Day is dimmed (3% η²), no strong suggestion. The progress footer shows the 70% target marker is ahead but the remaining factors are weak.\n\nThe analyst decides the investigation has found the key drivers (Store South + Dinner rush) and toggles to Narrative Mode.\n\n### Step 6: Narrative Mode — Communication\n\n**Investigation Layer**: Timeline appears:\n\n- **Step 1**: Store = South — \"Explains 40% of variation. Mean delivery time: 35 min vs. 28 min overall.\"\n- **Step 2**: Time_Slot = Dinner — \"Explains 25% of remaining variation. Dinner adds +7 min average.\"\n- **Interaction note**: Dashed arc between steps — \"Store × Time_Slot interaction (p = 0.02). Dinner rush at Store South is 2× worse than other stores.\"\n- **Conclusion**: \"Two factors explain 58% of delivery time variation. Day has no significant effect.\"\n\nThe analyst adds an annotation to Step 1: \"Store South uses contract drivers with less route knowledge.\" Exports as PNG for the team meeting.\n\n_Compared to Flow Map Step 7_: Previously, the investigation ended without ceremony — no summary, no exportable artifact. Now the Narrative Mode creates a presentation-ready visual story.\n\n---\n\n## 9. Competitive Positioning\n\nNo competitor offers a spatial investigation overview. The Investigation Mindmap is a genuine differentiator — and critically, it is a **consolidation** (fewer surfaces, less cognitive load) rather than a feature addition.\n\n### What Competitors Offer\n\n| Competitor | Factor Exploration | Investigation Overview | Presentation Output |\n| ------------ | ---------------------------------------------------------- | -------------------------------------------- | ------------------------------------- |\n| **Minitab** | Menu-driven ANOVA, stepwise regression. No visual ranking. | Session Window (text log). No spatial view. | Manual PowerPoint. |\n| **JMP** | Effect Summary ranks by LogWorth. Model-first. | Journal (command replay). No spatial view. | JMP Journal export. |\n| **Tableau** | Sidebar filters, equal-weight checkboxes. | Dashboard shows current state, not journey. | Story Points (manual slide sequence). |\n| **Power BI** | Slicer paradigm. Key Influencers auto-ranks. | Decomposition Tree (enforced top-down tree). | Report export. |\n| **EDAScout** | Smart Cards, AI chatbot. | Chat transcript (verbose, not visual). | No export. |\n\nSee [competitor benchmarks](competitive/) for detailed assessments.\n\n### VariScout's Unique Position\n\nThe Mindmap combines three capabilities no competitor has together:\n\n1. **Spatial factor overview** — factors as nodes sized by statistical importance (η²), not a flat list or tree.\n2. **Investigation state tracking** — the drill trail shows where the analyst has been, suggested-next shows where to go.\n3. **Interaction overlay** — edges show factor-pair relationships without requiring a separate analysis step.\n\nThis is achieved through consolidation. The current Funnel Panel has more UI elements than most competitors' entire factor analysis workflow — but those elements are hidden, dense, and PWA-only. The Mindmap surfaces the same statistical insights through a simpler, spatial interface available on both PWA and Azure.\n\n---\n\n## 10. Design Questions for UI/UX Phase\n\nThese questions must be resolved during the UI/UX design phase before implementation begins.\n\n### Node Layout\n\n1. **Layout algorithm**: Should nodes use a radial layout (factors arranged in a circle around a center \"start\" node), a hierarchical layout (top-to-bottom by η² ranking), or force-directed-lite (spring forces with fixed positions after initial layout)? Radial is simplest to implement (static SVG positioning). Hierarchical matches the ranking mental model. Force-directed is most flexible but requires a physics engine.\n\n2. **Node count limit**: With 3–5 factors, any layout works. At 8+ factors (possible in Azure with complex datasets), does the spatial layout become cluttered? Should there be a threshold where the layout switches to a compact list fallback?\n\n### Mode Switch\n\n3. **Discoverability**: How does the analyst discover that Interaction Mode and Narrative Mode exist? Options: (a) segmented control always visible at the top, (b) icon toggle that reveals modes on hover, (c) contextual prompt (\"You've drilled 2 factors — check for interactions?\"). The segmented control is most discoverable but takes space.\n\n### Click-Popover\n\n4. **Category count limit**: When a factor has 7+ categories (e.g., Day of week), does the click-popover become too long? Should it scroll, paginate, or show only the top N categories by contribution? The Pizza dataset's \"Day\" factor has 7 levels — a good test case.\n\n### Mobile\n\n5. **Mobile adaptation**: On mobile viewports (\u003C768px), should the Mindmap open as a full-screen overlay (replacing the dashboard temporarily) or remain a slide-out panel? The current FunnelPanel uses a 320px slide-out which leaves no space for chart interaction. Full-screen mode gives the Mindmap room but breaks the \"mindmap beside charts\" spatial memory.\n\n### Export\n\n6. **Narrative export MVP**: Is PNG-only sufficient for the first release? SVG would allow lossless scaling but is less familiar to users. Should copy-to-clipboard (as image) be prioritized over file-save for the \"paste into slides\" workflow?\n\n---\n\n## 11. Design Thinking History\n\nThis spec consolidates four concept documents written during the design exploration phase. Each contributed specific ideas that are now incorporated into the Mindmap-first architecture.\n\n| Document | What It Contributed | Status |\n| -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [Design Brief](design-brief-guided-investigation.md) | Statistical methodology (η² for drill ranking, regression for interactions, ΔR² helper specification). UI audit of 10+ existing guidance elements. Competitive design principles (rank by importance, make suggestions optional, integrate into flow). 10 design questions. | Historical — statistical methodology and competitive principles are canonical references. Design questions revised into Section 10. |\n| [Investigation Flow Map](investigation-flow-map.md) | 7-step Pizza Delivery walkthrough documenting existing guidance at each step and identifying gaps. Guidance coverage table mapping existing elements to Phase 1/2/3 features. | Historical — the \"before\" state. The Section 8 walkthrough is the \"after\" state showing the Mindmap-first UX at each step. |\n| [Investigation Mindmap](patterns/investigation-mindmap.md) | Two-mode concept (Drilldown + Interaction). Node sizing by η², color by filter state. Suggested-next pulsing. Click-to-filter. Pop-out window model. Competitive landscape (no competitor has spatial investigation overview). Persona impact assessment. | **Elevated to primary** — the two-mode concept is expanded to three modes (adding Narrative). The Investigation Mindmap pattern evaluation is the conceptual ancestor of this spec. |\n| [Investigation Narrative](patterns/investigation-narrative.md) | Timeline concept with step annotations and cumulative progress. Export for stakeholder presentations. Persona impact (strongly positive for Olivia, Tina). Platform fit (Azure primary, PWA limited). | **Absorbed as Mindmap's third mode** — the Narrative becomes a mode within the Mindmap rather than a separate component. This simplifies the architecture (one component, three views) and leverages the shared node layout. |\n\nThe four documents are kept in `docs/01-vision/evaluations/` as historical design thinking. They should not be used as implementation references — this spec is the authoritative source for the Mindmap UX.\n\n---\n\n## 12. Implementation Phasing\n\nThe Mindmap ships mode-by-mode. Each phase is self-contained and shippable; each builds on the previous phase's infrastructure.\n\n### Phase A: Infrastructure + Drilldown Mode\n\nShips first. Replaces the Funnel Panel with a spatial investigation view.\n\n**New infrastructure:**\n\n| Component | Scope | Estimate |\n| --------------------- | ------------------------------------------------------------------------------------------------------------- | -------------- |\n| `useDrillPath` hook | Records drill steps with before/after stats (factor, filtered value, η², cumulative η², mean, Cpk, timestamp) | ~100 lines |\n| Mindmap SVG component | Static radial or hierarchical layout of factor nodes | ~300–500 lines |\n\n**Drilldown Mode features:**\n\n- **Node rendering**: Size proportional to η² (via `getEtaSquared()`), color by filter state (active/available/exhausted), factor labels\n- **Drill trail**: Highlighted path through nodes in drill order (Start → Store → Time_Slot)\n- **Suggested-next**: Pulsing glow on the highest-η² remaining node\n- **Click-popover**: Category values with contribution %, drill action per value\n- **Cumulative progress footer**: Running η² bar with 70% target marker\n\n**Reuses existing infrastructure:**\n\n- `FunnelPanel.tsx` shell (slide-out, backdrop, escape-to-close) → `MindmapPanel.tsx`\n- `FunnelWindow.tsx` sync pattern (localStorage + postMessage) → `MindmapWindow.tsx`\n- `useVariationTracking` (η² data, cumulative tracking)\n- `getEtaSquared()` (node sizing)\n\n**Replaces:** Funnel icon in the header opens the Mindmap instead of the Funnel Panel. The Funnel Panel remains in the codebase until the Mindmap is validated, then is removed.\n\n### Phase B: Interaction Mode\n\nAdds edge rendering to the existing node layout. Requires Phase A's nodes and SVG component.\n\n**New infrastructure:**\n\n| Component | Scope | Estimate |\n| --------------------------------- | -------------------------------------------------------------------------------------------------- | --------- |\n| `getInteractionStrength()` helper | Utility in `@variscout/core`: ΔR² = R²_full − R²_main (runs `calculateMultipleRegression()` twice) | ~10 lines |\n\n**Interaction Mode features:**\n\n- **Edge rendering**: SVG paths between factor nodes, thickness proportional to ΔR², color by p-value (bright for p \u003C 0.05, muted for p \u003C 0.10, absent for p ≥ 0.10)\n- **Edge tooltips**: ΔR², standardized β, p-value, plain-language description\n- **Mode toggle**: Segmented control at top of Mindmap (Drilldown / Interaction)\n\n**Reuses:**\n\n- `calculateMultipleRegression()` with `includeInteractions: true/false` (existing in `stats.ts:1886`)\n- Phase A's node layout, SVG component, and panel shell\n\n### Phase C: Narrative Mode + WhatIfSimulator Separation\n\nAdds timeline layout and export. Requires Phase A's drill trail data and Phase B's edge data for interaction cross-connections.\n\n**New infrastructure:**\n\n| Component | Scope |\n| ------------------------------- | ----------------------------------------------------------------------- |\n| Timeline layout | Reorganize nodes into horizontal (desktop) / vertical (mobile) sequence |\n| Step annotations | η², mean shift, Cpk change per step from `useDrillPath` recorded data |\n| Interaction cross-connections | Dashed arcs between timeline steps from Phase B edge data |\n| Conclusion panel | Summary text generated from drill-path statistics |\n| PNG export | Canvas/SVG-to-PNG rendering for stakeholder presentations |\n| WhatIfSimulator standalone page | New route `/whatif`, presets migrated from `VariationFunnel.tsx` |\n\n**Mode toggle expands** to three segments (Drilldown / Interaction / Narrative).\n\n### Phase D: Polish + Azure Enhancements\n\nPlatform-specific refinements. No new modes.\n\n- **Azure split-pane option**: Persistent side panel alongside dashboard on viewport > 1280px\n- **Annotations**: Text input per timeline step (Azure: saved to OneDrive with project; PWA: session-only)\n- **SVG export**: Azure only (lossless scaling for team presentations)\n- **\"Model improvements\" button**: At end of Narrative timeline → links to WhatIfSimulator at `/whatif`\n\n### Phase Dependencies\n\n```\nPhase A (Drilldown Mode)\n └─→ Phase B (Interaction Mode) — needs A's nodes + SVG component\n └─→ Phase C (Narrative Mode) — needs A's drill trail + B's edges\n └─→ Phase D (Polish) — needs all three modes complete\n```\n\n### What This Phasing Subsumes\n\nThe original evaluations index proposed a four-phase sequence (Factor Suggestion → Interaction Heatmap → Investigation Mindmap → Factor Map). The Mindmap-first architecture consolidates this:\n\n- **Factor Suggestion** (old Phase 1) is subsumed by the suggested-next node in Drilldown Mode (Phase A). The pulsing glow on the highest-η² node provides the same guidance without a separate feature.\n- **Interaction Heatmap** (old Phase 2) is subsumed by Interaction Mode edges (Phase B). Visual edges between nodes replace the standalone heatmap component.\n- **Factor Map** (old Phase 4) is no longer needed. The Mindmap _is_ a lighter-weight Factor Map with three focused modes instead of one dense visualization.\n\nThe Mindmap consolidates rather than adding surfaces.\n\n---\n\n## Related Documents\n\n- [Design Brief](design-brief-guided-investigation.md) — Statistical methodology, UI audit, competitive principles\n- [Investigation Flow Map](investigation-flow-map.md) — 7-step walkthrough (pre-Mindmap UX)\n- [Investigation Mindmap](patterns/investigation-mindmap.md) — Original two-mode concept evaluation\n- [Investigation Narrative](patterns/investigation-narrative.md) — Original timeline/export concept evaluation\n- [Evaluations Index](index.md) — Summary matrix of all tensions and patterns\n- [Feature Parity](../../08-products/feature-parity.md) — Platform feature availability matrix", + "src/content/docs/01-vision/evaluations/design-spec-investigation-mindmap.md", + "60207ee26d8d1746", + { "html": 5481, "metadata": 5482 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"design-spec-investigation-mindmap\">Design Spec: Investigation Mindmap\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#design-spec-investigation-mindmap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Spec: Investigation Mindmap”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Authoritative design specification for the Mindmap-first investigation UX. Consolidates four concept documents into a three-layer architecture that replaces the Funnel Panel ecosystem with one spatial view.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"1-three-layer-architecture\">1. Three-Layer Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#1-three-layer-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Three-Layer Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The investigation UX consolidates into three layers with clear boundaries. No layer depends on the others being visible — each works independently but they compose into a coherent whole.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Layer\u003C/th>\u003Cth>Visibility\u003C/th>\u003Cth>Components\u003C/th>\u003Cth>Role\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Chart Layer\u003C/strong>\u003C/td>\u003Ctd>Always visible\u003C/td>\u003Ctd>Boxplot ”↓ drill here”, Pareto ranking, I-Chart patterns, Stats Panel\u003C/td>\u003Ctd>Primary workspace — the analyst reads data and acts on it\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Navigation Layer\u003C/strong>\u003C/td>\u003Ctd>Always visible\u003C/td>\u003Ctd>FilterBreadcrumb (contribution %), VariationBar (cumulative %)\u003C/td>\u003Ctd>Filter state — the analyst sees where they are in the investigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Investigation Layer\u003C/strong>\u003C/td>\u003Ctd>On demand\u003C/td>\u003Ctd>Investigation Mindmap (slide-out panel or pop-out window)\u003C/td>\u003Ctd>Strategic overview — the analyst plans next steps and reviews progress\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layer-boundaries\">Layer Boundaries\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layer-boundaries\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layer Boundaries”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Chart Layer\u003C/strong> owns the data visualization. Charts accept data via props and render the current filtered view. The Boxplot’s ”↓ drill here” label (\u003Ccode dir=\"auto\">Boxplot.tsx:389\u003C/code>) is the Chart Layer’s only guidance element — it points to the highest-η² bar.\u003C/li>\n\u003Cli>\u003Cstrong>Navigation Layer\u003C/strong> owns filter state display. FilterBreadcrumb shows active filters with contribution % badges (color-coded: ≥50% green, ≥30% amber, <30% blue). VariationBar shows cumulative explained variation as a horizontal bar. These components exist today and require no changes.\u003C/li>\n\u003Cli>\u003Cstrong>Investigation Layer\u003C/strong> owns the strategic overview. The Investigation Mindmap replaces the Funnel Panel as the on-demand companion view. It shows all factors spatially, the drill trail, and interaction relationships — information that the Chart and Navigation layers cannot convey because they show one factor at a time.\u003C/li>\n\u003C/ul>\n\u003Cp>The three-layer architecture reduces the current PWA from 20+ guidance surfaces to three clearly scoped layers. The analyst knows where to look: charts for data, breadcrumbs for filter state, mindmap for investigation strategy.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"2-investigation-mindmap--three-modes\">2. Investigation Mindmap — Three Modes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#2-investigation-mindmap--three-modes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Investigation Mindmap — Three Modes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Mindmap has three switchable modes that share the same node layout but show different information. A mode toggle (segmented control) at the top of the mindmap switches between modes. Nodes stay fixed during transitions; only edges, annotations, and layout direction change.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mode-progressive-disclosure\">Mode Progressive Disclosure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mode-progressive-disclosure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mode Progressive Disclosure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Modes unlock progressively as the investigation progresses. The segmented control always shows all three modes, but unavailable modes are muted with a tooltip explaining the requirement.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Mode\u003C/th>\u003Cth>Available When\u003C/th>\u003Cth>Disabled Reason Tooltip\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Drilldown\u003C/strong>\u003C/td>\u003Ctd>Always\u003C/td>\u003Ctd>(never disabled)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Interaction\u003C/strong>\u003C/td>\u003Ctd>2+ factors in the dataset AND n >= 5 after filtering\u003C/td>\u003Ctd>”Requires 2+ factors with at least 5 data points”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Narrative\u003C/strong>\u003C/td>\u003Ctd>1+ drill applied (at least one filter active)\u003C/td>\u003Ctd>“Apply a filter to start building the timeline”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>This is a mode-level progressive disclosure: the analyst cannot switch to Interaction Mode until the data supports pairwise regression, and cannot switch to Narrative Mode until there is at least one drill step to narrate. The gating prevents empty-state confusion.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"drilldown-mode\">Drilldown Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#drilldown-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drilldown Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The default mode. Shows the factor landscape and investigation path.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Factor nodes\u003C/strong>: All categorical factors appear as nodes. Node size is proportional to η² (computed by \u003Ccode dir=\"auto\">getEtaSquared()\u003C/code> in \u003Ccode dir=\"auto\">stats.ts:177\u003C/code> against the current filtered subset). The factor explaining the most remaining variation is the largest node.\u003C/li>\n\u003Cli>\u003Cstrong>Node color encodes filter state\u003C/strong>:\n\u003Cul>\n\u003Cli>\u003Cstrong>Active filter\u003C/strong> (e.g., Store = South): Solid fill, bright color. The filtered value appears as a label below the node.\u003C/li>\n\u003Cli>\u003Cstrong>Available\u003C/strong> (not yet filtered): Outlined, neutral fill. Hovering shows the η² value.\u003C/li>\n\u003Cli>\u003Cstrong>Exhausted\u003C/strong> (filtered, negligible remaining η²): Dimmed/grayed. Signals diminishing returns.\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Drill trail\u003C/strong>: A highlighted path connects nodes in drill order (Start → Store → Time_Slot). The path is the visual record of the investigation sequence.\u003C/li>\n\u003Cli>\u003Cstrong>Suggested-next node\u003C/strong>: The factor with the highest η² among remaining (unfiltered) factors has a pulsing glow or “suggested” badge. This is the spatial equivalent of the Boxplot’s ”↓ drill here” label.\u003C/li>\n\u003Cli>\u003Cstrong>Click node → filter dropdown\u003C/strong>: Clicking a node opens a popover listing that factor’s category values with their contribution percentages. Selecting a value applies the filter. The main dashboard updates simultaneously.\u003C/li>\n\u003Cli>\u003Cstrong>Cumulative progress footer\u003C/strong>: A persistent bar at the bottom shows cumulative explained variation (e.g., “58% of variation explained”) with a 70% target marker. Source: \u003Ccode dir=\"auto\">useVariationTracking\u003C/code> running sum.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interaction-mode\">Interaction Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interaction-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interaction Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Same factor nodes in the same positions. Edges appear showing interaction relationships.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Edges between nodes\u003C/strong>: Thickness proportional to interaction strength (ΔR² — the difference in R² between a model with and without the interaction term, computed by running \u003Ccode dir=\"auto\">calculateMultipleRegression()\u003C/code> at \u003Ccode dir=\"auto\">stats.ts:1886\u003C/code> twice).\u003C/li>\n\u003Cli>\u003Cstrong>Edge color encodes significance\u003C/strong>: Bright/saturated for p < 0.05, muted/translucent for p < 0.10, absent for p ≥ 0.10.\u003C/li>\n\u003Cli>\u003Cstrong>Hover edge → tooltip\u003C/strong>: Shows ΔR², standardized β, p-value, and a plain-language description (e.g., “Store and Time_Slot interact — the Dinner rush effect is stronger at Store South”).\u003C/li>\n\u003Cli>\u003Cstrong>Click edge → multi-select\u003C/strong>: Selects both connected factors for combined analysis in the Regression Panel.\u003C/li>\n\u003Cli>\u003Cstrong>No edges visible\u003C/strong> is itself informative: “Your factors don’t interact significantly — the sequential drill-down captured the main effects.”\u003C/li>\n\u003Cli>\u003Cstrong>Computation\u003C/strong>: Interaction scan runs on demand when the analyst switches to Interaction Mode (not on data load). For N factors, this is N×(N−1)/2 regression pairs. For the typical 3–5 factor dataset, this is 3–10 pairs — fast enough for interactive use.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"narrative-mode\">Narrative Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#narrative-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Narrative Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The spatial layout reorganizes into a linear timeline for stakeholder communication.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Timeline layout\u003C/strong>: Nodes appear sequentially (horizontal on desktop, vertical on mobile) in drill order. Each node is a “step” in the investigation story.\u003C/li>\n\u003Cli>\u003Cstrong>Step annotations\u003C/strong>: Each step shows key findings from that drill point:\n\u003Cul>\n\u003Cli>Factor name and filtered value (e.g., “Step 1: Store = South”)\u003C/li>\n\u003Cli>Variation explained (η² from \u003Ccode dir=\"auto\">useVariationTracking\u003C/code>)\u003C/li>\n\u003Cli>Key statistic change (mean shift, Cpk change from before/after \u003Ccode dir=\"auto\">calculateStats\u003C/code>)\u003C/li>\n\u003Cli>Cumulative explained variation at that point\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Interaction cross-connections\u003C/strong>: If significant interactions were detected, they appear as cross-links between timeline steps (e.g., a dashed arc between Store and Time_Slot steps).\u003C/li>\n\u003Cli>\u003Cstrong>Cumulative progress\u003C/strong>: A running bar along the timeline shows explained variation building at each step.\u003C/li>\n\u003Cli>\u003Cstrong>Conclusion panel\u003C/strong>: At the end of the timeline, a summary: “Two factors explain 60% of delivery time variation.”\u003C/li>\n\u003Cli>\u003Cstrong>Export\u003C/strong>: PNG/SVG image export. The analyst can paste the image into slides or reports. This is the MVP export format.\u003C/li>\n\u003Cli>\u003Cstrong>Annotations\u003C/strong>: The analyst can optionally add text notes to each step (e.g., “Store South uses contract drivers”). Annotations are stored locally and included in exports.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mode-switch-interaction\">Mode Switch Interaction\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mode-switch-interaction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mode Switch Interaction”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>From\u003C/th>\u003Cth>To\u003C/th>\u003Cth>Transition\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Drilldown → Interaction\u003C/td>\u003Ctd>Nodes stay fixed; edges fade in\u003C/td>\u003Ctd>Analyst wants to check factor-pair relationships\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Drilldown → Narrative\u003C/td>\u003Ctd>Nodes reorganize into timeline; trail becomes the sequence\u003C/td>\u003Ctd>Analyst is done investigating, wants to communicate findings\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Interaction → Drilldown\u003C/td>\u003Ctd>Edges fade out; nodes regain drill-state coloring\u003C/td>\u003Ctd>Analyst returns to investigation after checking interactions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Interaction → Narrative\u003C/td>\u003Ctd>Edges fade, nodes reorganize into timeline\u003C/td>\u003Ctd>Analyst wants to include interaction findings in the story\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Narrative → Drilldown\u003C/td>\u003Ctd>Timeline collapses back to spatial layout\u003C/td>\u003Ctd>Analyst wants to resume investigating\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"3-what-the-mindmap-replaces\">3. What the Mindmap Replaces\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#3-what-the-mindmap-replaces\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. What the Mindmap Replaces”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Funnel Panel ecosystem (\u003Ccode dir=\"auto\">VariationFunnel.tsx\u003C/code> — 965 lines, \u003Ccode dir=\"auto\">FunnelPanel.tsx\u003C/code>, \u003Ccode dir=\"auto\">FunnelWindow.tsx\u003C/code>, \u003Ccode dir=\"auto\">InteractionGuidance.tsx\u003C/code>) currently provides investigation guidance through dense, everything-at-once presentation. The Mindmap replaces this with progressive disclosure.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"element-by-element-replacement-map\">Element-by-Element Replacement Map\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#element-by-element-replacement-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Element-by-Element Replacement Map”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Current Funnel Element\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>Mindmap Equivalent\u003C/th>\u003Cth>How It Improves\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Factor ranking list\u003C/strong> (η² bars, sorted)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">VariationFunnel.tsx:96–123\u003C/code>\u003C/td>\u003Ctd>Node size encodes η² ranking spatially\u003C/td>\u003Ctd>Spatial layout is scannable at a glance; no scrolling through a list\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Factor selection checkboxes\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">VariationFunnel.tsx:126–129, 288–298\u003C/code>\u003C/td>\u003Ctd>Click node → filter dropdown\u003C/td>\u003Ctd>Direct manipulation replaces checkbox+apply two-step\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>”Highest impact” label + Drill button\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">VariationFunnel.tsx:635–647\u003C/code>\u003C/td>\u003Ctd>Suggested-next node (pulsing glow)\u003C/td>\u003Ctd>Spatial emphasis is more visible than a text label in a list\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>”Worst” red label\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">VariationFunnel.tsx:727–728\u003C/code>\u003C/td>\u003Ctd>Red-tinted category in click-popover; contribution % visible\u003C/td>\u003Ctd>On-demand detail replaces always-visible label\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Inline Cpk badge\u003C/strong> (improvement projection)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">VariationFunnel.tsx:737–767\u003C/code>\u003C/td>\u003Ctd>Removed — moves to WhatIfSimulator (separate page)\u003C/td>\u003Ctd>Cpk projection is a “what if” scenario, not an investigation guidance element\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Cumulative explained summary\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">VariationFunnel.tsx:267–283\u003C/code>\u003C/td>\u003Ctd>Cumulative progress footer in all three modes\u003C/td>\u003Ctd>Always visible at bottom of mindmap, not buried in a list header\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Category-level μ/σ/% density table\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">VariationFunnel.tsx:183–189\u003C/code> (expanded rows)\u003C/td>\u003Ctd>Available on hover/click in Drilldown Mode popover\u003C/td>\u003Ctd>Progressive disclosure: shown when requested, not always\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>WhatIfSimulator\u003C/strong> (embedded)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">VariationFunnel.tsx:25–28, 139–143\u003C/code>\u003C/td>\u003Ctd>Moves to separate page (see Section 4)\u003C/td>\u003Ctd>Separated mental modes: investigation ≠ scenario modeling\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>InteractionGuidance\u003C/strong> (text prompt)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">InteractionGuidance.tsx:26\u003C/code>\u003C/td>\u003Ctd>Interaction Mode replaces text with visual evidence\u003C/td>\u003Ctd>Edges show \u003Cem>whether\u003C/em> interactions exist, not just \u003Cem>that they might\u003C/em>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pop-out window sync\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FunnelWindow.tsx\u003C/code> (localStorage + postMessage)\u003C/td>\u003Ctd>Reused for Mindmap pop-out window\u003C/td>\u003Ctd>Same bidirectional sync pattern, new content\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Slide-out panel shell\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FunnelPanel.tsx\u003C/code> (backdrop, escape-to-close)\u003C/td>\u003Ctd>Reused for Mindmap slide-out panel\u003C/td>\u003Ctd>Same panel infrastructure, new content\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-gets-explicitly-removed\">What Gets Explicitly Removed\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-gets-explicitly-removed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Gets Explicitly Removed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These Funnel elements are not replicated in the Mindmap because they contribute to the density problem:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Removed Element\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Dual checkboxes\u003C/strong> (select factor + select category)\u003C/td>\u003Ctd>The Funnel required selecting which factors to include, then expanding to select categories. The Mindmap shows all factors by default (nodes) and uses click-to-drill for categories. No two-step selection needed.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Inline Cpk badges\u003C/strong> on category rows\u003C/td>\u003Ctd>Cpk projection per-category is a scenario modeling feature (what if we removed this category?). This belongs in the WhatIfSimulator, not in the investigation overview.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Category-level μ/σ/% always-visible density\u003C/strong>\u003C/td>\u003Ctd>In the Funnel, expanding a factor showed a table of every category with mean, std dev, and % of data. This is useful but dense. The Mindmap’s click-popover shows category contribution % (the actionable metric) on demand. Full stats remain available in the Stats Panel.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>”Standardize to best” presets\u003C/strong>\u003C/td>\u003Ctd>These WhatIfSimulator presets generated from category stats move with the simulator to its own page.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Excluded-category tracking\u003C/strong>\u003C/td>\u003Ctd>The Funnel allowed checking/unchecking categories to see projected stats. This is WhatIfSimulator territory.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"net-effect\">Net Effect\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#net-effect\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Net Effect”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Funnel Panel presents ~15 interactive elements per factor row (checkbox, expand button, category checkboxes, drill button, Cpk badge, worst label, μ/σ/% per category). For 3 factors with 3–7 categories each, this is \u003Cstrong>60–150 interactive elements\u003C/strong> in a 320px-wide panel.\u003C/p>\n\u003Cp>The Mindmap presents 3–5 factor nodes with hover tooltips and click-popovers. The default view has \u003Cstrong>3–5 interactive elements\u003C/strong> plus the mode toggle and progress footer. Detail is available on demand, not by default.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-whatifsimulator-as-separate-page\">4. WhatIfSimulator as Separate Page\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-whatifsimulator-as-separate-page\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. WhatIfSimulator as Separate Page”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The WhatIfSimulator (\u003Ccode dir=\"auto\">WhatIfSimulator.tsx\u003C/code> — currently embedded in the Funnel Panel and available standalone in Azure) moves to its own page/view, accessible from the Settings menu or a dedicated route.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"rationale\">Rationale\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#rationale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Rationale”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Investigation and scenario modeling are distinct mental modes:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Investigation\u003C/strong> (Mindmap): “What is causing the variation?” — exploratory, analytical, drilling into data to identify root causes. The analyst is \u003Cem>reading\u003C/em> the process.\u003C/li>\n\u003Cli>\u003Cstrong>Scenario modeling\u003C/strong> (WhatIfSimulator): “What if we fixed it?” — projective, hypothetical, adjusting parameters to estimate improvement. The analyst is \u003Cem>imagining\u003C/em> a different process.\u003C/li>\n\u003C/ul>\n\u003Cp>Embedding the WhatIfSimulator inside the Funnel Panel conflated these modes. The analyst would drill into a factor, see the “worst” category, then immediately see a Cpk projection for removing it — before finishing the investigation. The separate page enforces a natural workflow: investigate first, then model improvements.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"access-pattern\">Access Pattern\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#access-pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Access Pattern”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Route\u003C/strong>: \u003Ccode dir=\"auto\">/whatif\u003C/code> or equivalent in-app navigation\u003C/li>\n\u003Cli>\u003Cstrong>Entry points\u003C/strong>: (1) Settings/tools menu, (2) “Model improvements” button at the end of a Narrative Mode timeline, (3) direct link from FilterBreadcrumb context menu\u003C/li>\n\u003Cli>\u003Cstrong>Data flow\u003C/strong>: The WhatIfSimulator receives the current process statistics (mean, stdDev, Cpk) and spec limits from the DataContext. It does not need the investigation state — it operates on the filtered data as-is.\u003C/li>\n\u003Cli>\u003Cstrong>Presets\u003C/strong>: The “Exclude worst category” and “Standardize to best” presets (currently generated in \u003Ccode dir=\"auto\">VariationFunnel.tsx:192–265\u003C/code>) move to the WhatIfSimulator page. They are generated from the current filtered data, not from the mindmap state.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"5-statistical-foundation\">5. Statistical Foundation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#5-statistical-foundation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Statistical Foundation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Mindmap’s three modes are powered by two statistical engines already present in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>, plus one new infrastructure requirement.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"existing-η-for-node-sizing-and-drill-ranking\">Existing: η² for Node Sizing and Drill Ranking\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#existing-η-for-node-sizing-and-drill-ranking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Existing: η² for Node Sizing and Drill Ranking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">getEtaSquared(data, factor, outcome)\u003C/code> at \u003Ccode dir=\"auto\">stats.ts:177\u003C/code> computes one-way ANOVA eta-squared (η² = SS_between / SS_total). This is the primary metric for:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Node size\u003C/strong>: Larger η² → larger node. The visual hierarchy directly encodes statistical importance.\u003C/li>\n\u003Cli>\u003Cstrong>Suggested-next\u003C/strong>: The factor with the highest η² among unfiltered factors gets the pulsing suggestion.\u003C/li>\n\u003Cli>\u003Cstrong>Cumulative tracking\u003C/strong>: \u003Ccode dir=\"auto\">useVariationTracking\u003C/code> (in \u003Ccode dir=\"auto\">packages/hooks/src/useVariationTracking.ts\u003C/code>) maintains the running cumulative η² that powers the progress footer.\u003C/li>\n\u003C/ul>\n\u003Cp>η² values are computed per-factor against the current filtered subset, so they update dynamically as the analyst drills. This is the existing behavior — no changes needed.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"existing-regression-for-interaction-edges\">Existing: Regression for Interaction Edges\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#existing-regression-for-interaction-edges\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Existing: Regression for Interaction Edges”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">calculateMultipleRegression(data, outcome, [factor1, factor2], { includeInteractions: true })\u003C/code> at \u003Ccode dir=\"auto\">stats.ts:1886\u003C/code> computes interaction effects. The returned \u003Ccode dir=\"auto\">CoefficientResult\u003C/code> objects include \u003Ccode dir=\"auto\">standardizedBeta\u003C/code>, \u003Ccode dir=\"auto\">tStatistic\u003C/code>, and \u003Ccode dir=\"auto\">pValue\u003C/code> for each interaction term.\u003C/p>\n\u003Cp>For Interaction Mode edges:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Edge thickness\u003C/strong>: ΔR² = R²_full − R²_main (run \u003Ccode dir=\"auto\">calculateMultipleRegression\u003C/code> twice — once with \u003Ccode dir=\"auto\">includeInteractions: false\u003C/code>, once with \u003Ccode dir=\"auto\">true\u003C/code>). This is a ~10-line utility function (see \u003Ca href=\"design-brief-guided-investigation.md#1-statistical-methodology\">Design Brief §1\u003C/a> for specification).\u003C/li>\n\u003Cli>\u003Cstrong>Edge color\u003C/strong>: Based on the interaction term’s p-value from the full model.\u003C/li>\n\u003Cli>\u003Cstrong>Tooltip content\u003C/strong>: ΔR², largest |standardized β| among interaction terms, p-value.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"new-infrastructure-drill-path-recording\">New Infrastructure: Drill-Path Recording\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#new-infrastructure-drill-path-recording\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “New Infrastructure: Drill-Path Recording”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All three Mindmap modes require a recorded sequence of drill steps. This does not exist today — the current filter stack (\u003Ccode dir=\"auto\">useFilterNavigation\u003C/code>) tracks \u003Cem>what\u003C/em> is filtered but not the \u003Cem>order\u003C/em> or \u003Cem>statistics at each step\u003C/em>.\u003C/p>\n\u003Cp>The drill-path recording system needs to capture, for each drill step:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Field\u003C/th>\u003Cth>Source\u003C/th>\u003Cth>Used By\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Factor name\u003C/td>\u003Ctd>Filter action\u003C/td>\u003Ctd>All three modes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filtered value(s)\u003C/td>\u003Ctd>Filter action\u003C/td>\u003Ctd>Drilldown Mode (node labels), Narrative Mode (step annotations)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>η² at time of drill\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getEtaSquared()\u003C/code> on pre-drill data\u003C/td>\u003Ctd>Narrative Mode (step annotations)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cumulative η² after drill\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code>\u003C/td>\u003Ctd>Narrative Mode (progress bar)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mean before/after\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">calculateStats()\u003C/code> on pre/post-drill data\u003C/td>\u003Ctd>Narrative Mode (statistic change)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cpk before/after\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">calculateStats()\u003C/code> on pre/post-drill data\u003C/td>\u003Ctd>Narrative Mode (capability change)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Timestamp\u003C/td>\u003Ctd>System clock\u003C/td>\u003Ctd>Narrative Mode (ordering)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>This recording can be built as a new hook (\u003Ccode dir=\"auto\">useDrillPath\u003C/code>) or as an extension to \u003Ccode dir=\"auto\">useFilterNavigation\u003C/code>. The data is ephemeral (session-only) and lightweight (~100 bytes per drill step). Implementation detail is deferred to the coding phase.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"6-platform-strategy--pwa-and-azure-only\">6. Platform Strategy — PWA and Azure Only\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#6-platform-strategy--pwa-and-azure-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Platform Strategy — PWA and Azure Only”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Investigation Mindmap is a \u003Cstrong>PWA + Azure feature only\u003C/strong>. The Excel Add-in has a fundamentally different interaction model (native Excel slicers) and doesn’t use the progressive drill-down workflow that the Mindmap visualizes.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa\">PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Panel model\u003C/strong>: Slide-out panel from the right side, occupying the same slot as the current Funnel Panel. Reuses the \u003Ccode dir=\"auto\">FunnelPanel.tsx\u003C/code> shell (backdrop, escape-to-close, outside-click-to-close).\u003C/li>\n\u003Cli>\u003Cstrong>Pop-out window\u003C/strong>: Available as an option. Reuses the \u003Ccode dir=\"auto\">FunnelWindow.tsx\u003C/code> bidirectional sync pattern (localStorage + postMessage). The analyst can drag the Mindmap to a second monitor while the main dashboard stays on the primary screen.\u003C/li>\n\u003Cli>\u003Cstrong>Modes available\u003C/strong>: Drilldown Mode (full), Interaction Mode (full), Narrative Mode (view only — PNG export limited to screenshot).\u003C/li>\n\u003Cli>\u003Cstrong>Trigger\u003C/strong>: Labelled “Investigation” button (Network icon + text) in the header. Replaces the previous unlabelled icon toggle.\u003C/li>\n\u003Cli>\u003Cstrong>First-drill prompt\u003C/strong>: A one-time callout (\u003Ccode dir=\"auto\">InvestigationPrompt\u003C/code>) appears when the user applies their first filter, pointing them to the Investigation panel. Dismissed per session via sessionStorage.\u003C/li>\n\u003Cli>\u003Cstrong>VariationBar gateway\u003C/strong>: The VariationBar accepts an optional \u003Ccode dir=\"auto\">onClick\u003C/code> prop, allowing it to serve as an additional entry point to the Investigation panel.\u003C/li>\n\u003Cli>\u003Cstrong>Export\u003C/strong>: Copy-to-clipboard, PNG download, and SVG download available in all three modes (Drilldown, Interactions, Narrative).\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure\">Azure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Panel model\u003C/strong>: Same slide-out panel as PWA.\u003C/li>\n\u003Cli>\u003Cstrong>Split-pane option\u003C/strong>: On desktop (viewport > 1280px), the Mindmap can open as a persistent side panel alongside the dashboard. This is appropriate for Azure’s desktop-oriented professional workflow.\u003C/li>\n\u003Cli>\u003Cstrong>Pop-out window\u003C/strong>: Same as PWA.\u003C/li>\n\u003Cli>\u003Cstrong>Modes available\u003C/strong>: All three modes with full functionality.\u003C/li>\n\u003Cli>\u003Cstrong>Trigger\u003C/strong>: Labelled “Investigation” button (Network icon + text), same as PWA.\u003C/li>\n\u003Cli>\u003Cstrong>First-drill prompt\u003C/strong>: Same \u003Ccode dir=\"auto\">InvestigationPrompt\u003C/code> callout as PWA (same default color scheme).\u003C/li>\n\u003Cli>\u003Cstrong>VariationBar gateway\u003C/strong>: Same clickable VariationBar as PWA.\u003C/li>\n\u003Cli>\u003Cstrong>Export\u003C/strong>: Copy-to-clipboard, PNG download, and SVG download available in all three modes. SVG export is Azure-only. Annotations are saved with the project (OneDrive sync).\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"excel-add-in--explicitly-excluded\">Excel Add-in — Explicitly Excluded\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#excel-add-in--explicitly-excluded\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Excel Add-in — Explicitly Excluded”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Excel Add-in uses native Excel slicers for filtering. There is no progressive drill-down workflow, no filter breadcrumbs, no cumulative η² tracking. The Mindmap concept does not apply to the slicer interaction model. The Excel Add-in’s investigation workflow is: set slicer values → read chart → adjust slicers. This is fundamentally different from the PWA/Azure drill-down-and-refine workflow.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"export-by-platform\">Export by Platform\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#export-by-platform\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Export by Platform”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Export (copy-to-clipboard, PNG, SVG) is available in all three modes, not only Narrative.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>PWA (free)\u003C/th>\u003Cth>Azure (paid)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Export modes\u003C/td>\u003Ctd>All (Drilldown, Interactions, Narrative)\u003C/td>\u003Ctd>All (Drilldown, Interactions, Narrative)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Copy to clipboard\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PNG export\u003C/td>\u003Ctd>Yes (high-resolution render)\u003C/td>\u003Ctd>Yes (high-resolution render)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SVG export\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Annotations\u003C/td>\u003Ctd>Session-only (not saved)\u003C/td>\u003Ctd>Saved with project (OneDrive)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Template customization\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Future (post-MVP)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"7-progressive-disclosure-design\">7. Progressive Disclosure Design\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#7-progressive-disclosure-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “7. Progressive Disclosure Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Mindmap’s core design principle is progressive disclosure — the answer to the Funnel Panel’s density problem. The Funnel showed everything simultaneously; the Mindmap shows information in layers activated by user intent.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"disclosure-levels\">Disclosure Levels\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#disclosure-levels\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Disclosure Levels”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Level\u003C/th>\u003Cth>Trigger\u003C/th>\u003Cth>What Appears\u003C/th>\u003Cth>Cognitive Load\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Default view\u003C/strong>\u003C/td>\u003Ctd>Panel opens\u003C/td>\u003Ctd>Factor nodes + drill trail + progress footer\u003C/td>\u003Ctd>Low — 3–5 nodes, one trail, one bar\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Hover\u003C/strong>\u003C/td>\u003Ctd>Mouse over node\u003C/td>\u003Ctd>Factor name, η² value, current filter value (if active)\u003C/td>\u003Ctd>Low — single tooltip\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Click\u003C/strong>\u003C/td>\u003Ctd>Click on node\u003C/td>\u003Ctd>Popover with category values, contribution % per category, “drill” action per value\u003C/td>\u003Ctd>Moderate — one factor’s detail\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mode switch\u003C/strong>\u003C/td>\u003Ctd>Toggle control\u003C/td>\u003Ctd>Drilldown ↔ Interaction ↔ Narrative (gated — see below)\u003C/td>\u003Ctd>Moderate — changes the information lens\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Interaction hover\u003C/strong>\u003C/td>\u003Ctd>Mouse over edge\u003C/td>\u003Ctd>ΔR², p-value, plain-language description\u003C/td>\u003Ctd>Moderate — single interaction detail\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Mode-level gating\u003C/strong>: Modes themselves are gated by progressive disclosure. Interactions mode requires 2+ factors AND n >= 5 after filtering. Narrative mode requires at least 1 drill applied. Disabled modes appear muted in the segmented control with a tooltip explaining what is needed to unlock them. This prevents the analyst from encountering empty or meaningless views.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-is-never-shown-simultaneously\">What Is Never Shown Simultaneously\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-is-never-shown-simultaneously\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Is Never Shown Simultaneously”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The following information was shown simultaneously in the Funnel Panel and is now gated behind progressive disclosure:\u003C/p>\n\u003Cul>\n\u003Cli>All category statistics (μ, σ, %) for all factors — only shown for one factor at a time, on click\u003C/li>\n\u003Cli>Dual checkboxes (factor-level + category-level) — eliminated entirely\u003C/li>\n\u003Cli>Inline Cpk badges per category — moved to WhatIfSimulator\u003C/li>\n\u003Cli>“Worst” labels on every category row — replaced by contribution % color-coding in click-popover\u003C/li>\n\u003Cli>WhatIfSimulator presets — moved to separate page\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"visual-hierarchy\">Visual Hierarchy\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#visual-hierarchy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Hierarchy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>In Drilldown Mode, the visual hierarchy is:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Node size\u003C/strong> — the dominant signal. Largest node = most variation explained. Scannable in <1 second.\u003C/li>\n\u003Cli>\u003Cstrong>Node color/fill\u003C/strong> — active (filled) vs. available (outlined) vs. exhausted (dimmed). Filter state at a glance.\u003C/li>\n\u003Cli>\u003Cstrong>Drill trail\u003C/strong> — the path through the nodes. Investigation history visible as a highlighted line.\u003C/li>\n\u003Cli>\u003Cstrong>Suggested-next pulse\u003C/strong> — draws attention to the recommended next factor. Subtle but discoverable.\u003C/li>\n\u003Cli>\u003Cstrong>Progress footer\u003C/strong> — cumulative %. Always visible but not competing with the spatial layout.\u003C/li>\n\u003C/ol>\n\u003Cp>In Interaction Mode, the hierarchy shifts:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Edge thickness\u003C/strong> — the dominant signal. Thickest edge = strongest interaction.\u003C/li>\n\u003Cli>\u003Cstrong>Edge color\u003C/strong> — significance encoding. Bright = statistically significant.\u003C/li>\n\u003Cli>\u003Cstrong>Node size\u003C/strong> — secondary context (η² for main effects).\u003C/li>\n\u003C/ol>\n\u003Cp>In Narrative Mode, the hierarchy is temporal:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Timeline position\u003C/strong> — left-to-right sequence of drill steps.\u003C/li>\n\u003Cli>\u003Cstrong>Step annotations\u003C/strong> — findings at each step.\u003C/li>\n\u003Cli>\u003Cstrong>Cumulative progress bar\u003C/strong> — building total along the timeline.\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"8-demo-walkthrough--pizza-delivery-with-mindmap-ux\">8. Demo Walkthrough — Pizza Delivery with Mindmap UX\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#8-demo-walkthrough--pizza-delivery-with-mindmap-ux\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “8. Demo Walkthrough — Pizza Delivery with Mindmap UX”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This walkthrough uses the Pizza Delivery dataset (\u003Ccode dir=\"auto\">packages/data/src/samples/pizza.ts\u003C/code>) — 252 observations, 3 factors (Store, Time_Slot, Day), outcome Delivery_Time_min. It revises the \u003Ca href=\"investigation-flow-map.md\">Investigation Flow Map\u003C/a> walkthrough to show the Mindmap-first UX.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-1-data-loaded\">Step 1: Data Loaded\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-data-loaded\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Data Loaded”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Chart Layer\u003C/strong>: I-Chart shows delivery times with control limits. Boxplot shows Store groups — Store South’s box is wider and higher. ”↓ drill here” appears on Store South. Pareto ranks out-of-spec frequency by Store.\u003C/p>\n\u003Cp>\u003Cstrong>Navigation Layer\u003C/strong>: No active filters. VariationBar shows 0% explained.\u003C/p>\n\u003Cp>\u003Cstrong>Investigation Layer (if opened)\u003C/strong>: Three factor nodes — Store (large, ~40% η²), Time_Slot (medium, ~20% η²), Day (small, ~3% η²). Store node pulses as suggested-next. No drill trail. Progress footer: “0% explained.”\u003C/p>\n\u003Cp>\u003Cem>Compared to Flow Map Step 1\u003C/em>: The Mindmap immediately shows the factor landscape — three nodes with visual hierarchy. The analyst sees that Store dominates before touching anything. Previously, this required opening the hidden Funnel Panel.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-2-analyst-drills-store-south\">Step 2: Analyst Drills Store South\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-analyst-drills-store-south\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Analyst Drills Store South”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst clicks the Store node in the Mindmap → popover shows: North (15%), Central (12%), South (45%). Analyst clicks “South” → filter applied.\u003C/p>\n\u003Cp>\u003Cstrong>Chart Layer\u003C/strong>: I-Chart filters to Store South. Boxplot now shows Time_Slot groups. ”↓ drill here” on Dinner.\u003C/p>\n\u003Cp>\u003Cstrong>Navigation Layer\u003C/strong>: FilterBreadcrumb shows “Store: South 45%”. VariationBar shows ~40%.\u003C/p>\n\u003Cp>\u003Cstrong>Investigation Layer\u003C/strong>: Store node fills solid (active). Trail: Start → Store. Time_Slot node is now the largest remaining (highest η² on filtered data). Time_Slot pulses as suggested-next. Day remains small. Progress footer: “40% explained.”\u003C/p>\n\u003Cp>\u003Cem>Compared to Flow Map Step 2\u003C/em>: The analyst can drill from the Mindmap or the Boxplot — both paths are valid. The Mindmap shows Time_Slot as the clear next candidate without requiring the analyst to open the Funnel Panel.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-3-analyst-drills-time_slot-dinner\">Step 3: Analyst Drills Time_Slot Dinner\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-analyst-drills-time_slot-dinner\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Analyst Drills Time_Slot Dinner”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst clicks the Time_Slot node → popover shows: Lunch (8%), Dinner (25%), Late Night (5%). Analyst clicks “Dinner.”\u003C/p>\n\u003Cp>\u003Cstrong>Chart Layer\u003C/strong>: I-Chart filters to Store South + Dinner. Boxplot shows Day groups (roughly even).\u003C/p>\n\u003Cp>\u003Cstrong>Navigation Layer\u003C/strong>: Two chips: “Store: South 45%” and “Time_Slot: Dinner 25%”. VariationBar shows ~58%.\u003C/p>\n\u003Cp>\u003Cstrong>Investigation Layer\u003C/strong>: Store and Time_Slot nodes filled. Trail: Start → Store → Time_Slot. Day node is small and dimmed (low η², ~3%). No suggestion pulse (remaining factors are weak). Progress footer: “58% explained.”\u003C/p>\n\u003Cp>\u003Cem>Compared to Flow Map Step 3\u003C/em>: Previously, the analyst would open the Funnel Panel to see the investigation state. Now the Mindmap shows the same information spatially — two filled nodes, one dimmed, trail visible.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-4-analyst-checks-interactions\">Step 4: Analyst Checks Interactions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-analyst-checks-interactions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Analyst Checks Interactions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Curious whether Store and Time_Slot interact, the analyst toggles to Interaction Mode.\u003C/p>\n\u003Cp>\u003Cstrong>Investigation Layer\u003C/strong>: Same three nodes. An edge appears between Store and Time_Slot — medium thickness (moderate ΔR²), bright color (p < 0.05). No significant edges for Store–Day or Time_Slot–Day. Hovering the edge: “Store × Time_Slot: ΔR² = 0.05, p = 0.02. The Dinner rush effect is stronger at Store South.”\u003C/p>\n\u003Cp>\u003Cem>Compared to Flow Map Steps 4 + 6\u003C/em>: Previously, the analyst saw a text-only InteractionGuidance prompt, then had to navigate to the Regression Panel, configure it, and read coefficient tables. Now the interaction is visible as a single edge — one glance instead of a multi-step workflow.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-5-analyst-decides-to-stop\">Step 5: Analyst Decides to Stop\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-analyst-decides-to-stop\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Analyst Decides to Stop”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Back in Drilldown Mode, the analyst sees: 58% explained, Day is dimmed (3% η²), no strong suggestion. The progress footer shows the 70% target marker is ahead but the remaining factors are weak.\u003C/p>\n\u003Cp>The analyst decides the investigation has found the key drivers (Store South + Dinner rush) and toggles to Narrative Mode.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-6-narrative-mode--communication\">Step 6: Narrative Mode — Communication\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-6-narrative-mode--communication\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 6: Narrative Mode — Communication”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Investigation Layer\u003C/strong>: Timeline appears:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Step 1\u003C/strong>: Store = South — “Explains 40% of variation. Mean delivery time: 35 min vs. 28 min overall.”\u003C/li>\n\u003Cli>\u003Cstrong>Step 2\u003C/strong>: Time_Slot = Dinner — “Explains 25% of remaining variation. Dinner adds +7 min average.”\u003C/li>\n\u003Cli>\u003Cstrong>Interaction note\u003C/strong>: Dashed arc between steps — “Store × Time_Slot interaction (p = 0.02). Dinner rush at Store South is 2× worse than other stores.”\u003C/li>\n\u003Cli>\u003Cstrong>Conclusion\u003C/strong>: “Two factors explain 58% of delivery time variation. Day has no significant effect.”\u003C/li>\n\u003C/ul>\n\u003Cp>The analyst adds an annotation to Step 1: “Store South uses contract drivers with less route knowledge.” Exports as PNG for the team meeting.\u003C/p>\n\u003Cp>\u003Cem>Compared to Flow Map Step 7\u003C/em>: Previously, the investigation ended without ceremony — no summary, no exportable artifact. Now the Narrative Mode creates a presentation-ready visual story.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"9-competitive-positioning\">9. Competitive Positioning\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#9-competitive-positioning\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “9. Competitive Positioning”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>No competitor offers a spatial investigation overview. The Investigation Mindmap is a genuine differentiator — and critically, it is a \u003Cstrong>consolidation\u003C/strong> (fewer surfaces, less cognitive load) rather than a feature addition.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-competitors-offer\">What Competitors Offer\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-competitors-offer\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Competitors Offer”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Competitor\u003C/th>\u003Cth>Factor Exploration\u003C/th>\u003Cth>Investigation Overview\u003C/th>\u003Cth>Presentation Output\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Minitab\u003C/strong>\u003C/td>\u003Ctd>Menu-driven ANOVA, stepwise regression. No visual ranking.\u003C/td>\u003Ctd>Session Window (text log). No spatial view.\u003C/td>\u003Ctd>Manual PowerPoint.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>JMP\u003C/strong>\u003C/td>\u003Ctd>Effect Summary ranks by LogWorth. Model-first.\u003C/td>\u003Ctd>Journal (command replay). No spatial view.\u003C/td>\u003Ctd>JMP Journal export.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Tableau\u003C/strong>\u003C/td>\u003Ctd>Sidebar filters, equal-weight checkboxes.\u003C/td>\u003Ctd>Dashboard shows current state, not journey.\u003C/td>\u003Ctd>Story Points (manual slide sequence).\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Power BI\u003C/strong>\u003C/td>\u003Ctd>Slicer paradigm. Key Influencers auto-ranks.\u003C/td>\u003Ctd>Decomposition Tree (enforced top-down tree).\u003C/td>\u003Ctd>Report export.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>EDAScout\u003C/strong>\u003C/td>\u003Ctd>Smart Cards, AI chatbot.\u003C/td>\u003Ctd>Chat transcript (verbose, not visual).\u003C/td>\u003Ctd>No export.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"competitive/\">competitor benchmarks\u003C/a> for detailed assessments.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscouts-unique-position\">VariScout’s Unique Position\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscouts-unique-position\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout’s Unique Position”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Mindmap combines three capabilities no competitor has together:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Spatial factor overview\u003C/strong> — factors as nodes sized by statistical importance (η²), not a flat list or tree.\u003C/li>\n\u003Cli>\u003Cstrong>Investigation state tracking\u003C/strong> — the drill trail shows where the analyst has been, suggested-next shows where to go.\u003C/li>\n\u003Cli>\u003Cstrong>Interaction overlay\u003C/strong> — edges show factor-pair relationships without requiring a separate analysis step.\u003C/li>\n\u003C/ol>\n\u003Cp>This is achieved through consolidation. The current Funnel Panel has more UI elements than most competitors’ entire factor analysis workflow — but those elements are hidden, dense, and PWA-only. The Mindmap surfaces the same statistical insights through a simpler, spatial interface available on both PWA and Azure.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"10-design-questions-for-uiux-phase\">10. Design Questions for UI/UX Phase\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#10-design-questions-for-uiux-phase\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “10. Design Questions for UI/UX Phase”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These questions must be resolved during the UI/UX design phase before implementation begins.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"node-layout\">Node Layout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#node-layout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Node Layout”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Layout algorithm\u003C/strong>: Should nodes use a radial layout (factors arranged in a circle around a center “start” node), a hierarchical layout (top-to-bottom by η² ranking), or force-directed-lite (spring forces with fixed positions after initial layout)? Radial is simplest to implement (static SVG positioning). Hierarchical matches the ranking mental model. Force-directed is most flexible but requires a physics engine.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Node count limit\u003C/strong>: With 3–5 factors, any layout works. At 8+ factors (possible in Azure with complex datasets), does the spatial layout become cluttered? Should there be a threshold where the layout switches to a compact list fallback?\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mode-switch\">Mode Switch\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mode-switch\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mode Switch”\u003C/span>\u003C/a>\u003C/div>\n\u003Col start=\"3\">\n\u003Cli>\u003Cstrong>Discoverability\u003C/strong>: How does the analyst discover that Interaction Mode and Narrative Mode exist? Options: (a) segmented control always visible at the top, (b) icon toggle that reveals modes on hover, (c) contextual prompt (“You’ve drilled 2 factors — check for interactions?”). The segmented control is most discoverable but takes space.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"click-popover\">Click-Popover\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#click-popover\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Click-Popover”\u003C/span>\u003C/a>\u003C/div>\n\u003Col start=\"4\">\n\u003Cli>\u003Cstrong>Category count limit\u003C/strong>: When a factor has 7+ categories (e.g., Day of week), does the click-popover become too long? Should it scroll, paginate, or show only the top N categories by contribution? The Pizza dataset’s “Day” factor has 7 levels — a good test case.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mobile\">Mobile\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mobile\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile”\u003C/span>\u003C/a>\u003C/div>\n\u003Col start=\"5\">\n\u003Cli>\u003Cstrong>Mobile adaptation\u003C/strong>: On mobile viewports (<768px), should the Mindmap open as a full-screen overlay (replacing the dashboard temporarily) or remain a slide-out panel? The current FunnelPanel uses a 320px slide-out which leaves no space for chart interaction. Full-screen mode gives the Mindmap room but breaks the “mindmap beside charts” spatial memory.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"export\">Export\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#export\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Export”\u003C/span>\u003C/a>\u003C/div>\n\u003Col start=\"6\">\n\u003Cli>\u003Cstrong>Narrative export MVP\u003C/strong>: Is PNG-only sufficient for the first release? SVG would allow lossless scaling but is less familiar to users. Should copy-to-clipboard (as image) be prioritized over file-save for the “paste into slides” workflow?\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"11-design-thinking-history\">11. Design Thinking History\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#11-design-thinking-history\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “11. Design Thinking History”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This spec consolidates four concept documents written during the design exploration phase. Each contributed specific ideas that are now incorporated into the Mindmap-first architecture.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Document\u003C/th>\u003Cth>What It Contributed\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"design-brief-guided-investigation.md\">Design Brief\u003C/a>\u003C/td>\u003Ctd>Statistical methodology (η² for drill ranking, regression for interactions, ΔR² helper specification). UI audit of 10+ existing guidance elements. Competitive design principles (rank by importance, make suggestions optional, integrate into flow). 10 design questions.\u003C/td>\u003Ctd>Historical — statistical methodology and competitive principles are canonical references. Design questions revised into Section 10.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"investigation-flow-map.md\">Investigation Flow Map\u003C/a>\u003C/td>\u003Ctd>7-step Pizza Delivery walkthrough documenting existing guidance at each step and identifying gaps. Guidance coverage table mapping existing elements to Phase 1/2/3 features.\u003C/td>\u003Ctd>Historical — the “before” state. The Section 8 walkthrough is the “after” state showing the Mindmap-first UX at each step.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/investigation-mindmap.md\">Investigation Mindmap\u003C/a>\u003C/td>\u003Ctd>Two-mode concept (Drilldown + Interaction). Node sizing by η², color by filter state. Suggested-next pulsing. Click-to-filter. Pop-out window model. Competitive landscape (no competitor has spatial investigation overview). Persona impact assessment.\u003C/td>\u003Ctd>\u003Cstrong>Elevated to primary\u003C/strong> — the two-mode concept is expanded to three modes (adding Narrative). The Investigation Mindmap pattern evaluation is the conceptual ancestor of this spec.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/investigation-narrative.md\">Investigation Narrative\u003C/a>\u003C/td>\u003Ctd>Timeline concept with step annotations and cumulative progress. Export for stakeholder presentations. Persona impact (strongly positive for Olivia, Tina). Platform fit (Azure primary, PWA limited).\u003C/td>\u003Ctd>\u003Cstrong>Absorbed as Mindmap’s third mode\u003C/strong> — the Narrative becomes a mode within the Mindmap rather than a separate component. This simplifies the architecture (one component, three views) and leverages the shared node layout.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The four documents are kept in \u003Ccode dir=\"auto\">docs/01-vision/evaluations/\u003C/code> as historical design thinking. They should not be used as implementation references — this spec is the authoritative source for the Mindmap UX.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"12-implementation-phasing\">12. Implementation Phasing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#12-implementation-phasing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “12. Implementation Phasing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Mindmap ships mode-by-mode. Each phase is self-contained and shippable; each builds on the previous phase’s infrastructure.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-a-infrastructure--drilldown-mode\">Phase A: Infrastructure + Drilldown Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-a-infrastructure--drilldown-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase A: Infrastructure + Drilldown Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Ships first. Replaces the Funnel Panel with a spatial investigation view.\u003C/p>\n\u003Cp>\u003Cstrong>New infrastructure:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Scope\u003C/th>\u003Cth>Estimate\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useDrillPath\u003C/code> hook\u003C/td>\u003Ctd>Records drill steps with before/after stats (factor, filtered value, η², cumulative η², mean, Cpk, timestamp)\u003C/td>\u003Ctd>~100 lines\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mindmap SVG component\u003C/td>\u003Ctd>Static radial or hierarchical layout of factor nodes\u003C/td>\u003Ctd>~300–500 lines\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Drilldown Mode features:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Node rendering\u003C/strong>: Size proportional to η² (via \u003Ccode dir=\"auto\">getEtaSquared()\u003C/code>), color by filter state (active/available/exhausted), factor labels\u003C/li>\n\u003Cli>\u003Cstrong>Drill trail\u003C/strong>: Highlighted path through nodes in drill order (Start → Store → Time_Slot)\u003C/li>\n\u003Cli>\u003Cstrong>Suggested-next\u003C/strong>: Pulsing glow on the highest-η² remaining node\u003C/li>\n\u003Cli>\u003Cstrong>Click-popover\u003C/strong>: Category values with contribution %, drill action per value\u003C/li>\n\u003Cli>\u003Cstrong>Cumulative progress footer\u003C/strong>: Running η² bar with 70% target marker\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Reuses existing infrastructure:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">FunnelPanel.tsx\u003C/code> shell (slide-out, backdrop, escape-to-close) → \u003Ccode dir=\"auto\">MindmapPanel.tsx\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">FunnelWindow.tsx\u003C/code> sync pattern (localStorage + postMessage) → \u003Ccode dir=\"auto\">MindmapWindow.tsx\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code> (η² data, cumulative tracking)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">getEtaSquared()\u003C/code> (node sizing)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Replaces:\u003C/strong> Funnel icon in the header opens the Mindmap instead of the Funnel Panel. The Funnel Panel remains in the codebase until the Mindmap is validated, then is removed.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-b-interaction-mode\">Phase B: Interaction Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-b-interaction-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase B: Interaction Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Adds edge rendering to the existing node layout. Requires Phase A’s nodes and SVG component.\u003C/p>\n\u003Cp>\u003Cstrong>New infrastructure:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Scope\u003C/th>\u003Cth>Estimate\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">getInteractionStrength()\u003C/code> helper\u003C/td>\u003Ctd>Utility in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>: ΔR² = R²_full − R²_main (runs \u003Ccode dir=\"auto\">calculateMultipleRegression()\u003C/code> twice)\u003C/td>\u003Ctd>~10 lines\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Interaction Mode features:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Edge rendering\u003C/strong>: SVG paths between factor nodes, thickness proportional to ΔR², color by p-value (bright for p < 0.05, muted for p < 0.10, absent for p ≥ 0.10)\u003C/li>\n\u003Cli>\u003Cstrong>Edge tooltips\u003C/strong>: ΔR², standardized β, p-value, plain-language description\u003C/li>\n\u003Cli>\u003Cstrong>Mode toggle\u003C/strong>: Segmented control at top of Mindmap (Drilldown / Interaction)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Reuses:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">calculateMultipleRegression()\u003C/code> with \u003Ccode dir=\"auto\">includeInteractions: true/false\u003C/code> (existing in \u003Ccode dir=\"auto\">stats.ts:1886\u003C/code>)\u003C/li>\n\u003Cli>Phase A’s node layout, SVG component, and panel shell\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-c-narrative-mode--whatifsimulator-separation\">Phase C: Narrative Mode + WhatIfSimulator Separation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-c-narrative-mode--whatifsimulator-separation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase C: Narrative Mode + WhatIfSimulator Separation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Adds timeline layout and export. Requires Phase A’s drill trail data and Phase B’s edge data for interaction cross-connections.\u003C/p>\n\u003Cp>\u003Cstrong>New infrastructure:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Scope\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Timeline layout\u003C/td>\u003Ctd>Reorganize nodes into horizontal (desktop) / vertical (mobile) sequence\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step annotations\u003C/td>\u003Ctd>η², mean shift, Cpk change per step from \u003Ccode dir=\"auto\">useDrillPath\u003C/code> recorded data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Interaction cross-connections\u003C/td>\u003Ctd>Dashed arcs between timeline steps from Phase B edge data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Conclusion panel\u003C/td>\u003Ctd>Summary text generated from drill-path statistics\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PNG export\u003C/td>\u003Ctd>Canvas/SVG-to-PNG rendering for stakeholder presentations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>WhatIfSimulator standalone page\u003C/td>\u003Ctd>New route \u003Ccode dir=\"auto\">/whatif\u003C/code>, presets migrated from \u003Ccode dir=\"auto\">VariationFunnel.tsx\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Mode toggle expands\u003C/strong> to three segments (Drilldown / Interaction / Narrative).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-d-polish--azure-enhancements\">Phase D: Polish + Azure Enhancements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-d-polish--azure-enhancements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase D: Polish + Azure Enhancements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Platform-specific refinements. No new modes.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Azure split-pane option\u003C/strong>: Persistent side panel alongside dashboard on viewport > 1280px\u003C/li>\n\u003Cli>\u003Cstrong>Annotations\u003C/strong>: Text input per timeline step (Azure: saved to OneDrive with project; PWA: session-only)\u003C/li>\n\u003Cli>\u003Cstrong>SVG export\u003C/strong>: Azure only (lossless scaling for team presentations)\u003C/li>\n\u003Cli>\u003Cstrong>“Model improvements” button\u003C/strong>: At end of Narrative timeline → links to WhatIfSimulator at \u003Ccode dir=\"auto\">/whatif\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-dependencies\">Phase Dependencies\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-dependencies\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase Dependencies”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Phase A (Drilldown Mode)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─→ Phase B (Interaction Mode) — needs A's nodes + SVG component\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─→ Phase C (Narrative Mode) — needs A's drill trail + B's edges\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─→ Phase D (Polish) — needs all three modes complete\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Phase A (Drilldown Mode) └─→ Phase B (Interaction Mode) — needs A's nodes + SVG component └─→ Phase C (Narrative Mode) — needs A's drill trail + B's edges └─→ Phase D (Polish) — needs all three modes complete\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-this-phasing-subsumes\">What This Phasing Subsumes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-this-phasing-subsumes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What This Phasing Subsumes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The original evaluations index proposed a four-phase sequence (Factor Suggestion → Interaction Heatmap → Investigation Mindmap → Factor Map). The Mindmap-first architecture consolidates this:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Factor Suggestion\u003C/strong> (old Phase 1) is subsumed by the suggested-next node in Drilldown Mode (Phase A). The pulsing glow on the highest-η² node provides the same guidance without a separate feature.\u003C/li>\n\u003Cli>\u003Cstrong>Interaction Heatmap\u003C/strong> (old Phase 2) is subsumed by Interaction Mode edges (Phase B). Visual edges between nodes replace the standalone heatmap component.\u003C/li>\n\u003Cli>\u003Cstrong>Factor Map\u003C/strong> (old Phase 4) is no longer needed. The Mindmap \u003Cem>is\u003C/em> a lighter-weight Factor Map with three focused modes instead of one dense visualization.\u003C/li>\n\u003C/ul>\n\u003Cp>The Mindmap consolidates rather than adding surfaces.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documents\">Related Documents\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documents\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documents”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"design-brief-guided-investigation.md\">Design Brief\u003C/a> — Statistical methodology, UI audit, competitive principles\u003C/li>\n\u003Cli>\u003Ca href=\"investigation-flow-map.md\">Investigation Flow Map\u003C/a> — 7-step walkthrough (pre-Mindmap UX)\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/investigation-mindmap.md\">Investigation Mindmap\u003C/a> — Original two-mode concept evaluation\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/investigation-narrative.md\">Investigation Narrative\u003C/a> — Original timeline/export concept evaluation\u003C/li>\n\u003Cli>\u003Ca href=\"index.md\">Evaluations Index\u003C/a> — Summary matrix of all tensions and patterns\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/feature-parity.md\">Feature Parity\u003C/a> — Platform feature availability matrix\u003C/li>\n\u003C/ul>", + { + "headings": 5483, + "localImagePaths": 5639, + "remoteImagePaths": 5640, + "frontmatter": 5641, + "imagePaths": 5642 + }, + [ + 5484, 5486, 5489, 5492, 5495, 5498, 5501, 5504, 5507, 5510, 5513, 5516, 5519, 5522, 5525, 5526, + 5529, 5532, 5535, 5538, 5541, 5544, 5547, 5550, 5553, 5556, 5559, 5562, 5565, 5568, 5571, 5574, + 5577, 5580, 5583, 5586, 5589, 5592, 5595, 5598, 5601, 5604, 5607, 5610, 5613, 5614, 5617, 5620, + 5623, 5626, 5629, 5632, 5635, 5638 + ], + { "depth": 30, "slug": 5485, "text": 5473 }, + "design-spec-investigation-mindmap", + { "depth": 33, "slug": 5487, "text": 5488 }, + "1-three-layer-architecture", + "1. Three-Layer Architecture", + { "depth": 79, "slug": 5490, "text": 5491 }, + "layer-boundaries", + "Layer Boundaries", + { "depth": 33, "slug": 5493, "text": 5494 }, + "2-investigation-mindmap--three-modes", + "2. Investigation Mindmap — Three Modes", + { "depth": 79, "slug": 5496, "text": 5497 }, + "mode-progressive-disclosure", + "Mode Progressive Disclosure", + { "depth": 79, "slug": 5499, "text": 5500 }, + "drilldown-mode", + "Drilldown Mode", + { "depth": 79, "slug": 5502, "text": 5503 }, + "interaction-mode", + "Interaction Mode", + { "depth": 79, "slug": 5505, "text": 5506 }, + "narrative-mode", + "Narrative Mode", + { "depth": 79, "slug": 5508, "text": 5509 }, + "mode-switch-interaction", + "Mode Switch Interaction", + { "depth": 33, "slug": 5511, "text": 5512 }, + "3-what-the-mindmap-replaces", + "3. What the Mindmap Replaces", + { "depth": 79, "slug": 5514, "text": 5515 }, + "element-by-element-replacement-map", + "Element-by-Element Replacement Map", + { "depth": 79, "slug": 5517, "text": 5518 }, + "what-gets-explicitly-removed", + "What Gets Explicitly Removed", + { "depth": 79, "slug": 5520, "text": 5521 }, + "net-effect", + "Net Effect", + { "depth": 33, "slug": 5523, "text": 5524 }, + "4-whatifsimulator-as-separate-page", + "4. WhatIfSimulator as Separate Page", + { "depth": 79, "slug": 2527, "text": 2528 }, + { "depth": 79, "slug": 5527, "text": 5528 }, + "access-pattern", + "Access Pattern", + { "depth": 33, "slug": 5530, "text": 5531 }, + "5-statistical-foundation", + "5. Statistical Foundation", + { "depth": 79, "slug": 5533, "text": 5534 }, + "existing-η-for-node-sizing-and-drill-ranking", + "Existing: η² for Node Sizing and Drill Ranking", + { "depth": 79, "slug": 5536, "text": 5537 }, + "existing-regression-for-interaction-edges", + "Existing: Regression for Interaction Edges", + { "depth": 79, "slug": 5539, "text": 5540 }, + "new-infrastructure-drill-path-recording", + "New Infrastructure: Drill-Path Recording", + { "depth": 33, "slug": 5542, "text": 5543 }, + "6-platform-strategy--pwa-and-azure-only", + "6. Platform Strategy — PWA and Azure Only", + { "depth": 79, "slug": 5545, "text": 5546 }, + "pwa", + "PWA", + { "depth": 79, "slug": 5548, "text": 5549 }, + "azure", + "Azure", + { "depth": 79, "slug": 5551, "text": 5552 }, + "excel-add-in--explicitly-excluded", + "Excel Add-in — Explicitly Excluded", + { "depth": 79, "slug": 5554, "text": 5555 }, + "export-by-platform", + "Export by Platform", + { "depth": 33, "slug": 5557, "text": 5558 }, + "7-progressive-disclosure-design", + "7. Progressive Disclosure Design", + { "depth": 79, "slug": 5560, "text": 5561 }, + "disclosure-levels", + "Disclosure Levels", + { "depth": 79, "slug": 5563, "text": 5564 }, + "what-is-never-shown-simultaneously", + "What Is Never Shown Simultaneously", + { "depth": 79, "slug": 5566, "text": 5567 }, + "visual-hierarchy", + "Visual Hierarchy", + { "depth": 33, "slug": 5569, "text": 5570 }, + "8-demo-walkthrough--pizza-delivery-with-mindmap-ux", + "8. Demo Walkthrough — Pizza Delivery with Mindmap UX", + { "depth": 79, "slug": 5572, "text": 5573 }, + "step-1-data-loaded", + "Step 1: Data Loaded", + { "depth": 79, "slug": 5575, "text": 5576 }, + "step-2-analyst-drills-store-south", + "Step 2: Analyst Drills Store South", + { "depth": 79, "slug": 5578, "text": 5579 }, + "step-3-analyst-drills-time_slot-dinner", + "Step 3: Analyst Drills Time_Slot Dinner", + { "depth": 79, "slug": 5581, "text": 5582 }, + "step-4-analyst-checks-interactions", + "Step 4: Analyst Checks Interactions", + { "depth": 79, "slug": 5584, "text": 5585 }, + "step-5-analyst-decides-to-stop", + "Step 5: Analyst Decides to Stop", + { "depth": 79, "slug": 5587, "text": 5588 }, + "step-6-narrative-mode--communication", + "Step 6: Narrative Mode — Communication", + { "depth": 33, "slug": 5590, "text": 5591 }, + "9-competitive-positioning", + "9. Competitive Positioning", + { "depth": 79, "slug": 5593, "text": 5594 }, + "what-competitors-offer", + "What Competitors Offer", + { "depth": 79, "slug": 5596, "text": 5597 }, + "variscouts-unique-position", + "VariScout’s Unique Position", + { "depth": 33, "slug": 5599, "text": 5600 }, + "10-design-questions-for-uiux-phase", + "10. Design Questions for UI/UX Phase", + { "depth": 79, "slug": 5602, "text": 5603 }, + "node-layout", + "Node Layout", + { "depth": 79, "slug": 5605, "text": 5606 }, + "mode-switch", + "Mode Switch", + { "depth": 79, "slug": 5608, "text": 5609 }, + "click-popover", + "Click-Popover", + { "depth": 79, "slug": 5611, "text": 5612 }, + "mobile", + "Mobile", + { "depth": 79, "slug": 1278, "text": 1279 }, + { "depth": 33, "slug": 5615, "text": 5616 }, + "11-design-thinking-history", + "11. Design Thinking History", + { "depth": 33, "slug": 5618, "text": 5619 }, + "12-implementation-phasing", + "12. Implementation Phasing", + { "depth": 79, "slug": 5621, "text": 5622 }, + "phase-a-infrastructure--drilldown-mode", + "Phase A: Infrastructure + Drilldown Mode", + { "depth": 79, "slug": 5624, "text": 5625 }, + "phase-b-interaction-mode", + "Phase B: Interaction Mode", + { "depth": 79, "slug": 5627, "text": 5628 }, + "phase-c-narrative-mode--whatifsimulator-separation", + "Phase C: Narrative Mode + WhatIfSimulator Separation", + { "depth": 79, "slug": 5630, "text": 5631 }, + "phase-d-polish--azure-enhancements", + "Phase D: Polish + Azure Enhancements", + { "depth": 79, "slug": 5633, "text": 5634 }, + "phase-dependencies", + "Phase Dependencies", + { "depth": 79, "slug": 5636, "text": 5637 }, + "what-this-phasing-subsumes", + "What This Phasing Subsumes", + { "depth": 33, "slug": 4342, "text": 4343 }, + [], + [], + { "title": 5473 }, + [], + "01-vision/evaluations/hospital-ward-flow-map", + { "id": 5643, "data": 5645, "body": 5650, "filePath": 5651, "digest": 5652, "rendered": 5653 }, + { + "title": 5646, + "editUrl": 16, + "head": 5647, + "template": 18, + "sidebar": 5648, + "pagefind": 16, + "draft": 20 + }, + "Investigation Flow Map: Hospital Ward (Aggregation Trap)", + [], + { "hidden": 20, "attrs": 5649 }, + {}, + "# Investigation Flow Map: Hospital Ward (Aggregation Trap)\n\n> A step-by-step walkthrough of a complete variation investigation using the Hospital Ward dataset, documenting what exists at each step, what guidance the analyst receives, and where gaps remain. Follows the [Pizza Delivery flow map](investigation-flow-map.md) format.\n\n---\n\n## Dataset: Hospital Ward Utilization\n\n- **Source**: `packages/data/src/samples/hospital-ward.ts`\n- **Outcome**: `Utilization_pct` (target: 75%, USL: 90%)\n- **Factors**: Time_Period (Night 22–06, Morning 7–13, Afternoon 14–16, Evening 17–21), Day_of_Week (Mon–Sun)\n- **Data generation**: 672 observations = 28 days x 24 hours. Night: mean=94, std=3 (crisis). Morning: mean=70, std=6. Afternoon: mean=48, std=6 (waste). Evening: mean=65, std=7. All clamped [35, 100].\n- **Expected story**: Time_Period dominates massively (multimodal distribution). Day_of_Week is weak. The overall mean (~69%) looks \"fine\" — but it hides a 94% crisis and a 48% waste reality. This is the textbook aggregation trap: an average of extremes that matches no individual's experience.\n\n---\n\n## Step 1: Data Loaded — The Misleading Dashboard\n\nThe analyst loads the Hospital Ward sample via `/?sample=hospital-ward`. The Dashboard renders the Four Lenses.\n\n**What the analyst sees:**\n\n- **I-Chart**: 672 hourly utilization values plotted sequentially. Very noisy — the chart is dense with points cycling between high and low values. Control limits are wide due to the mixed population. The overall pattern looks chaotic but \"centered.\"\n- **Boxplot**: Four groups for Time_Period (the first factor). Immediately striking: Night is high and tight (~94%), Afternoon is low (~48%), Morning and Evening are in between. The boxes barely overlap.\n- **Pareto**: Ranked by out-of-spec frequency against the 90% USL.\n- **Stats Panel**: Overall mean ~69%, std dev ~16–18%, n=672. With the 90% USL, overall Cpk is modest. With the 75% target, the mean looks \"close enough.\"\n\n**Existing guidance at this step:**\n\n- Boxplot shows **\"↓ drill here\"** on the Time_Period group with the highest contribution to variation (likely Night, due to its extreme position).\n- VariationBar shows total variation scope.\n- The 4-group Boxplot immediately reveals the multimodal structure — this is the chart's strongest moment.\n\n**Gap — the overall mean is the lie, but nothing calls it out:**\nThe Stats Panel displays mean ~69%, which a manager would read as \"we're at 69%, target is 75%, we have room to improve.\" This sounds like a mild shortfall. But 69% is a mathematical fiction — it's the average of 94% (crisis) and 48% (waste), a number that describes nobody's actual experience. The product shows both the misleading mean and the revealing Boxplot on the same screen, but draws no connection between them. There is no \"your overall mean hides 4 different realities\" teaching callout.\n\n---\n\n## Step 2: Boxplot Reveals Four Realities\n\nThe analyst studies the Boxplot. Four Time_Period groups tell dramatically different stories.\n\n**What the analyst sees:**\n\n- **Night** (22:00–06:00): Box centered around ~94%. Very tight (std=3). The entire box sits near or above the 90% USL line. Crisis-level capacity.\n- **Morning** (07:00–13:00): Box centered around ~70%. Moderate spread (std=6). Comfortable operating range.\n- **Afternoon** (14:00–16:00): Box centered around ~48%. Moderate spread (std=6). Dramatically underutilized — waste.\n- **Evening** (17:00–21:00): Box centered around ~65%. Wider spread (std=7). Below target.\n- The boxes barely overlap. Time_Period's contribution % is very high (likely >60%).\n- The \"↓ drill here\" label appears on the highest-contribution group.\n\n**Existing guidance at this step:**\n\n- \"↓ drill here\" with contribution % identifies the dominant factor.\n- ANOVA (in maximized view) shows Time_Period is overwhelmingly significant.\n- The visual separation of the four boxes is itself the primary guidance — the multimodal structure is unmistakable.\n\n**Gap — no \"aggregation trap\" teaching callout:**\nThe Boxplot reveals the structure brilliantly — four non-overlapping boxes are a textbook sign that the overall average is meaningless. But the product doesn't name this pattern. There is no \"These four groups don't overlap — the overall mean of 69% represents none of them\" annotation. The aggregation trap is the entire teaching point of this dataset, yet the product relies on the analyst recognizing it themselves.\n\n---\n\n## Step 3: Click Night — The Crisis\n\nThe analyst clicks the Night group in the Boxplot. The dashboard filters to Night observations only.\n\n**What the analyst sees:**\n\n- **I-Chart**: ~252 data points (9 hours/day x 28 days). Remarkably stable — all values clustered tightly around 94%. The process is \"in control\" at a dangerously high level. Some points touch or exceed the 90% USL.\n- **Boxplot**: Now shows Day_of_Week groups within Night (7 groups: Mon–Sun).\n- **Stats Panel**: Mean ~94%, std dev ~3%, n ~252. Pass rate against 90% USL is low — many observations exceed the spec limit.\n- **FilterBreadcrumb**: A chip appears: **\"Time_Period: Night XX%\"** — showing a very high contribution percentage.\n- **VariationBar**: Updates to show substantial explained variation.\n\n**Existing guidance at this step:**\n\n- Filter chip with high contribution % confirms Night is the dominant source.\n- The I-Chart's stability at ~94% is visually striking — the problem isn't random spikes, it's the entire operating level.\n- Pass rate against USL drops dramatically, making the crisis concrete.\n\n**Gap — no \"above USL\" emphasis at the subgroup level:**\nThe overall dataset had a mix of pass/fail against the 90% USL. But Night's mean is ~94% — nearly every observation is at or above the limit. The pass rate stat updates, but there is no explicit callout like \"During Night hours, average utilization exceeds your 90% capacity limit.\" The connection between the filtered stats and operational risk (patient safety, staff burnout) is left to the analyst.\n\n---\n\n## Step 4: Day_of_Week within Night — Every Day\n\nThe analyst examines the Boxplot showing Mon–Sun within Night.\n\n**What the analyst sees:**\n\n- **Boxplot**: Seven boxes (Mon–Sun), all clustered around ~94% with similar spread. No day stands out. The crisis is chronic, not day-specific.\n- **\"↓ drill here\"** may appear on one day, but the contribution % is negligible.\n- **ANOVA** (if checked): Day_of_Week within Night has a low F-statistic and high p-value. Day explains essentially zero variation within Night.\n\n**Existing guidance at this step:**\n\n- Low contribution % signals this factor isn't helpful.\n- ANOVA confirms Day_of_Week is not significant within Night.\n- The visual uniformity of the seven boxes tells the story.\n\n**Gap — no \"chronic problem\" confirmation:**\nThe analyst has discovered that Night's crisis happens every day, not just weekends or specific days. This is an important operational finding — it means the solution must be systemic (staffing model, admission scheduling), not targeted (e.g., \"add Sunday night coverage\"). But the product doesn't synthesize this. There is no \"Day_of_Week explains \u003C2% of Night variation — the crisis is every night\" summary.\n\n---\n\n## Step 5: Backtrack, Click Afternoon — The Waste\n\nThe analyst removes the Night filter and clicks the Afternoon group in the Boxplot.\n\n**What the analyst sees:**\n\n- **I-Chart**: ~84 data points (3 hours/day x 28 days). Stable at a dramatically different level — values cluster around ~48%. The process is \"in control\" at severe underutilization.\n- **Boxplot**: Shows Day_of_Week within Afternoon. Similar pattern to Night — no day stands out.\n- **Stats Panel**: Mean ~48%, std dev ~6%, n ~84. Far below the 75% target. The opposite problem from Night.\n- **FilterBreadcrumb**: \"Time_Period: Afternoon XX%\".\n\n**Existing guidance at this step:**\n\n- The stats panel clearly shows the low mean.\n- Filter chip with contribution %.\n\n**Gap — no connection between Night and Afternoon:**\nThe analyst has now seen 94% (Night) and 48% (Afternoon). The arithmetic is compelling: (94 + 48) / 2 ≈ 71% — close to the \"overall 69%\" the dashboard showed. But the product doesn't draw this connection. There is no \"Night's 94% and Afternoon's 48% average to the 69% your dashboard showed — but neither group experiences 69%\" callout. The aggregation trap demonstration requires the analyst to do the mental arithmetic themselves.\n\n---\n\n## Step 6: Return to Full View — The Lying Dashboard\n\nThe analyst removes the Afternoon filter to return to the full 672-point dataset.\n\n**What the analyst sees:**\n\n- Overall stats restored: mean ~69%, std dev ~16–18%, n=672.\n- The same Boxplot showing four non-overlapping groups.\n- ANOVA confirming Time_Period's dominance.\n- The overall mean of ~69% — the number that started this investigation — looks innocuous again.\n\n**Existing guidance at this step:**\n\n- ANOVA provides statistical confirmation.\n- The Boxplot structure remains visible and revealing.\n- Contribution % on the \"↓ drill here\" label quantifies Time_Period's importance.\n\n**Gap — no \"before and after understanding\" contrast:**\nThe analyst now knows that \"69% average\" is a fiction. But the dashboard looks exactly the same as when they started. There is no visual marker of the analyst's changed understanding. No \"you've now seen that this 69% mean hides a 94% crisis (Night) and 48% waste (Afternoon)\" summary. The investigation has transformed the analyst's understanding, but the product's display is unchanged.\n\n---\n\n## Step 7: Investigation Complete — Aggregation Trap Revealed\n\nThe investigation concludes with the core insight: **\"Night: 94% (crisis). Afternoon: 48% (waste). The dashboard showed 69%. The average lied.\"**\n\n**What the analyst should take away:**\n\n- The overall 69% utilization looks acceptable but describes nobody's reality.\n- Night shifts consistently operate at 94% — above the 90% USL, meaning patient safety risk and staff burnout.\n- Afternoon shifts operate at 48% — severe underutilization representing wasted capacity and staffing cost.\n- The solution is flex staffing by time period, not uniform cuts or additions.\n- Reducing night staff (the management proposal based on \"75% target, 69% actual = spare capacity\") would create a patient safety crisis.\n- The I-Chart of the full dataset showed \"noise\" that was actually signal — the cycling between high and low values _was_ the time-of-day pattern.\n\n**Existing guidance at this step:**\n\n- None — the product provides no investigation conclusion or narrative summary.\n\n**Gap — no aggregation trap lesson:**\nThis dataset exists specifically to teach the aggregation trap — the most common statistical fallacy in management dashboards. Yet the product never names the pattern, never draws the connection between the overall mean and the subgroup means, and never provides the operational implication. The teaching arc is: \"Your dashboard showed 75%. Your nurses said something is wrong. Who's right? Both — but the dashboard is hiding the structure.\" The product supports the analysis but doesn't deliver the lesson.\n\n---\n\n## Summary: Guidance Coverage by Step\n\n| Step | Description | Existing Guidance | Gaps |\n| ---- | --------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------- |\n| 1 | Data loaded | Boxplot \"↓ drill here\", VariationBar | Overall mean ~69% looks \"fine\" — no warning it's meaningless |\n| 2 | Boxplot reveals 4 realities | \"↓ drill here\" with contribution %, ANOVA | No \"aggregation trap\" teaching callout for non-overlapping boxes |\n| 3 | Drill into Night | Filter chip with high %, I-Chart shows stability at ~94% | No \"above USL\" emphasis for the subgroup |\n| 4 | Day_of_Week within Night | Low contribution %, ANOVA not significant | No \"chronic problem\" confirmation |\n| 5 | Backtrack, drill Afternoon | Stats show low mean (~48%) | No connection drawn to Night — (94+48)/2 ≈ 69% is invisible |\n| 6 | Return to full view | ANOVA confirms Time_Period dominant | No summary of what was found vs initial perception |\n| 7 | Investigation complete | (none) | No aggregation trap lesson or operational recommendation |\n\n---\n\n## Key Takeaways for Design\n\n1. **The Boxplot immediately reveals the multimodal structure** — four non-overlapping boxes are visually unmistakable. This dataset validates the Boxplot as the primary investigation chart. The analyst doesn't need to be told something is wrong — they can see it.\n\n2. **The overall mean is the enemy** — it's the single number that enables the management mistake. The Stats Panel shows it prominently, and nothing in the UI warns that it's misleading when the Boxplot shows non-overlapping groups. Detecting and flagging multimodal distributions would be the highest-impact guidance addition.\n\n3. **The Night-to-Afternoon comparison is the \"aha\" moment** — but sequential drilling loses it. The analyst sees 94% in one drill and 48% in another, but never on the same screen. The arithmetic (94+48)/2 ≈ 69% is the punch line, but it requires mental math across drill states.\n\n4. **Cpk/pass rate changes dramatically per subgroup** — overall pass rate against 90% USL is moderate, but Night's pass rate is terrible. The Stats Panel updates correctly per filter, but there's no visual comparison of subgroup pass rates. A \"pass rate by Time_Period\" view would make the operational risk concrete.\n\n5. **This is the most common dashboard lie in practice** — every hospital, factory, and call center has this pattern. The aggregation trap is not an edge case; it's the default failure mode of summary dashboards. Making VariScout explicitly name and teach this pattern would be a significant competitive differentiator.\n\n---\n\n## Related Documents\n\n- [Hospital Ward Case Study](../../04-cases/hospital-ward/index.md) — Teaching narrative and dataset description\n- [Pizza Delivery Flow Map](investigation-flow-map.md) — Template this document follows\n- [Bottleneck Flow Map](bottleneck-flow-map.md) — Companion flow map demonstrating variation vs mean\n- [Progressive Stratification](../progressive-stratification.md) — Theoretical framework for drill-down methodology", + "src/content/docs/01-vision/evaluations/hospital-ward-flow-map.md", + "1476d7cba3ecfdbd", + { "html": 5654, "metadata": 5655 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"investigation-flow-map-hospital-ward-aggregation-trap\">Investigation Flow Map: Hospital Ward (Aggregation Trap)\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-flow-map-hospital-ward-aggregation-trap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation Flow Map: Hospital Ward (Aggregation Trap)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>A step-by-step walkthrough of a complete variation investigation using the Hospital Ward dataset, documenting what exists at each step, what guidance the analyst receives, and where gaps remain. Follows the \u003Ca href=\"investigation-flow-map.md\">Pizza Delivery flow map\u003C/a> format.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dataset-hospital-ward-utilization\">Dataset: Hospital Ward Utilization\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dataset-hospital-ward-utilization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dataset: Hospital Ward Utilization”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Source\u003C/strong>: \u003Ccode dir=\"auto\">packages/data/src/samples/hospital-ward.ts\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Outcome\u003C/strong>: \u003Ccode dir=\"auto\">Utilization_pct\u003C/code> (target: 75%, USL: 90%)\u003C/li>\n\u003Cli>\u003Cstrong>Factors\u003C/strong>: Time_Period (Night 22–06, Morning 7–13, Afternoon 14–16, Evening 17–21), Day_of_Week (Mon–Sun)\u003C/li>\n\u003Cli>\u003Cstrong>Data generation\u003C/strong>: 672 observations = 28 days x 24 hours. Night: mean=94, std=3 (crisis). Morning: mean=70, std=6. Afternoon: mean=48, std=6 (waste). Evening: mean=65, std=7. All clamped [35, 100].\u003C/li>\n\u003Cli>\u003Cstrong>Expected story\u003C/strong>: Time_Period dominates massively (multimodal distribution). Day_of_Week is weak. The overall mean (~69%) looks “fine” — but it hides a 94% crisis and a 48% waste reality. This is the textbook aggregation trap: an average of extremes that matches no individual’s experience.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-1-data-loaded--the-misleading-dashboard\">Step 1: Data Loaded — The Misleading Dashboard\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-data-loaded--the-misleading-dashboard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Data Loaded — The Misleading Dashboard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst loads the Hospital Ward sample via \u003Ccode dir=\"auto\">/?sample=hospital-ward\u003C/code>. The Dashboard renders the Four Lenses.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: 672 hourly utilization values plotted sequentially. Very noisy — the chart is dense with points cycling between high and low values. Control limits are wide due to the mixed population. The overall pattern looks chaotic but “centered.”\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Four groups for Time_Period (the first factor). Immediately striking: Night is high and tight (~94%), Afternoon is low (~48%), Morning and Evening are in between. The boxes barely overlap.\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong>: Ranked by out-of-spec frequency against the 90% USL.\u003C/li>\n\u003Cli>\u003Cstrong>Stats Panel\u003C/strong>: Overall mean ~69%, std dev ~16–18%, n=672. With the 90% USL, overall Cpk is modest. With the 75% target, the mean looks “close enough.”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Boxplot shows \u003Cstrong>”↓ drill here”\u003C/strong> on the Time_Period group with the highest contribution to variation (likely Night, due to its extreme position).\u003C/li>\n\u003Cli>VariationBar shows total variation scope.\u003C/li>\n\u003Cli>The 4-group Boxplot immediately reveals the multimodal structure — this is the chart’s strongest moment.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — the overall mean is the lie, but nothing calls it out:\u003C/strong>\nThe Stats Panel displays mean ~69%, which a manager would read as “we’re at 69%, target is 75%, we have room to improve.” This sounds like a mild shortfall. But 69% is a mathematical fiction — it’s the average of 94% (crisis) and 48% (waste), a number that describes nobody’s actual experience. The product shows both the misleading mean and the revealing Boxplot on the same screen, but draws no connection between them. There is no “your overall mean hides 4 different realities” teaching callout.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-2-boxplot-reveals-four-realities\">Step 2: Boxplot Reveals Four Realities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-boxplot-reveals-four-realities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Boxplot Reveals Four Realities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst studies the Boxplot. Four Time_Period groups tell dramatically different stories.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Night\u003C/strong> (22:00–06:00): Box centered around ~94%. Very tight (std=3). The entire box sits near or above the 90% USL line. Crisis-level capacity.\u003C/li>\n\u003Cli>\u003Cstrong>Morning\u003C/strong> (07:00–13:00): Box centered around ~70%. Moderate spread (std=6). Comfortable operating range.\u003C/li>\n\u003Cli>\u003Cstrong>Afternoon\u003C/strong> (14:00–16:00): Box centered around ~48%. Moderate spread (std=6). Dramatically underutilized — waste.\u003C/li>\n\u003Cli>\u003Cstrong>Evening\u003C/strong> (17:00–21:00): Box centered around ~65%. Wider spread (std=7). Below target.\u003C/li>\n\u003Cli>The boxes barely overlap. Time_Period’s contribution % is very high (likely >60%).\u003C/li>\n\u003Cli>The ”↓ drill here” label appears on the highest-contribution group.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>”↓ drill here” with contribution % identifies the dominant factor.\u003C/li>\n\u003Cli>ANOVA (in maximized view) shows Time_Period is overwhelmingly significant.\u003C/li>\n\u003Cli>The visual separation of the four boxes is itself the primary guidance — the multimodal structure is unmistakable.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no “aggregation trap” teaching callout:\u003C/strong>\nThe Boxplot reveals the structure brilliantly — four non-overlapping boxes are a textbook sign that the overall average is meaningless. But the product doesn’t name this pattern. There is no “These four groups don’t overlap — the overall mean of 69% represents none of them” annotation. The aggregation trap is the entire teaching point of this dataset, yet the product relies on the analyst recognizing it themselves.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-3-click-night--the-crisis\">Step 3: Click Night — The Crisis\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-click-night--the-crisis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Click Night — The Crisis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst clicks the Night group in the Boxplot. The dashboard filters to Night observations only.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: ~252 data points (9 hours/day x 28 days). Remarkably stable — all values clustered tightly around 94%. The process is “in control” at a dangerously high level. Some points touch or exceed the 90% USL.\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Now shows Day_of_Week groups within Night (7 groups: Mon–Sun).\u003C/li>\n\u003Cli>\u003Cstrong>Stats Panel\u003C/strong>: Mean ~94%, std dev ~3%, n ~252. Pass rate against 90% USL is low — many observations exceed the spec limit.\u003C/li>\n\u003Cli>\u003Cstrong>FilterBreadcrumb\u003C/strong>: A chip appears: \u003Cstrong>“Time_Period: Night XX%”\u003C/strong> — showing a very high contribution percentage.\u003C/li>\n\u003Cli>\u003Cstrong>VariationBar\u003C/strong>: Updates to show substantial explained variation.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Filter chip with high contribution % confirms Night is the dominant source.\u003C/li>\n\u003Cli>The I-Chart’s stability at ~94% is visually striking — the problem isn’t random spikes, it’s the entire operating level.\u003C/li>\n\u003Cli>Pass rate against USL drops dramatically, making the crisis concrete.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no “above USL” emphasis at the subgroup level:\u003C/strong>\nThe overall dataset had a mix of pass/fail against the 90% USL. But Night’s mean is ~94% — nearly every observation is at or above the limit. The pass rate stat updates, but there is no explicit callout like “During Night hours, average utilization exceeds your 90% capacity limit.” The connection between the filtered stats and operational risk (patient safety, staff burnout) is left to the analyst.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-4-day_of_week-within-night--every-day\">Step 4: Day_of_Week within Night — Every Day\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-day_of_week-within-night--every-day\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Day_of_Week within Night — Every Day”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst examines the Boxplot showing Mon–Sun within Night.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Seven boxes (Mon–Sun), all clustered around ~94% with similar spread. No day stands out. The crisis is chronic, not day-specific.\u003C/li>\n\u003Cli>\u003Cstrong>”↓ drill here”\u003C/strong> may appear on one day, but the contribution % is negligible.\u003C/li>\n\u003Cli>\u003Cstrong>ANOVA\u003C/strong> (if checked): Day_of_Week within Night has a low F-statistic and high p-value. Day explains essentially zero variation within Night.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Low contribution % signals this factor isn’t helpful.\u003C/li>\n\u003Cli>ANOVA confirms Day_of_Week is not significant within Night.\u003C/li>\n\u003Cli>The visual uniformity of the seven boxes tells the story.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no “chronic problem” confirmation:\u003C/strong>\nThe analyst has discovered that Night’s crisis happens every day, not just weekends or specific days. This is an important operational finding — it means the solution must be systemic (staffing model, admission scheduling), not targeted (e.g., “add Sunday night coverage”). But the product doesn’t synthesize this. There is no “Day_of_Week explains <2% of Night variation — the crisis is every night” summary.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-5-backtrack-click-afternoon--the-waste\">Step 5: Backtrack, Click Afternoon — The Waste\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-backtrack-click-afternoon--the-waste\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Backtrack, Click Afternoon — The Waste”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst removes the Night filter and clicks the Afternoon group in the Boxplot.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: ~84 data points (3 hours/day x 28 days). Stable at a dramatically different level — values cluster around ~48%. The process is “in control” at severe underutilization.\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Shows Day_of_Week within Afternoon. Similar pattern to Night — no day stands out.\u003C/li>\n\u003Cli>\u003Cstrong>Stats Panel\u003C/strong>: Mean ~48%, std dev ~6%, n ~84. Far below the 75% target. The opposite problem from Night.\u003C/li>\n\u003Cli>\u003Cstrong>FilterBreadcrumb\u003C/strong>: “Time_Period: Afternoon XX%”.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>The stats panel clearly shows the low mean.\u003C/li>\n\u003Cli>Filter chip with contribution %.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no connection between Night and Afternoon:\u003C/strong>\nThe analyst has now seen 94% (Night) and 48% (Afternoon). The arithmetic is compelling: (94 + 48) / 2 ≈ 71% — close to the “overall 69%” the dashboard showed. But the product doesn’t draw this connection. There is no “Night’s 94% and Afternoon’s 48% average to the 69% your dashboard showed — but neither group experiences 69%” callout. The aggregation trap demonstration requires the analyst to do the mental arithmetic themselves.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-6-return-to-full-view--the-lying-dashboard\">Step 6: Return to Full View — The Lying Dashboard\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-6-return-to-full-view--the-lying-dashboard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 6: Return to Full View — The Lying Dashboard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst removes the Afternoon filter to return to the full 672-point dataset.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Overall stats restored: mean ~69%, std dev ~16–18%, n=672.\u003C/li>\n\u003Cli>The same Boxplot showing four non-overlapping groups.\u003C/li>\n\u003Cli>ANOVA confirming Time_Period’s dominance.\u003C/li>\n\u003Cli>The overall mean of ~69% — the number that started this investigation — looks innocuous again.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>ANOVA provides statistical confirmation.\u003C/li>\n\u003Cli>The Boxplot structure remains visible and revealing.\u003C/li>\n\u003Cli>Contribution % on the ”↓ drill here” label quantifies Time_Period’s importance.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no “before and after understanding” contrast:\u003C/strong>\nThe analyst now knows that “69% average” is a fiction. But the dashboard looks exactly the same as when they started. There is no visual marker of the analyst’s changed understanding. No “you’ve now seen that this 69% mean hides a 94% crisis (Night) and 48% waste (Afternoon)” summary. The investigation has transformed the analyst’s understanding, but the product’s display is unchanged.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-7-investigation-complete--aggregation-trap-revealed\">Step 7: Investigation Complete — Aggregation Trap Revealed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-7-investigation-complete--aggregation-trap-revealed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 7: Investigation Complete — Aggregation Trap Revealed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The investigation concludes with the core insight: \u003Cstrong>“Night: 94% (crisis). Afternoon: 48% (waste). The dashboard showed 69%. The average lied.”\u003C/strong>\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst should take away:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>The overall 69% utilization looks acceptable but describes nobody’s reality.\u003C/li>\n\u003Cli>Night shifts consistently operate at 94% — above the 90% USL, meaning patient safety risk and staff burnout.\u003C/li>\n\u003Cli>Afternoon shifts operate at 48% — severe underutilization representing wasted capacity and staffing cost.\u003C/li>\n\u003Cli>The solution is flex staffing by time period, not uniform cuts or additions.\u003C/li>\n\u003Cli>Reducing night staff (the management proposal based on “75% target, 69% actual = spare capacity”) would create a patient safety crisis.\u003C/li>\n\u003Cli>The I-Chart of the full dataset showed “noise” that was actually signal — the cycling between high and low values \u003Cem>was\u003C/em> the time-of-day pattern.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>None — the product provides no investigation conclusion or narrative summary.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no aggregation trap lesson:\u003C/strong>\nThis dataset exists specifically to teach the aggregation trap — the most common statistical fallacy in management dashboards. Yet the product never names the pattern, never draws the connection between the overall mean and the subgroup means, and never provides the operational implication. The teaching arc is: “Your dashboard showed 75%. Your nurses said something is wrong. Who’s right? Both — but the dashboard is hiding the structure.” The product supports the analysis but doesn’t deliver the lesson.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"summary-guidance-coverage-by-step\">Summary: Guidance Coverage by Step\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#summary-guidance-coverage-by-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Summary: Guidance Coverage by Step”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Step\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Existing Guidance\u003C/th>\u003Cth>Gaps\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Data loaded\u003C/td>\u003Ctd>Boxplot ”↓ drill here”, VariationBar\u003C/td>\u003Ctd>Overall mean ~69% looks “fine” — no warning it’s meaningless\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Boxplot reveals 4 realities\u003C/td>\u003Ctd>”↓ drill here” with contribution %, ANOVA\u003C/td>\u003Ctd>No “aggregation trap” teaching callout for non-overlapping boxes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Drill into Night\u003C/td>\u003Ctd>Filter chip with high %, I-Chart shows stability at ~94%\u003C/td>\u003Ctd>No “above USL” emphasis for the subgroup\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Day_of_Week within Night\u003C/td>\u003Ctd>Low contribution %, ANOVA not significant\u003C/td>\u003Ctd>No “chronic problem” confirmation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Backtrack, drill Afternoon\u003C/td>\u003Ctd>Stats show low mean (~48%)\u003C/td>\u003Ctd>No connection drawn to Night — (94+48)/2 ≈ 69% is invisible\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Return to full view\u003C/td>\u003Ctd>ANOVA confirms Time_Period dominant\u003C/td>\u003Ctd>No summary of what was found vs initial perception\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>Investigation complete\u003C/td>\u003Ctd>(none)\u003C/td>\u003Ctd>No aggregation trap lesson or operational recommendation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-takeaways-for-design\">Key Takeaways for Design\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-takeaways-for-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Takeaways for Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>The Boxplot immediately reveals the multimodal structure\u003C/strong> — four non-overlapping boxes are visually unmistakable. This dataset validates the Boxplot as the primary investigation chart. The analyst doesn’t need to be told something is wrong — they can see it.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>The overall mean is the enemy\u003C/strong> — it’s the single number that enables the management mistake. The Stats Panel shows it prominently, and nothing in the UI warns that it’s misleading when the Boxplot shows non-overlapping groups. Detecting and flagging multimodal distributions would be the highest-impact guidance addition.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>The Night-to-Afternoon comparison is the “aha” moment\u003C/strong> — but sequential drilling loses it. The analyst sees 94% in one drill and 48% in another, but never on the same screen. The arithmetic (94+48)/2 ≈ 69% is the punch line, but it requires mental math across drill states.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Cpk/pass rate changes dramatically per subgroup\u003C/strong> — overall pass rate against 90% USL is moderate, but Night’s pass rate is terrible. The Stats Panel updates correctly per filter, but there’s no visual comparison of subgroup pass rates. A “pass rate by Time_Period” view would make the operational risk concrete.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>This is the most common dashboard lie in practice\u003C/strong> — every hospital, factory, and call center has this pattern. The aggregation trap is not an edge case; it’s the default failure mode of summary dashboards. Making VariScout explicitly name and teach this pattern would be a significant competitive differentiator.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documents\">Related Documents\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documents\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documents”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../04-cases/hospital-ward/index.md\">Hospital Ward Case Study\u003C/a> — Teaching narrative and dataset description\u003C/li>\n\u003Cli>\u003Ca href=\"investigation-flow-map.md\">Pizza Delivery Flow Map\u003C/a> — Template this document follows\u003C/li>\n\u003Cli>\u003Ca href=\"bottleneck-flow-map.md\">Bottleneck Flow Map\u003C/a> — Companion flow map demonstrating variation vs mean\u003C/li>\n\u003Cli>\u003Ca href=\"../progressive-stratification.md\">Progressive Stratification\u003C/a> — Theoretical framework for drill-down methodology\u003C/li>\n\u003C/ul>", + { + "headings": 5656, + "localImagePaths": 5686, + "remoteImagePaths": 5687, + "frontmatter": 5688, + "imagePaths": 5689 + }, + [5657, 5659, 5662, 5665, 5668, 5671, 5674, 5677, 5680, 5683, 5684, 5685], + { "depth": 30, "slug": 5658, "text": 5646 }, + "investigation-flow-map-hospital-ward-aggregation-trap", + { "depth": 33, "slug": 5660, "text": 5661 }, + "dataset-hospital-ward-utilization", + "Dataset: Hospital Ward Utilization", + { "depth": 33, "slug": 5663, "text": 5664 }, + "step-1-data-loaded--the-misleading-dashboard", + "Step 1: Data Loaded — The Misleading Dashboard", + { "depth": 33, "slug": 5666, "text": 5667 }, + "step-2-boxplot-reveals-four-realities", + "Step 2: Boxplot Reveals Four Realities", + { "depth": 33, "slug": 5669, "text": 5670 }, + "step-3-click-night--the-crisis", + "Step 3: Click Night — The Crisis", + { "depth": 33, "slug": 5672, "text": 5673 }, + "step-4-day_of_week-within-night--every-day", + "Step 4: Day_of_Week within Night — Every Day", + { "depth": 33, "slug": 5675, "text": 5676 }, + "step-5-backtrack-click-afternoon--the-waste", + "Step 5: Backtrack, Click Afternoon — The Waste", + { "depth": 33, "slug": 5678, "text": 5679 }, + "step-6-return-to-full-view--the-lying-dashboard", + "Step 6: Return to Full View — The Lying Dashboard", + { "depth": 33, "slug": 5681, "text": 5682 }, + "step-7-investigation-complete--aggregation-trap-revealed", + "Step 7: Investigation Complete — Aggregation Trap Revealed", + { "depth": 33, "slug": 5373, "text": 5374 }, + { "depth": 33, "slug": 5376, "text": 5377 }, + { "depth": 33, "slug": 4342, "text": 4343 }, + [], + [], + { "title": 5646 }, + [], + "01-vision/evaluations", + { "id": 5690, "data": 5692, "body": 5697, "filePath": 5698, "digest": 5699, "rendered": 5700 }, + { + "title": 5693, + "editUrl": 16, + "head": 5694, + "template": 18, + "sidebar": 5695, + "pagefind": 16, + "draft": 20 + }, + "Evaluations: Progressive Stratification Tensions & Patterns", + [], + { "hidden": 20, "attrs": 5696 }, + {}, + "# Evaluations: Progressive Stratification Tensions & Patterns\n\nProduct strategy evaluations for the design tensions and alternative patterns identified in [Progressive Stratification](../progressive-stratification.md) Part 2. Each evaluation assesses fit against VariScout's philosophy, personas, and competitive positioning.\n\n---\n\n## Summary Matrix\n\n### Tensions\n\n| Tension | Strategic Weight | Primary Personas Affected | Key Insight |\n| -------------------------------------------------------- | ---------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------- |\n| [Hierarchy Assumption](tensions/hierarchy-assumption.md) | **High** | Gary, Olivia | Interaction effects are common in real processes; the one-factor drill-down may miss them. |\n| [Discoverability](tensions/discoverability.md) | **High** | Gary, Carlos | The drill-down is both the primary differentiator and the hardest feature to find. |\n| [Factor Ordering](tensions/factor-ordering.md) | **Medium** | Gary, Sara | Analysts may not read eta-squared as navigation guidance without explicit prompting. |\n| [When to Stop](tensions/when-to-stop.md) | **Medium** | Sara, Olivia | Statistical isolation doesn't guarantee operational actionability. |\n| [Mobile Screen Budget](tensions/mobile-screen-budget.md) | **Medium** | Sara, Carlos | Filter state and chart content compete for limited mobile viewport. |\n| [Path Dependency](tensions/path-dependency.md) | **Low** | Sara | Intermediate numbers differ by drill order, but final results converge. Correct behavior, potentially confusing. |\n\n### Patterns\n\n| Pattern | Verdict | Tensions Addressed | Philosophy Fit |\n| ---------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------- | -------------------------------- |\n| [Factor Suggestion](patterns/factor-suggestion.md) | **Pursue** | Factor Ordering, Discoverability, When to Stop | Good (if optional/subtle) |\n| [Interaction Heatmap](patterns/interaction-heatmap.md) | **Pursue** | Hierarchy Assumption, Factor Ordering | Strong |\n| [Parallel Path Comparison](patterns/parallel-path-comparison.md) | **Defer** | Path Dependency, Hierarchy Assumption | Good |\n| [Auto-Combination Finder](patterns/auto-combination-finder.md) | **Defer** | Hierarchy Assumption, Factor Ordering, Path Dependency | Mixed (conflicts with pedagogy) |\n| [Small Multiples](patterns/small-multiples.md) | **Defer** | Factor Ordering, Path Dependency | Good (scaling limits) |\n| [Factor Map](patterns/factor-map.md) | **Defer** | All 5 non-mobile tensions | Strong (high complexity) |\n| [Investigation Mindmap](patterns/investigation-mindmap.md) | **Primary** (replaces Funnel) | Hierarchy Assumption, Discoverability, Factor Ordering, Path Dependency | Strong (lighter Factor Map) |\n| [Investigation Narrative](patterns/investigation-narrative.md) | **Primary** (absorbed into Mindmap) | When to Stop, Path Dependency, Discoverability | Strong |\n| [Sidebar Filter Panel](patterns/sidebar-filter-panel.md) | **Reject** | Discoverability | Poor (undermines differentiator) |\n\n---\n\n## Crosswalk: Which Patterns Address Which Tensions\n\n| | Factor Suggestion | Interaction Heatmap | Parallel Path | Auto-Combination | Small Multiples | Factor Map | Inv. Mindmap | Inv. Narrative | Sidebar Panel |\n| ------------------------ | ----------------- | ------------------- | ------------- | ---------------- | --------------- | ----------- | ------------ | -------------- | ------------- |\n| **Hierarchy Assumption** | | **primary** | secondary | **primary** | | **primary** | **primary** | | |\n| **Discoverability** | secondary | | | | | secondary | secondary | secondary | **primary** |\n| **Factor Ordering** | **primary** | secondary | | **primary** | partial | **primary** | **primary** | | |\n| **When to Stop** | secondary | | | | | | | **primary** | |\n| **Mobile Screen Budget** | | | | | worsens | improves | improves | | worsens |\n| **Path Dependency** | | | **primary** | **primary** | partial | **primary** | secondary | secondary | |\n\n**Legend**: **primary** = directly resolves the tension. secondary = partially addresses. partial = helps for some cases. worsens = makes the tension worse.\n\n---\n\n## Recommended Sequence\n\nThe Investigation Mindmap consolidates Factor Suggestion, Interaction Heatmap, and Investigation Narrative into one three-mode component that replaces the Funnel Panel. Implementation is phased by mode:\n\n1. **Phase A: Drilldown Mode** — Replaces the Funnel Panel with a spatial investigation view. Factor nodes sized by η², drill trail, suggested-next pulsing, click-to-filter popovers. Subsumes Factor Suggestion (the suggested-next node provides the same guidance). New infrastructure: `useDrillPath` hook, Mindmap SVG component.\n2. **Phase B: Interaction Mode** — Adds edges between factor nodes showing interaction strength (ΔR²) and significance. Subsumes Interaction Heatmap (visual edges replace the standalone heatmap). New infrastructure: `getInteractionStrength()` helper in `@variscout/core`.\n3. **Phase C: Narrative Mode + WhatIfSimulator separation** — Reorganizes nodes into a timeline for stakeholder communication. Step annotations, interaction cross-connections, conclusion panel, PNG export. WhatIfSimulator moves to standalone `/whatif` route.\n4. **Phase D: Polish + Azure enhancements** — Split-pane option (Azure, viewport > 1280px), annotations (Azure: OneDrive-synced; PWA: session-only), SVG export (Azure), \"Model improvements\" → WhatIfSimulator link.\n\nEach phase builds on the previous: B needs A's nodes, C needs A's drill trail + B's edges, D needs all three modes complete. See [Design Spec §12](design-spec-investigation-mindmap.md#12-implementation-phasing) for full infrastructure prerequisites and reuse mapping.\n\nThe sidebar filter panel is rejected as incompatible with VariScout's core differentiator. The auto-combination finder is deferred to the Azure App only, as it conflicts with the PWA's educational mission. Parallel Path Comparison, Small Multiples, and Factor Map are deferred — the Mindmap addresses the tensions they targeted through consolidation rather than additional surfaces.\n\n---\n\n## Methodology\n\nEach evaluation uses a consistent template:\n\n- **Tension files**: The tension described, persona impact assessment (6 personas), current mitigation, strategic weight, and related patterns.\n- **Pattern files**: The concept described, tensions addressed, philosophy alignment (EDA, Sock Mystery, Four Lenses, Two Voices), persona impact, platform fit (PWA/Azure/Excel), competitive landscape, and strategic verdict.\n\nContent is seeded from [Progressive Stratification](../progressive-stratification.md) Part 2 and expanded with assessments drawn from [persona definitions](../../02-journeys/personas/) and [product philosophy](../philosophy.md).\n\n---\n\n## Design Preparation\n\nPre-design deliverables that bridge the gap between competitive intelligence and actionable UI/UX design work.\n\n| Document | Purpose |\n| -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| [Design Spec: Investigation Mindmap](design-spec-investigation-mindmap.md) | **Authoritative spec.** Three-layer architecture (Chart/Navigation/Investigation), three Mindmap modes (Drilldown/Interaction/Narrative), Funnel Panel replacement mapping, progressive disclosure design. |\n| [Design Brief](design-brief-guided-investigation.md) | Historical: competitive intelligence → statistical methodology → existing UI audit → design principles → design questions for the UI/UX phase. |\n| [Investigation Flow Map](investigation-flow-map.md) | Historical: step-by-step walkthrough of a complete investigation using the Pizza Delivery dataset. Documents existing guidance at each step and identifies gaps. The Design Spec Section 8 provides the updated \"after\" walkthrough. |\n| [Bottleneck Flow Map](bottleneck-flow-map.md) | UX flow evaluation: 7-step bottleneck detection journey using the Bottleneck dataset. Demonstrates \"variation > mean\" — Step 2's high variance vs Step 3's high average. E2E tests: `apps/pwa/e2e/bottleneck-investigation.spec.ts`. |\n| [Hospital Ward Flow Map](hospital-ward-flow-map.md) | UX flow evaluation: 7-step aggregation trap discovery using the Hospital Ward dataset. Night 94% crisis + Afternoon 48% waste hidden behind 69% average. E2E tests: `apps/pwa/e2e/hospital-ward-investigation.spec.ts`. |\n| [Mindmap Chrome Evaluation](mindmap-chrome-evaluation.md) | Automated Playwright evaluation of the Mindmap panel with both datasets. Finds contribution metric misleads for dispersion scenarios (Step 2 = 0%), no dead-end signal, and CategoryPopover's pre-drill contrast is the key success. |\n\nThe [Design Spec](design-spec-investigation-mindmap.md) is the authoritative design document for the Investigation Mindmap feature. It consolidates the Design Brief's statistical methodology, the Flow Map's step-by-step scenario, the Investigation Mindmap's two-mode concept (elevated to three modes), and the Investigation Narrative (absorbed as the Mindmap's third mode) into a single implementable specification. The Design Brief and Flow Map are retained as historical design thinking.\n\n---\n\n## Competitive Intelligence\n\n| Document | Summary |\n| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| [EDAScout Benchmark](competitive/edascout-benchmark.md) | Technical assessment of EDAScout v4/v6/v7/v9 --- architecture, statistics quality, AI rollback arc, and strategic implications. Based on direct codebase analysis. |\n| [Minitab Benchmark](competitive/minitab-benchmark.md) | Industry-standard desktop SPC tool (~$1,700/year). Deep feature set, menu-driven workflow, no linked filtering or progressive drill-down. |\n| [JMP Benchmark](competitive/jmp-benchmark.md) | SAS visual analytics platform ($1,785+/year). Strongest EDA heritage (Graph Builder), but model-first for factor analysis. Closest philosophical competitor. |\n| [Tableau Benchmark](competitive/tableau-benchmark.md) | Dominant BI platform ($75/user/month). Defines the sidebar filter paradigm VariScout rejects. No SPC capabilities. |\n| [Power BI Benchmark](competitive/powerbi-benchmark.md) | Microsoft enterprise BI ($10/user/month). Slicer paradigm, no native SPC. Key Influencers visual provides ML-based factor ranking. |\n| [Minor Competitors](competitive/minor-competitors.md) | Brief profiles of SigmaXL (Excel add-in, stepwise regression) and Looker (Google BI, filter bar pattern). |\n\nEDAScout is the closest conceptual competitor to VariScout (browser-based variation analysis for quality professionals). The EDAScout benchmark is based on direct codebase analysis across four versions and maps findings to the tension/pattern framework above. Key takeaways: EDAScout's AI guidance was added in v6, completely rolled back in v7, and restored in v9 --- validating VariScout's methodology-driven approach. Their statistical implementation has critical flaws (hardcoded p-value buckets, misleading within-group SS metric) that VariScout's correct eta-squared and proper F-distribution calculations avoid.\n\nThe four major competitor benchmarks (Minitab, JMP, Tableau, Power BI) are based on public documentation and published feature sets, not codebase analysis. Each document maps the competitor's capabilities to VariScout's 6 tension framework and identifies strategic differentiation points. The consistent finding across all competitors: no tool combines linked filtering, progressive stratification, and statistical variation quantification into a unified investigation workflow.", + "src/content/docs/01-vision/evaluations/index.md", + "53a4c26caa91a503", + { "html": 5701, "metadata": 5702 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"evaluations-progressive-stratification-tensions--patterns\">Evaluations: Progressive Stratification Tensions & Patterns\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#evaluations-progressive-stratification-tensions--patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Evaluations: Progressive Stratification Tensions & Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Product strategy evaluations for the design tensions and alternative patterns identified in \u003Ca href=\"../progressive-stratification.md\">Progressive Stratification\u003C/a> Part 2. Each evaluation assesses fit against VariScout’s philosophy, personas, and competitive positioning.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"summary-matrix\">Summary Matrix\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#summary-matrix\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Summary Matrix”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tensions\">Tensions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tensions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tensions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tension\u003C/th>\u003Cth>Strategic Weight\u003C/th>\u003Cth>Primary Personas Affected\u003C/th>\u003Cth>Key Insight\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"tensions/hierarchy-assumption.md\">Hierarchy Assumption\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>High\u003C/strong>\u003C/td>\u003Ctd>Gary, Olivia\u003C/td>\u003Ctd>Interaction effects are common in real processes; the one-factor drill-down may miss them.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"tensions/discoverability.md\">Discoverability\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>High\u003C/strong>\u003C/td>\u003Ctd>Gary, Carlos\u003C/td>\u003Ctd>The drill-down is both the primary differentiator and the hardest feature to find.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"tensions/factor-ordering.md\">Factor Ordering\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Medium\u003C/strong>\u003C/td>\u003Ctd>Gary, Sara\u003C/td>\u003Ctd>Analysts may not read eta-squared as navigation guidance without explicit prompting.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"tensions/when-to-stop.md\">When to Stop\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Medium\u003C/strong>\u003C/td>\u003Ctd>Sara, Olivia\u003C/td>\u003Ctd>Statistical isolation doesn’t guarantee operational actionability.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"tensions/mobile-screen-budget.md\">Mobile Screen Budget\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Medium\u003C/strong>\u003C/td>\u003Ctd>Sara, Carlos\u003C/td>\u003Ctd>Filter state and chart content compete for limited mobile viewport.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"tensions/path-dependency.md\">Path Dependency\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Low\u003C/strong>\u003C/td>\u003Ctd>Sara\u003C/td>\u003Ctd>Intermediate numbers differ by drill order, but final results converge. Correct behavior, potentially confusing.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"patterns\">Patterns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Patterns”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>Verdict\u003C/th>\u003Cth>Tensions Addressed\u003C/th>\u003Cth>Philosophy Fit\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/factor-suggestion.md\">Factor Suggestion\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Pursue\u003C/strong>\u003C/td>\u003Ctd>Factor Ordering, Discoverability, When to Stop\u003C/td>\u003Ctd>Good (if optional/subtle)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/interaction-heatmap.md\">Interaction Heatmap\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Pursue\u003C/strong>\u003C/td>\u003Ctd>Hierarchy Assumption, Factor Ordering\u003C/td>\u003Ctd>Strong\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/parallel-path-comparison.md\">Parallel Path Comparison\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Defer\u003C/strong>\u003C/td>\u003Ctd>Path Dependency, Hierarchy Assumption\u003C/td>\u003Ctd>Good\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/auto-combination-finder.md\">Auto-Combination Finder\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Defer\u003C/strong>\u003C/td>\u003Ctd>Hierarchy Assumption, Factor Ordering, Path Dependency\u003C/td>\u003Ctd>Mixed (conflicts with pedagogy)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/small-multiples.md\">Small Multiples\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Defer\u003C/strong>\u003C/td>\u003Ctd>Factor Ordering, Path Dependency\u003C/td>\u003Ctd>Good (scaling limits)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/factor-map.md\">Factor Map\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Defer\u003C/strong>\u003C/td>\u003Ctd>All 5 non-mobile tensions\u003C/td>\u003Ctd>Strong (high complexity)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/investigation-mindmap.md\">Investigation Mindmap\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Primary\u003C/strong> (replaces Funnel)\u003C/td>\u003Ctd>Hierarchy Assumption, Discoverability, Factor Ordering, Path Dependency\u003C/td>\u003Ctd>Strong (lighter Factor Map)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/investigation-narrative.md\">Investigation Narrative\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Primary\u003C/strong> (absorbed into Mindmap)\u003C/td>\u003Ctd>When to Stop, Path Dependency, Discoverability\u003C/td>\u003Ctd>Strong\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"patterns/sidebar-filter-panel.md\">Sidebar Filter Panel\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Reject\u003C/strong>\u003C/td>\u003Ctd>Discoverability\u003C/td>\u003Ctd>Poor (undermines differentiator)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"crosswalk-which-patterns-address-which-tensions\">Crosswalk: Which Patterns Address Which Tensions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#crosswalk-which-patterns-address-which-tensions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Crosswalk: Which Patterns Address Which Tensions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>\u003C/th>\u003Cth>Factor Suggestion\u003C/th>\u003Cth>Interaction Heatmap\u003C/th>\u003Cth>Parallel Path\u003C/th>\u003Cth>Auto-Combination\u003C/th>\u003Cth>Small Multiples\u003C/th>\u003Cth>Factor Map\u003C/th>\u003Cth>Inv. Mindmap\u003C/th>\u003Cth>Inv. Narrative\u003C/th>\u003Cth>Sidebar Panel\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Hierarchy Assumption\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>secondary\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Discoverability\u003C/strong>\u003C/td>\u003Ctd>secondary\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>secondary\u003C/td>\u003Ctd>secondary\u003C/td>\u003Ctd>secondary\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Factor Ordering\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>secondary\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>partial\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>When to Stop\u003C/strong>\u003C/td>\u003Ctd>secondary\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mobile Screen Budget\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>worsens\u003C/td>\u003Ctd>improves\u003C/td>\u003Ctd>improves\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>worsens\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Path Dependency\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>partial\u003C/td>\u003Ctd>\u003Cstrong>primary\u003C/strong>\u003C/td>\u003Ctd>secondary\u003C/td>\u003Ctd>secondary\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Legend\u003C/strong>: \u003Cstrong>primary\u003C/strong> = directly resolves the tension. secondary = partially addresses. partial = helps for some cases. worsens = makes the tension worse.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"recommended-sequence\">Recommended Sequence\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#recommended-sequence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Recommended Sequence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Investigation Mindmap consolidates Factor Suggestion, Interaction Heatmap, and Investigation Narrative into one three-mode component that replaces the Funnel Panel. Implementation is phased by mode:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Phase A: Drilldown Mode\u003C/strong> — Replaces the Funnel Panel with a spatial investigation view. Factor nodes sized by η², drill trail, suggested-next pulsing, click-to-filter popovers. Subsumes Factor Suggestion (the suggested-next node provides the same guidance). New infrastructure: \u003Ccode dir=\"auto\">useDrillPath\u003C/code> hook, Mindmap SVG component.\u003C/li>\n\u003Cli>\u003Cstrong>Phase B: Interaction Mode\u003C/strong> — Adds edges between factor nodes showing interaction strength (ΔR²) and significance. Subsumes Interaction Heatmap (visual edges replace the standalone heatmap). New infrastructure: \u003Ccode dir=\"auto\">getInteractionStrength()\u003C/code> helper in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>.\u003C/li>\n\u003Cli>\u003Cstrong>Phase C: Narrative Mode + WhatIfSimulator separation\u003C/strong> — Reorganizes nodes into a timeline for stakeholder communication. Step annotations, interaction cross-connections, conclusion panel, PNG export. WhatIfSimulator moves to standalone \u003Ccode dir=\"auto\">/whatif\u003C/code> route.\u003C/li>\n\u003Cli>\u003Cstrong>Phase D: Polish + Azure enhancements\u003C/strong> — Split-pane option (Azure, viewport > 1280px), annotations (Azure: OneDrive-synced; PWA: session-only), SVG export (Azure), “Model improvements” → WhatIfSimulator link.\u003C/li>\n\u003C/ol>\n\u003Cp>Each phase builds on the previous: B needs A’s nodes, C needs A’s drill trail + B’s edges, D needs all three modes complete. See \u003Ca href=\"design-spec-investigation-mindmap.md#12-implementation-phasing\">Design Spec §12\u003C/a> for full infrastructure prerequisites and reuse mapping.\u003C/p>\n\u003Cp>The sidebar filter panel is rejected as incompatible with VariScout’s core differentiator. The auto-combination finder is deferred to the Azure App only, as it conflicts with the PWA’s educational mission. Parallel Path Comparison, Small Multiples, and Factor Map are deferred — the Mindmap addresses the tensions they targeted through consolidation rather than additional surfaces.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"methodology\">Methodology\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#methodology\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Methodology”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each evaluation uses a consistent template:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Tension files\u003C/strong>: The tension described, persona impact assessment (6 personas), current mitigation, strategic weight, and related patterns.\u003C/li>\n\u003Cli>\u003Cstrong>Pattern files\u003C/strong>: The concept described, tensions addressed, philosophy alignment (EDA, Sock Mystery, Four Lenses, Two Voices), persona impact, platform fit (PWA/Azure/Excel), competitive landscape, and strategic verdict.\u003C/li>\n\u003C/ul>\n\u003Cp>Content is seeded from \u003Ca href=\"../progressive-stratification.md\">Progressive Stratification\u003C/a> Part 2 and expanded with assessments drawn from \u003Ca href=\"../../02-journeys/personas/\">persona definitions\u003C/a> and \u003Ca href=\"../philosophy.md\">product philosophy\u003C/a>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"design-preparation\">Design Preparation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#design-preparation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Preparation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pre-design deliverables that bridge the gap between competitive intelligence and actionable UI/UX design work.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Document\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"design-spec-investigation-mindmap.md\">Design Spec: Investigation Mindmap\u003C/a>\u003C/td>\u003Ctd>\u003Cstrong>Authoritative spec.\u003C/strong> Three-layer architecture (Chart/Navigation/Investigation), three Mindmap modes (Drilldown/Interaction/Narrative), Funnel Panel replacement mapping, progressive disclosure design.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"design-brief-guided-investigation.md\">Design Brief\u003C/a>\u003C/td>\u003Ctd>Historical: competitive intelligence → statistical methodology → existing UI audit → design principles → design questions for the UI/UX phase.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"investigation-flow-map.md\">Investigation Flow Map\u003C/a>\u003C/td>\u003Ctd>Historical: step-by-step walkthrough of a complete investigation using the Pizza Delivery dataset. Documents existing guidance at each step and identifies gaps. The Design Spec Section 8 provides the updated “after” walkthrough.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"bottleneck-flow-map.md\">Bottleneck Flow Map\u003C/a>\u003C/td>\u003Ctd>UX flow evaluation: 7-step bottleneck detection journey using the Bottleneck dataset. Demonstrates “variation > mean” — Step 2’s high variance vs Step 3’s high average. E2E tests: \u003Ccode dir=\"auto\">apps/pwa/e2e/bottleneck-investigation.spec.ts\u003C/code>.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"hospital-ward-flow-map.md\">Hospital Ward Flow Map\u003C/a>\u003C/td>\u003Ctd>UX flow evaluation: 7-step aggregation trap discovery using the Hospital Ward dataset. Night 94% crisis + Afternoon 48% waste hidden behind 69% average. E2E tests: \u003Ccode dir=\"auto\">apps/pwa/e2e/hospital-ward-investigation.spec.ts\u003C/code>.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"mindmap-chrome-evaluation.md\">Mindmap Chrome Evaluation\u003C/a>\u003C/td>\u003Ctd>Automated Playwright evaluation of the Mindmap panel with both datasets. Finds contribution metric misleads for dispersion scenarios (Step 2 = 0%), no dead-end signal, and CategoryPopover’s pre-drill contrast is the key success.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The \u003Ca href=\"design-spec-investigation-mindmap.md\">Design Spec\u003C/a> is the authoritative design document for the Investigation Mindmap feature. It consolidates the Design Brief’s statistical methodology, the Flow Map’s step-by-step scenario, the Investigation Mindmap’s two-mode concept (elevated to three modes), and the Investigation Narrative (absorbed as the Mindmap’s third mode) into a single implementable specification. The Design Brief and Flow Map are retained as historical design thinking.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-intelligence\">Competitive Intelligence\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-intelligence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Intelligence”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Document\u003C/th>\u003Cth>Summary\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"competitive/edascout-benchmark.md\">EDAScout Benchmark\u003C/a>\u003C/td>\u003Ctd>Technical assessment of EDAScout v4/v6/v7/v9 --- architecture, statistics quality, AI rollback arc, and strategic implications. Based on direct codebase analysis.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"competitive/minitab-benchmark.md\">Minitab Benchmark\u003C/a>\u003C/td>\u003Ctd>Industry-standard desktop SPC tool (~$1,700/year). Deep feature set, menu-driven workflow, no linked filtering or progressive drill-down.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"competitive/jmp-benchmark.md\">JMP Benchmark\u003C/a>\u003C/td>\u003Ctd>SAS visual analytics platform ($1,785+/year). Strongest EDA heritage (Graph Builder), but model-first for factor analysis. Closest philosophical competitor.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"competitive/tableau-benchmark.md\">Tableau Benchmark\u003C/a>\u003C/td>\u003Ctd>Dominant BI platform ($75/user/month). Defines the sidebar filter paradigm VariScout rejects. No SPC capabilities.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"competitive/powerbi-benchmark.md\">Power BI Benchmark\u003C/a>\u003C/td>\u003Ctd>Microsoft enterprise BI ($10/user/month). Slicer paradigm, no native SPC. Key Influencers visual provides ML-based factor ranking.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"competitive/minor-competitors.md\">Minor Competitors\u003C/a>\u003C/td>\u003Ctd>Brief profiles of SigmaXL (Excel add-in, stepwise regression) and Looker (Google BI, filter bar pattern).\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>EDAScout is the closest conceptual competitor to VariScout (browser-based variation analysis for quality professionals). The EDAScout benchmark is based on direct codebase analysis across four versions and maps findings to the tension/pattern framework above. Key takeaways: EDAScout’s AI guidance was added in v6, completely rolled back in v7, and restored in v9 --- validating VariScout’s methodology-driven approach. Their statistical implementation has critical flaws (hardcoded p-value buckets, misleading within-group SS metric) that VariScout’s correct eta-squared and proper F-distribution calculations avoid.\u003C/p>\n\u003Cp>The four major competitor benchmarks (Minitab, JMP, Tableau, Power BI) are based on public documentation and published feature sets, not codebase analysis. Each document maps the competitor’s capabilities to VariScout’s 6 tension framework and identifies strategic differentiation points. The consistent finding across all competitors: no tool combines linked filtering, progressive stratification, and statistical variation quantification into a unified investigation workflow.\u003C/p>", + { + "headings": 5703, + "localImagePaths": 5726, + "remoteImagePaths": 5727, + "frontmatter": 5728, + "imagePaths": 5729 + }, + [5704, 5706, 5709, 5712, 5713, 5716, 5719, 5720, 5723], + { "depth": 30, "slug": 5705, "text": 5693 }, + "evaluations-progressive-stratification-tensions--patterns", + { "depth": 33, "slug": 5707, "text": 5708 }, + "summary-matrix", + "Summary Matrix", + { "depth": 79, "slug": 5710, "text": 5711 }, + "tensions", + "Tensions", + { "depth": 79, "slug": 2005, "text": 2006 }, + { "depth": 33, "slug": 5714, "text": 5715 }, + "crosswalk-which-patterns-address-which-tensions", + "Crosswalk: Which Patterns Address Which Tensions", + { "depth": 33, "slug": 5717, "text": 5718 }, + "recommended-sequence", + "Recommended Sequence", + { "depth": 33, "slug": 563, "text": 564 }, + { "depth": 33, "slug": 5721, "text": 5722 }, + "design-preparation", + "Design Preparation", + { "depth": 33, "slug": 5724, "text": 5725 }, + "competitive-intelligence", + "Competitive Intelligence", + [], + [], + { "title": 5693 }, + [], + "01-vision/evaluations/investigation-flow-map", + { "id": 5730, "data": 5732, "body": 5737, "filePath": 5738, "digest": 5739, "rendered": 5740 }, + { + "title": 5733, + "editUrl": 16, + "head": 5734, + "template": 18, + "sidebar": 5735, + "pagefind": 16, + "draft": 20 + }, + "Investigation Flow Map: Pizza Delivery", + [], + { "hidden": 20, "attrs": 5736 }, + {}, + "# Investigation Flow Map: Pizza Delivery\n\n> **Historical document** — describes the pre-Mindmap investigation flow using FunnelPanel.\n> See [design-spec-investigation-mindmap.md](./design-spec-investigation-mindmap.md) for the current implementation.\n\n> A step-by-step walkthrough of a complete variation investigation using the Pizza Delivery dataset, documenting what exists at each step, what guidance the analyst receives, and where enhanced/new elements would improve the flow.\n\n---\n\n## Dataset: Pizza Delivery\n\n- **Source**: `packages/data/src/samples/pizza.ts`\n- **Outcome**: `Delivery_Time_min` (target: 30 min, USL: 45 min)\n- **Factors**: Store (3 levels: North, Central, South), Time_Slot (3: Lunch, Dinner, Late Night), Day (7: Mon–Sun)\n- **Data generation**: Store South has higher base mean (35 vs 28) and more variance (σ=8 vs σ=4). Dinner rush adds +5 min. Late Night subtracts −3 min. 252 observations (4 weeks × 7 days × 3 stores × 3 time slots).\n- **Expected η² hierarchy**: Store dominates (large mean shift + variance difference), Time_Slot moderate (rush penalty), Day weak (no systematic effect in generation code).\n\n---\n\n## Step 1: Data Loaded — Dashboard Shows Four Lenses\n\nThe analyst loads the Pizza Delivery sample. The Dashboard renders the Four Lenses: I-Chart, Boxplot, Pareto, and Stats Panel.\n\n**What the analyst sees:**\n\n- **I-Chart**: Individual delivery times plotted sequentially. Control limits (UCL/LCL) calculated from overall data. Some points above UCL, concentrated where Store South + Dinner overlap.\n- **Boxplot**: Three groups for the first factor (Store). Store South's box is wider and shifted higher than North and Central. The whiskers extend further.\n- **Pareto**: Ranked bar chart of out-of-spec frequency by Store.\n- **Stats Panel**: Overall mean, std dev, Cp/Cpk against the 45-min USL and 30-min target.\n\n**Existing guidance at this step:**\n\n- Boxplot shows **\"↓ drill here\"** in red text on the Store South bar (highest η²). (`Boxplot.tsx:389`)\n- No other suggestions visible unless the analyst opens the Funnel Panel.\n\n**Gap — no \"start here\" for first-time users:**\nThe Boxplot label says \"↓ drill here\" but doesn't explain _why_ Store South is highlighted or what drilling means. A first-time user (Student Sara) sees a red label but may not understand it as an invitation to filter. There is no onboarding prompt, no \"Your data has 3 factors — Store explains the most variation. Click a bar to investigate\" message.\n\n**What the Investigation Mindmap would show:**\nThree factor nodes (Store, Time_Slot, Day) sized by η². Store is the largest node. No drill path yet. If interactions are pre-scanned, faint connections between Store–Time_Slot (potential rush interaction) and Store–Day (probably negligible).\n\n**What competitors' users would do differently:**\n\n- _Minitab_: Choose Stat → ANOVA → One-Way from the menu, type in \"Store\" as the factor. No visual prompt.\n- _JMP_: Drag Delivery_Time onto Y and Store onto X in Graph Builder. No guidance on which variable to start with.\n- _Tableau_: Drag Store onto the filter shelf. No statistical ranking of factors.\n- _Power BI_: Add Store to a slicer. Or use Key Influencers, which would auto-rank factors but as a separate visual.\n\n---\n\n## Step 2: Analyst Clicks Store South — First Drill\n\nThe analyst clicks the Store South bar in the Boxplot (or selects Store = Store South from a dropdown). The dashboard filters to only Store South data.\n\n**What the analyst sees:**\n\n- **I-Chart**: Only Store South delivery times. The pattern is noisier (σ=8). Some high values clustered during Dinner time slots.\n- **Boxplot**: Now shows Time_Slot groups within Store South. Dinner bar is tallest/widest. Lunch is tightest.\n- **Pareto**: Ranked by Time_Slot within Store South.\n- **Stats Panel**: Store South statistics (mean ~35, higher std dev).\n- **FilterBreadcrumb**: A chip appears: **\"Store: South 45%\"** — indicating Store explains ~45% of total variation. The badge is green (≥50% threshold may not be hit; depends on actual η²; could be amber at ~40%).\n\n**Existing guidance at this step:**\n\n- FilterBreadcrumb shows **contribution %** badge on the Store chip. (`FilterBreadcrumb.tsx:272–297`)\n- Boxplot shows **\"↓ drill here\"** on the Dinner bar (highest η² among Time_Slot levels within the filtered data).\n- VariationBar updates to show cumulative explained variation.\n\n**Gap — no \"suggested next factor\" after first drill:**\nThe analyst sees the contribution % on the active filter and the \"↓ drill here\" on the next Boxplot. But there's no explicit prompt like \"Time_Slot explains 25% of remaining variation — try this next.\" The analyst must infer from the Boxplot label that Dinner is worth investigating.\n\n**What the Investigation Mindmap would show:**\nStore node is highlighted/filled (active filter). A trail leads from the center (start) to Store. Time_Slot and Day nodes are outlined (available). Time_Slot is larger than Day (higher η² on remaining data). The \"suggested next\" node (Time_Slot) pulses gently.\n\n---\n\n## Step 3: Analyst Opens Funnel Panel\n\nCurious about the investigation state, the analyst clicks the funnel icon in the header to open the Variation Funnel slide-out panel.\n\n**What the analyst sees:**\n\n- **Factor ranking**: Store (η² ~0.40), Time_Slot (η² ~0.20), Day (η² ~0.03). Visual bars show relative importance.\n- **\"Highest impact\" labels**: Store South highlighted as the best value for Store. Dinner highlighted for Time_Slot.\n- **\"Worst\" labels**: Store South marked with a red \"worst\" label (highest contribution to variation >20%). Dinner similarly marked for Time_Slot.\n- **Cumulative bar**: Shows ~40% explained so far (Store filter only).\n- **Inline Cpk badge**: On the Store South \"worst\" row, a badge shows what the Cpk would improve to if Store South's variation matched the other stores.\n- **Drill buttons**: Each factor row has a \"Drill →\" button next to the highest-impact value.\n\n**Existing guidance at this step:**\nThis is the richest guidance view in VariScout. Factor ranking, worst labels, Cpk badges, cumulative tracking, and drill actions are all present. (`VariationFunnel.tsx:96–767`)\n\n**Gap — the Funnel is hidden:**\nAll this guidance requires the analyst to explicitly open the Funnel Panel. A first-time user who doesn't know the funnel icon exists will never see the factor ranking, cumulative tracking, or Cpk badges. The Funnel Panel is a slide-out overlay — it covers the charts, so the analyst can't see the guidance and the data simultaneously.\n\n**What competitors' users would do differently:**\n\n- _Minitab_: No equivalent to the Funnel Panel. The analyst would run separate ANOVA analyses and compare p-values manually.\n- _JMP_: Effect Summary in Fit Model shows a ranked bar chart of effects, but only after fitting a model with all terms specified.\n- _Power BI_: Key Influencers visual auto-ranks factors, but it's a separate visual on the report canvas, not integrated with the filtering workflow.\n\n---\n\n## Step 4: Analyst Drills into Time_Slot — Second Drill\n\nThe analyst clicks Dinner in the Boxplot (or uses the \"Drill →\" button in the Funnel for Time_Slot = Dinner).\n\n**What the analyst sees:**\n\n- **I-Chart**: Store South, Dinner only. Tighter distribution (noise from non-Dinner slots removed).\n- **Boxplot**: Now shows Day groups within Store South + Dinner. Bars are relatively even (Day has low η²).\n- **FilterBreadcrumb**: Two chips: **\"Store: South 45%\"** and **\"Time_Slot: Dinner 25%\"**. The percentages show each factor's individual contribution.\n- **Stats Panel**: Filtered statistics for Store South × Dinner.\n\n**Existing guidance at this step:**\n\n- Two contribution % badges in the FilterBreadcrumb.\n- Boxplot \"↓ drill here\" on the highest-η² Day bar (likely weak signal).\n- VariationBar shows cumulative ~55–60% explained.\n- **InteractionGuidance appears**: With 2+ factors in the drill stack, the `InteractionGuidance` component renders: \"When factors interact (e.g., Store × Time_Slot), use the Regression Panel with 'Include interactions'.\" (`InteractionGuidance.tsx:26`)\n\n**Gap — interaction guidance is text-only:**\nThe InteractionGuidance component tells the analyst that interactions _might_ exist and where to check. But it doesn't show whether Store × Time_Slot actually interacts in this data. The analyst has to navigate to the Regression Panel, configure it with both factors, enable interactions, and read the results. This is exactly the \"separate seeing from acting\" anti-pattern.\n\n**What the Interaction Heatmap would show (Phase 2):**\nA compact 3×3 matrix (Store × Time_Slot × Day) with cells colored by interaction strength. The Store × Time_Slot cell might glow warm (moderate interaction — Store South's Dinner rush penalty is larger than other stores'). Store × Day and Time_Slot × Day cells would be cool/neutral (no interaction in the data generation). The heatmap would replace the text-only InteractionGuidance with visual evidence.\n\n**What the Investigation Mindmap would show:**\nStore and Time_Slot nodes are both filled (active filters). The drill trail runs Start → Store → Time_Slot. Day node is outlined but small (low η²). If the heatmap data is synced, the Store–Time_Slot edge glows to show the interaction. The analyst can see that the remaining factor (Day) is weak — a visual signal that further drilling has diminishing returns.\n\n---\n\n## Step 5: Analyst Considers Day — Diminishing Returns\n\nThe Boxplot shows Day bars that are roughly similar in height and position. The \"↓ drill here\" label is present but the η² is low (~0.03).\n\n**What the analyst sees:**\n\n- Relatively even Boxplot bars across Day groups.\n- The Funnel Panel (if open) shows Day with a small bar and ~3% η².\n- Cumulative explained variation is ~55–60% without Day.\n\n**Existing guidance at this step:**\n\n- Boxplot label still shows \"↓ drill here\" on the highest Day bar, even though the effect is tiny. The label doesn't distinguish between \"you should definitely drill here\" and \"this is the best of a weak set.\"\n- The Funnel Panel's cumulative bar shows the investigation is past the 50% mark but hasn't reached the 70% target.\n- No explicit \"Day is weak — you might want to stop\" prompt.\n\n**Gap — no stopping signal in the main view:**\nThe cumulative target (70%) lives only in the Funnel Panel. In the main dashboard, there's no visual signal that the investigation has reached a \"good enough\" point or that further drilling into Day would yield diminishing returns. The Boxplot \"↓ drill here\" label treats all factors equally — it doesn't convey \"this is a weak suggestion.\"\n\n**What a Factor Suggestion enhancement would do (Phase 1):**\nA suggestion chip near the Boxplot would read: \"Day explains ~3% of remaining variation. Consider stopping — you've explained 58% so far.\" Or simply: the suggestion chip would use muted styling (gray instead of blue) to signal that the recommendation is weak. This distinguishes a strong \"drill here\" from a weak \"you could drill here, but...\"\n\n---\n\n## Step 6: Analyst Checks Interactions via Regression Panel\n\nFollowing the InteractionGuidance prompt (or curiosity), the analyst navigates to the Regression Panel and selects Store and Time_Slot as predictors with \"Include interactions\" enabled.\n\n**What the analyst sees:**\n\n- Regression results with main effects (Store levels, Time_Slot levels) and interaction terms (Store × Time_Slot pairs).\n- R² for the main-effects-only model vs. the full model with interactions.\n- Individual coefficient p-values and standardized betas.\n- If the Pizza data has a meaningful Store × Time_Slot interaction, the interaction term's coefficient would be significant and the ΔR² would be noticeable.\n\n**Existing guidance at this step:**\n\n- The Regression Panel displays results clearly, with significant terms highlighted.\n- No explicit summary like \"interactions add 5% explanatory power\" or \"Store × Time_Slot is the strongest interaction.\"\n\n**Gap — results require interpretation:**\nThe regression output is a table of coefficients. The analyst must compare R² values mentally and scan the interaction terms to find significant ones. There is no visual summary (like the heatmap) and no ranking of interaction importance. For Green Belt Gary this is manageable; for Student Sara it's a barrier.\n\n**What the Interaction Heatmap would provide (Phase 2):**\nThe heatmap would pre-compute and visualize exactly this information: ΔR² for each factor pair, displayed as colored cells. The analyst wouldn't need to configure a regression — the heatmap would surface the \"Store × Time_Slot interaction is moderate\" finding proactively.\n\n---\n\n## Step 7: Investigation Complete — Stopping Point\n\nThe analyst has identified Store (specifically Store South) and Time_Slot (specifically Dinner rush) as the primary drivers of delivery time variation. Together they explain ~60% of variation. Day is negligible.\n\n**What the analyst sees:**\n\n- FilterBreadcrumb with two active filters and their contribution percentages.\n- If the Funnel Panel is open: cumulative bar at ~60%, short of the 70% target.\n- Stats Panel showing the filtered (Store South × Dinner) statistics vs. the overall statistics.\n\n**Existing guidance at this step:**\n\n- The Funnel Panel's cumulative bar turns green at 70%. At 60%, it's still amber.\n- No explicit \"investigation complete\" or \"you've found enough\" prompt.\n- No summary view of what was found.\n\n**Gap — no narrative summary:**\nThe investigation ends without ceremony. There's no \"you investigated 3 factors, found 2 significant ones, explained 60% of variation\" summary. The analyst must mentally reconstruct the investigation story for their report or team meeting.\n\n**What the Investigation Narrative would provide (Phase 3):**\nA presentation mode that transforms the investigation into a visual story: \"We started with 252 deliveries. Store South was the biggest driver (45% of variation). Within Store South, the Dinner rush added the most time (25% more). Together these explain 60% of delivery time variation. Recommended action: focus on Store South's Dinner operations.\"\n\n**What the Investigation Mindmap would show at this point:**\nThe drill trail is complete: Start → Store South → Time_Slot: Dinner. Two nodes filled, one dimmed (Day). The mindmap is a visual record of the investigation path. In Narrative mode, this becomes the stakeholder presentation.\n\n---\n\n## Summary: Guidance Coverage by Step\n\n| Step | Description | Existing Guidance | Gaps | Phase 1 (Factor Suggestion) | Phase 2 (Interaction Heatmap) | Phase 3 (Mindmap/Narrative) |\n| ---- | ------------------------ | ---------------------------------------- | ---------------------------------------- | ------------------------------------------------ | ------------------------------------------- | ---------------------------------------- |\n| 1 | Data loaded | Boxplot \"↓ drill here\" | No \"start here\" for novices | Add suggestion chip with η² value | — | Mindmap shows factor landscape |\n| 2 | First drill (Store) | Contribution %, Boxplot label | No \"suggested next factor\" | Suggestion chip: \"Try Time_Slot — 25% remaining\" | — | Drill trail begins |\n| 3 | Funnel opened | Rich: ranking, Cpk, cumulative | Funnel is hidden, covers charts | Surface key metrics in main view | — | Mindmap provides always-visible overview |\n| 4 | Second drill (Time_Slot) | Contribution %, InteractionGuidance | Interaction guidance is text-only | — | Heatmap shows Store × Time_Slot interaction | Mindmap shows interaction edges |\n| 5 | Consider Day (weak) | Boxplot label (no weak-signal indicator) | No diminishing returns signal | Muted suggestion styling for weak factors | — | Small/dim Day node signals weakness |\n| 6 | Check interactions | Regression coefficients table | Results require expert interpretation | — | Heatmap pre-computes and visualizes | — |\n| 7 | Investigation complete | Cumulative bar (if Funnel open) | No narrative summary, no stopping prompt | Stopping signal: \"You've explained X%\" | — | Narrative mode generates presentation |\n\n---\n\n## Key Takeaways for Design\n\n1. **The existing guidance is deeper than it appears** — the Funnel Panel ecosystem is rich. The problem is discoverability and platform parity, not capability.\n\n2. **Phase 1 (Factor Suggestion) has the highest impact per effort** — a suggestion chip in the main view surfaces the Funnel Panel's best insights without requiring the analyst to find and open it.\n\n3. **Phase 2 (Interaction Heatmap) replaces a two-step workaround** — currently the analyst sees a text prompt → navigates to Regression Panel → configures it → reads results. The heatmap collapses this into a glance.\n\n4. **Phase 3 (Mindmap/Narrative) addresses the end of the investigation** — everything from Steps 1–6 is about finding the answer. Step 7 reveals that VariScout has no support for communicating the answer.\n\n5. **The Pizza dataset works as a primary demo** — its 3-factor structure walks through all the guidance elements without being overwhelming. Store dominance → Time_Slot secondary → Day diminishing returns is a clean pedagogical arc.\n\n---\n\n## Related Documents\n\n- [Design Brief](design-brief-guided-investigation.md) — Statistical methodology and design principles\n- [Investigation Mindmap](patterns/investigation-mindmap.md) — Pattern evaluation for the companion view\n- [Investigation Narrative](patterns/investigation-narrative.md) — Pattern evaluation for presentation mode\n- [Factor Suggestion](patterns/factor-suggestion.md) — Phase 1 pattern evaluation\n- [Interaction Heatmap](patterns/interaction-heatmap.md) — Phase 2 pattern evaluation", + "src/content/docs/01-vision/evaluations/investigation-flow-map.md", + "57635427b327c736", + { "html": 5741, "metadata": 5742 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"investigation-flow-map-pizza-delivery\">Investigation Flow Map: Pizza Delivery\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-flow-map-pizza-delivery\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation Flow Map: Pizza Delivery”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Historical document\u003C/strong> — describes the pre-Mindmap investigation flow using FunnelPanel.\nSee \u003Ca href=\"./design-spec-investigation-mindmap.md\">design-spec-investigation-mindmap.md\u003C/a> for the current implementation.\u003C/p>\n\u003C/blockquote>\n\u003Cblockquote>\n\u003Cp>A step-by-step walkthrough of a complete variation investigation using the Pizza Delivery dataset, documenting what exists at each step, what guidance the analyst receives, and where enhanced/new elements would improve the flow.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dataset-pizza-delivery\">Dataset: Pizza Delivery\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dataset-pizza-delivery\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dataset: Pizza Delivery”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Source\u003C/strong>: \u003Ccode dir=\"auto\">packages/data/src/samples/pizza.ts\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Outcome\u003C/strong>: \u003Ccode dir=\"auto\">Delivery_Time_min\u003C/code> (target: 30 min, USL: 45 min)\u003C/li>\n\u003Cli>\u003Cstrong>Factors\u003C/strong>: Store (3 levels: North, Central, South), Time_Slot (3: Lunch, Dinner, Late Night), Day (7: Mon–Sun)\u003C/li>\n\u003Cli>\u003Cstrong>Data generation\u003C/strong>: Store South has higher base mean (35 vs 28) and more variance (σ=8 vs σ=4). Dinner rush adds +5 min. Late Night subtracts −3 min. 252 observations (4 weeks × 7 days × 3 stores × 3 time slots).\u003C/li>\n\u003Cli>\u003Cstrong>Expected η² hierarchy\u003C/strong>: Store dominates (large mean shift + variance difference), Time_Slot moderate (rush penalty), Day weak (no systematic effect in generation code).\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-1-data-loaded--dashboard-shows-four-lenses\">Step 1: Data Loaded — Dashboard Shows Four Lenses\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-data-loaded--dashboard-shows-four-lenses\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Data Loaded — Dashboard Shows Four Lenses”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst loads the Pizza Delivery sample. The Dashboard renders the Four Lenses: I-Chart, Boxplot, Pareto, and Stats Panel.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: Individual delivery times plotted sequentially. Control limits (UCL/LCL) calculated from overall data. Some points above UCL, concentrated where Store South + Dinner overlap.\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Three groups for the first factor (Store). Store South’s box is wider and shifted higher than North and Central. The whiskers extend further.\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong>: Ranked bar chart of out-of-spec frequency by Store.\u003C/li>\n\u003Cli>\u003Cstrong>Stats Panel\u003C/strong>: Overall mean, std dev, Cp/Cpk against the 45-min USL and 30-min target.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Boxplot shows \u003Cstrong>”↓ drill here”\u003C/strong> in red text on the Store South bar (highest η²). (\u003Ccode dir=\"auto\">Boxplot.tsx:389\u003C/code>)\u003C/li>\n\u003Cli>No other suggestions visible unless the analyst opens the Funnel Panel.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no “start here” for first-time users:\u003C/strong>\nThe Boxplot label says ”↓ drill here” but doesn’t explain \u003Cem>why\u003C/em> Store South is highlighted or what drilling means. A first-time user (Student Sara) sees a red label but may not understand it as an invitation to filter. There is no onboarding prompt, no “Your data has 3 factors — Store explains the most variation. Click a bar to investigate” message.\u003C/p>\n\u003Cp>\u003Cstrong>What the Investigation Mindmap would show:\u003C/strong>\nThree factor nodes (Store, Time_Slot, Day) sized by η². Store is the largest node. No drill path yet. If interactions are pre-scanned, faint connections between Store–Time_Slot (potential rush interaction) and Store–Day (probably negligible).\u003C/p>\n\u003Cp>\u003Cstrong>What competitors’ users would do differently:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cem>Minitab\u003C/em>: Choose Stat → ANOVA → One-Way from the menu, type in “Store” as the factor. No visual prompt.\u003C/li>\n\u003Cli>\u003Cem>JMP\u003C/em>: Drag Delivery_Time onto Y and Store onto X in Graph Builder. No guidance on which variable to start with.\u003C/li>\n\u003Cli>\u003Cem>Tableau\u003C/em>: Drag Store onto the filter shelf. No statistical ranking of factors.\u003C/li>\n\u003Cli>\u003Cem>Power BI\u003C/em>: Add Store to a slicer. Or use Key Influencers, which would auto-rank factors but as a separate visual.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-2-analyst-clicks-store-south--first-drill\">Step 2: Analyst Clicks Store South — First Drill\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-analyst-clicks-store-south--first-drill\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Analyst Clicks Store South — First Drill”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst clicks the Store South bar in the Boxplot (or selects Store = Store South from a dropdown). The dashboard filters to only Store South data.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: Only Store South delivery times. The pattern is noisier (σ=8). Some high values clustered during Dinner time slots.\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Now shows Time_Slot groups within Store South. Dinner bar is tallest/widest. Lunch is tightest.\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong>: Ranked by Time_Slot within Store South.\u003C/li>\n\u003Cli>\u003Cstrong>Stats Panel\u003C/strong>: Store South statistics (mean ~35, higher std dev).\u003C/li>\n\u003Cli>\u003Cstrong>FilterBreadcrumb\u003C/strong>: A chip appears: \u003Cstrong>“Store: South 45%”\u003C/strong> — indicating Store explains ~45% of total variation. The badge is green (≥50% threshold may not be hit; depends on actual η²; could be amber at ~40%).\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>FilterBreadcrumb shows \u003Cstrong>contribution %\u003C/strong> badge on the Store chip. (\u003Ccode dir=\"auto\">FilterBreadcrumb.tsx:272–297\u003C/code>)\u003C/li>\n\u003Cli>Boxplot shows \u003Cstrong>”↓ drill here”\u003C/strong> on the Dinner bar (highest η² among Time_Slot levels within the filtered data).\u003C/li>\n\u003Cli>VariationBar updates to show cumulative explained variation.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no “suggested next factor” after first drill:\u003C/strong>\nThe analyst sees the contribution % on the active filter and the ”↓ drill here” on the next Boxplot. But there’s no explicit prompt like “Time_Slot explains 25% of remaining variation — try this next.” The analyst must infer from the Boxplot label that Dinner is worth investigating.\u003C/p>\n\u003Cp>\u003Cstrong>What the Investigation Mindmap would show:\u003C/strong>\nStore node is highlighted/filled (active filter). A trail leads from the center (start) to Store. Time_Slot and Day nodes are outlined (available). Time_Slot is larger than Day (higher η² on remaining data). The “suggested next” node (Time_Slot) pulses gently.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-3-analyst-opens-funnel-panel\">Step 3: Analyst Opens Funnel Panel\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-analyst-opens-funnel-panel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Analyst Opens Funnel Panel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Curious about the investigation state, the analyst clicks the funnel icon in the header to open the Variation Funnel slide-out panel.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Factor ranking\u003C/strong>: Store (η² ~0.40), Time_Slot (η² ~0.20), Day (η² ~0.03). Visual bars show relative importance.\u003C/li>\n\u003Cli>\u003Cstrong>“Highest impact” labels\u003C/strong>: Store South highlighted as the best value for Store. Dinner highlighted for Time_Slot.\u003C/li>\n\u003Cli>\u003Cstrong>“Worst” labels\u003C/strong>: Store South marked with a red “worst” label (highest contribution to variation >20%). Dinner similarly marked for Time_Slot.\u003C/li>\n\u003Cli>\u003Cstrong>Cumulative bar\u003C/strong>: Shows ~40% explained so far (Store filter only).\u003C/li>\n\u003Cli>\u003Cstrong>Inline Cpk badge\u003C/strong>: On the Store South “worst” row, a badge shows what the Cpk would improve to if Store South’s variation matched the other stores.\u003C/li>\n\u003Cli>\u003Cstrong>Drill buttons\u003C/strong>: Each factor row has a “Drill →” button next to the highest-impact value.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\nThis is the richest guidance view in VariScout. Factor ranking, worst labels, Cpk badges, cumulative tracking, and drill actions are all present. (\u003Ccode dir=\"auto\">VariationFunnel.tsx:96–767\u003C/code>)\u003C/p>\n\u003Cp>\u003Cstrong>Gap — the Funnel is hidden:\u003C/strong>\nAll this guidance requires the analyst to explicitly open the Funnel Panel. A first-time user who doesn’t know the funnel icon exists will never see the factor ranking, cumulative tracking, or Cpk badges. The Funnel Panel is a slide-out overlay — it covers the charts, so the analyst can’t see the guidance and the data simultaneously.\u003C/p>\n\u003Cp>\u003Cstrong>What competitors’ users would do differently:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cem>Minitab\u003C/em>: No equivalent to the Funnel Panel. The analyst would run separate ANOVA analyses and compare p-values manually.\u003C/li>\n\u003Cli>\u003Cem>JMP\u003C/em>: Effect Summary in Fit Model shows a ranked bar chart of effects, but only after fitting a model with all terms specified.\u003C/li>\n\u003Cli>\u003Cem>Power BI\u003C/em>: Key Influencers visual auto-ranks factors, but it’s a separate visual on the report canvas, not integrated with the filtering workflow.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-4-analyst-drills-into-time_slot--second-drill\">Step 4: Analyst Drills into Time_Slot — Second Drill\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-analyst-drills-into-time_slot--second-drill\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Analyst Drills into Time_Slot — Second Drill”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst clicks Dinner in the Boxplot (or uses the “Drill →” button in the Funnel for Time_Slot = Dinner).\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong>: Store South, Dinner only. Tighter distribution (noise from non-Dinner slots removed).\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong>: Now shows Day groups within Store South + Dinner. Bars are relatively even (Day has low η²).\u003C/li>\n\u003Cli>\u003Cstrong>FilterBreadcrumb\u003C/strong>: Two chips: \u003Cstrong>“Store: South 45%”\u003C/strong> and \u003Cstrong>“Time_Slot: Dinner 25%”\u003C/strong>. The percentages show each factor’s individual contribution.\u003C/li>\n\u003Cli>\u003Cstrong>Stats Panel\u003C/strong>: Filtered statistics for Store South × Dinner.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Two contribution % badges in the FilterBreadcrumb.\u003C/li>\n\u003Cli>Boxplot ”↓ drill here” on the highest-η² Day bar (likely weak signal).\u003C/li>\n\u003Cli>VariationBar shows cumulative ~55–60% explained.\u003C/li>\n\u003Cli>\u003Cstrong>InteractionGuidance appears\u003C/strong>: With 2+ factors in the drill stack, the \u003Ccode dir=\"auto\">InteractionGuidance\u003C/code> component renders: “When factors interact (e.g., Store × Time_Slot), use the Regression Panel with ‘Include interactions’.” (\u003Ccode dir=\"auto\">InteractionGuidance.tsx:26\u003C/code>)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — interaction guidance is text-only:\u003C/strong>\nThe InteractionGuidance component tells the analyst that interactions \u003Cem>might\u003C/em> exist and where to check. But it doesn’t show whether Store × Time_Slot actually interacts in this data. The analyst has to navigate to the Regression Panel, configure it with both factors, enable interactions, and read the results. This is exactly the “separate seeing from acting” anti-pattern.\u003C/p>\n\u003Cp>\u003Cstrong>What the Interaction Heatmap would show (Phase 2):\u003C/strong>\nA compact 3×3 matrix (Store × Time_Slot × Day) with cells colored by interaction strength. The Store × Time_Slot cell might glow warm (moderate interaction — Store South’s Dinner rush penalty is larger than other stores’). Store × Day and Time_Slot × Day cells would be cool/neutral (no interaction in the data generation). The heatmap would replace the text-only InteractionGuidance with visual evidence.\u003C/p>\n\u003Cp>\u003Cstrong>What the Investigation Mindmap would show:\u003C/strong>\nStore and Time_Slot nodes are both filled (active filters). The drill trail runs Start → Store → Time_Slot. Day node is outlined but small (low η²). If the heatmap data is synced, the Store–Time_Slot edge glows to show the interaction. The analyst can see that the remaining factor (Day) is weak — a visual signal that further drilling has diminishing returns.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-5-analyst-considers-day--diminishing-returns\">Step 5: Analyst Considers Day — Diminishing Returns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-analyst-considers-day--diminishing-returns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Analyst Considers Day — Diminishing Returns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Boxplot shows Day bars that are roughly similar in height and position. The ”↓ drill here” label is present but the η² is low (~0.03).\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Relatively even Boxplot bars across Day groups.\u003C/li>\n\u003Cli>The Funnel Panel (if open) shows Day with a small bar and ~3% η².\u003C/li>\n\u003Cli>Cumulative explained variation is ~55–60% without Day.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Boxplot label still shows ”↓ drill here” on the highest Day bar, even though the effect is tiny. The label doesn’t distinguish between “you should definitely drill here” and “this is the best of a weak set.”\u003C/li>\n\u003Cli>The Funnel Panel’s cumulative bar shows the investigation is past the 50% mark but hasn’t reached the 70% target.\u003C/li>\n\u003Cli>No explicit “Day is weak — you might want to stop” prompt.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no stopping signal in the main view:\u003C/strong>\nThe cumulative target (70%) lives only in the Funnel Panel. In the main dashboard, there’s no visual signal that the investigation has reached a “good enough” point or that further drilling into Day would yield diminishing returns. The Boxplot ”↓ drill here” label treats all factors equally — it doesn’t convey “this is a weak suggestion.”\u003C/p>\n\u003Cp>\u003Cstrong>What a Factor Suggestion enhancement would do (Phase 1):\u003C/strong>\nA suggestion chip near the Boxplot would read: “Day explains ~3% of remaining variation. Consider stopping — you’ve explained 58% so far.” Or simply: the suggestion chip would use muted styling (gray instead of blue) to signal that the recommendation is weak. This distinguishes a strong “drill here” from a weak “you could drill here, but…”\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-6-analyst-checks-interactions-via-regression-panel\">Step 6: Analyst Checks Interactions via Regression Panel\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-6-analyst-checks-interactions-via-regression-panel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 6: Analyst Checks Interactions via Regression Panel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Following the InteractionGuidance prompt (or curiosity), the analyst navigates to the Regression Panel and selects Store and Time_Slot as predictors with “Include interactions” enabled.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Regression results with main effects (Store levels, Time_Slot levels) and interaction terms (Store × Time_Slot pairs).\u003C/li>\n\u003Cli>R² for the main-effects-only model vs. the full model with interactions.\u003C/li>\n\u003Cli>Individual coefficient p-values and standardized betas.\u003C/li>\n\u003Cli>If the Pizza data has a meaningful Store × Time_Slot interaction, the interaction term’s coefficient would be significant and the ΔR² would be noticeable.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>The Regression Panel displays results clearly, with significant terms highlighted.\u003C/li>\n\u003Cli>No explicit summary like “interactions add 5% explanatory power” or “Store × Time_Slot is the strongest interaction.”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — results require interpretation:\u003C/strong>\nThe regression output is a table of coefficients. The analyst must compare R² values mentally and scan the interaction terms to find significant ones. There is no visual summary (like the heatmap) and no ranking of interaction importance. For Green Belt Gary this is manageable; for Student Sara it’s a barrier.\u003C/p>\n\u003Cp>\u003Cstrong>What the Interaction Heatmap would provide (Phase 2):\u003C/strong>\nThe heatmap would pre-compute and visualize exactly this information: ΔR² for each factor pair, displayed as colored cells. The analyst wouldn’t need to configure a regression — the heatmap would surface the “Store × Time_Slot interaction is moderate” finding proactively.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-7-investigation-complete--stopping-point\">Step 7: Investigation Complete — Stopping Point\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-7-investigation-complete--stopping-point\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 7: Investigation Complete — Stopping Point”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The analyst has identified Store (specifically Store South) and Time_Slot (specifically Dinner rush) as the primary drivers of delivery time variation. Together they explain ~60% of variation. Day is negligible.\u003C/p>\n\u003Cp>\u003Cstrong>What the analyst sees:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>FilterBreadcrumb with two active filters and their contribution percentages.\u003C/li>\n\u003Cli>If the Funnel Panel is open: cumulative bar at ~60%, short of the 70% target.\u003C/li>\n\u003Cli>Stats Panel showing the filtered (Store South × Dinner) statistics vs. the overall statistics.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Existing guidance at this step:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>The Funnel Panel’s cumulative bar turns green at 70%. At 60%, it’s still amber.\u003C/li>\n\u003Cli>No explicit “investigation complete” or “you’ve found enough” prompt.\u003C/li>\n\u003Cli>No summary view of what was found.\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Gap — no narrative summary:\u003C/strong>\nThe investigation ends without ceremony. There’s no “you investigated 3 factors, found 2 significant ones, explained 60% of variation” summary. The analyst must mentally reconstruct the investigation story for their report or team meeting.\u003C/p>\n\u003Cp>\u003Cstrong>What the Investigation Narrative would provide (Phase 3):\u003C/strong>\nA presentation mode that transforms the investigation into a visual story: “We started with 252 deliveries. Store South was the biggest driver (45% of variation). Within Store South, the Dinner rush added the most time (25% more). Together these explain 60% of delivery time variation. Recommended action: focus on Store South’s Dinner operations.”\u003C/p>\n\u003Cp>\u003Cstrong>What the Investigation Mindmap would show at this point:\u003C/strong>\nThe drill trail is complete: Start → Store South → Time_Slot: Dinner. Two nodes filled, one dimmed (Day). The mindmap is a visual record of the investigation path. In Narrative mode, this becomes the stakeholder presentation.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"summary-guidance-coverage-by-step\">Summary: Guidance Coverage by Step\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#summary-guidance-coverage-by-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Summary: Guidance Coverage by Step”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Step\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Existing Guidance\u003C/th>\u003Cth>Gaps\u003C/th>\u003Cth>Phase 1 (Factor Suggestion)\u003C/th>\u003Cth>Phase 2 (Interaction Heatmap)\u003C/th>\u003Cth>Phase 3 (Mindmap/Narrative)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Data loaded\u003C/td>\u003Ctd>Boxplot ”↓ drill here”\u003C/td>\u003Ctd>No “start here” for novices\u003C/td>\u003Ctd>Add suggestion chip with η² value\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Mindmap shows factor landscape\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>First drill (Store)\u003C/td>\u003Ctd>Contribution %, Boxplot label\u003C/td>\u003Ctd>No “suggested next factor”\u003C/td>\u003Ctd>Suggestion chip: “Try Time_Slot — 25% remaining”\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Drill trail begins\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Funnel opened\u003C/td>\u003Ctd>Rich: ranking, Cpk, cumulative\u003C/td>\u003Ctd>Funnel is hidden, covers charts\u003C/td>\u003Ctd>Surface key metrics in main view\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Mindmap provides always-visible overview\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Second drill (Time_Slot)\u003C/td>\u003Ctd>Contribution %, InteractionGuidance\u003C/td>\u003Ctd>Interaction guidance is text-only\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Heatmap shows Store × Time_Slot interaction\u003C/td>\u003Ctd>Mindmap shows interaction edges\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Consider Day (weak)\u003C/td>\u003Ctd>Boxplot label (no weak-signal indicator)\u003C/td>\u003Ctd>No diminishing returns signal\u003C/td>\u003Ctd>Muted suggestion styling for weak factors\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Small/dim Day node signals weakness\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Check interactions\u003C/td>\u003Ctd>Regression coefficients table\u003C/td>\u003Ctd>Results require expert interpretation\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Heatmap pre-computes and visualizes\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>Investigation complete\u003C/td>\u003Ctd>Cumulative bar (if Funnel open)\u003C/td>\u003Ctd>No narrative summary, no stopping prompt\u003C/td>\u003Ctd>Stopping signal: “You’ve explained X%“\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Narrative mode generates presentation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-takeaways-for-design\">Key Takeaways for Design\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-takeaways-for-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Takeaways for Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>The existing guidance is deeper than it appears\u003C/strong> — the Funnel Panel ecosystem is rich. The problem is discoverability and platform parity, not capability.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Phase 1 (Factor Suggestion) has the highest impact per effort\u003C/strong> — a suggestion chip in the main view surfaces the Funnel Panel’s best insights without requiring the analyst to find and open it.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Phase 2 (Interaction Heatmap) replaces a two-step workaround\u003C/strong> — currently the analyst sees a text prompt → navigates to Regression Panel → configures it → reads results. The heatmap collapses this into a glance.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Phase 3 (Mindmap/Narrative) addresses the end of the investigation\u003C/strong> — everything from Steps 1–6 is about finding the answer. Step 7 reveals that VariScout has no support for communicating the answer.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>The Pizza dataset works as a primary demo\u003C/strong> — its 3-factor structure walks through all the guidance elements without being overwhelming. Store dominance → Time_Slot secondary → Day diminishing returns is a clean pedagogical arc.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documents\">Related Documents\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documents\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documents”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"design-brief-guided-investigation.md\">Design Brief\u003C/a> — Statistical methodology and design principles\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/investigation-mindmap.md\">Investigation Mindmap\u003C/a> — Pattern evaluation for the companion view\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/investigation-narrative.md\">Investigation Narrative\u003C/a> — Pattern evaluation for presentation mode\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/factor-suggestion.md\">Factor Suggestion\u003C/a> — Phase 1 pattern evaluation\u003C/li>\n\u003Cli>\u003Ca href=\"patterns/interaction-heatmap.md\">Interaction Heatmap\u003C/a> — Phase 2 pattern evaluation\u003C/li>\n\u003C/ul>", + { + "headings": 5743, + "localImagePaths": 5771, + "remoteImagePaths": 5772, + "frontmatter": 5773, + "imagePaths": 5774 + }, + [5744, 5746, 5749, 5750, 5753, 5756, 5759, 5762, 5765, 5768, 5769, 5770], + { "depth": 30, "slug": 5745, "text": 5733 }, + "investigation-flow-map-pizza-delivery", + { "depth": 33, "slug": 5747, "text": 5748 }, + "dataset-pizza-delivery", + "Dataset: Pizza Delivery", + { "depth": 33, "slug": 5352, "text": 5353 }, + { "depth": 33, "slug": 5751, "text": 5752 }, + "step-2-analyst-clicks-store-south--first-drill", + "Step 2: Analyst Clicks Store South — First Drill", + { "depth": 33, "slug": 5754, "text": 5755 }, + "step-3-analyst-opens-funnel-panel", + "Step 3: Analyst Opens Funnel Panel", + { "depth": 33, "slug": 5757, "text": 5758 }, + "step-4-analyst-drills-into-time_slot--second-drill", + "Step 4: Analyst Drills into Time_Slot — Second Drill", + { "depth": 33, "slug": 5760, "text": 5761 }, + "step-5-analyst-considers-day--diminishing-returns", + "Step 5: Analyst Considers Day — Diminishing Returns", + { "depth": 33, "slug": 5763, "text": 5764 }, + "step-6-analyst-checks-interactions-via-regression-panel", + "Step 6: Analyst Checks Interactions via Regression Panel", + { "depth": 33, "slug": 5766, "text": 5767 }, + "step-7-investigation-complete--stopping-point", + "Step 7: Investigation Complete — Stopping Point", + { "depth": 33, "slug": 5373, "text": 5374 }, + { "depth": 33, "slug": 5376, "text": 5377 }, + { "depth": 33, "slug": 4342, "text": 4343 }, + [], + [], + { "title": 5733 }, + [], + "01-vision/evaluations/mindmap-chrome-evaluation", + { "id": 5775, "data": 5777, "body": 5782, "filePath": 5783, "digest": 5784, "rendered": 5785 }, + { + "title": 5778, + "editUrl": 16, + "head": 5779, + "template": 18, + "sidebar": 5780, + "pagefind": 16, + "draft": 20 + }, + "Chrome Evaluation: Mindmap with Bottleneck & Hospital Ward", + [], + { "hidden": 20, "attrs": 5781 }, + {}, + "# Chrome Evaluation: Mindmap with Bottleneck & Hospital Ward\n\n> Automated Playwright evaluation (13 tests, all passing) of the Investigation Mindmap panel with both Bottleneck and Hospital Ward case study datasets. Evaluates how the Mindmap contributes to the investigation workflow, documenting working features, UX gaps, and bugs. Screenshots in `apps/pwa/e2e/screenshots/mindmap-eval/`. E2E spec: `apps/pwa/e2e/mindmap-evaluation.spec.ts`.\n\n---\n\n## Summary of Findings\n\n| Area | Finding | Severity |\n| -------------------------- | ---------------------------------------------------------------------------------------------- | ---------- |\n| Suggestion metric | Shift suggested over Step in Bottleneck (58% vs 38%) — misleading for the pedagogical story | **High** |\n| CategoryPopover | Correctly shows all categories with contribution % before drilling | Working |\n| Dead-end signal | No dead-end after Bottleneck Step 2 drill — Shift still pulses at 71% | **Medium** |\n| Hospital Ward popover | Night 46% + Afternoon 35% visible together — analyst CAN see contrast before drilling | Working |\n| Day_of_Week after Night | Day_of_Week still pulses at 17% — mild false positive | **Low** |\n| Narrative mode | Works after single drill, shows mean/Cpk before/after, conclusion panel, \"+ Add note\" | Working |\n| Progress bar | Shows \"Focused on X% of variation\" with 70% target — clear visual progress | Working |\n| Drill path footer | Shows factor name + contribution % — useful breadcrumb | Working |\n| Panel close mechanisms | Escape and close button both work correctly | Working |\n| Investigation prompt | Blue nudge bar appears after first boxplot drill — good discoverability | Working |\n| CategoryPopover truncation | Category labels truncated at 110px — some text clipped (visible in screenshots) | **Low** |\n| Panel backdrop | Blocks filter chip remove buttons when panel is open — must close panel to undo drill | **Medium** |\n| Step 2 contribution 0% | Step 2 shows 0% contribution in CategoryPopover — counterintuitive for the \"hidden bottleneck\" | **Bug** |\n\n---\n\n## Scenario 1: Bottleneck Dataset\n\n### 1.1 Initial State\n\n**Measured values:**\n\n- Step node: 38% contribution, state: `available`\n- Shift node: 58% contribution, state: `suggested` (green pulse)\n- Progress bar: \"Focused on -- of variation\"\n\n**Finding: Shift is suggested instead of Step.**\nThe `maxContribution` metric (single largest category's Total SS %) favors Shift because Shift has only 2 categories (Morning/Afternoon) and one of them carries a high relative proportion of the within-shift variance. Step has 5 categories that divide the variance more evenly. This means the suggestion metric recommends Shift first, which leads the analyst away from the interesting story (Step 2's high variance).\n\nThis is a significant mismatch between the suggestion algorithm and the pedagogical intent. In the Bottleneck dataset, Step is the dominant factor by any ANOVA measure (F-statistic, eta-squared), yet the max-single-category heuristic suggests Shift. An analyst following the green pulse would drill Shift first, which is a dead end — Morning and Afternoon both show 0% contribution.\n\n**Recommendation:** Consider using the ANOVA F-statistic or eta-squared for suggestion ranking instead of max single-category contribution. The factor that explains the most between-group variance is the more analytically productive first drill.\n\n### 1.2 CategoryPopover for Step\n\n**Measured values (sorted by contribution):**\n| Category | Contribution |\n|----------|-------------|\n| Step 3 | 37% |\n| Step 5 | 13% |\n| Step 1 | 5% |\n| Step 4 | 1% |\n| Step 2 | **0%** |\n\n**Bug: Step 2 shows 0% contribution.**\nStep 2 is the hidden bottleneck — it has the highest variance (std ~10 vs std ~2 for other steps). However, the `maxContribution` metric measures contribution to Total SS differently than expected. The popover shows Step 3 (37%) as the dominant category, which aligns with its high mean (45s vs 35s overall mean) but misses the variation story entirely.\n\nThis is because `maxContribution` for individual categories appears to measure the deviation of the category mean from the overall mean (between-group effect), not the within-group spread. Step 2's mean (~37s) is close to the overall mean (~35s), so its contribution registers as 0%. Step 3's mean (~45s) is 10s above overall, giving it the highest between-group contribution.\n\n**The core problem:** The metric visible in the CategoryPopover is a between-group location metric, but the Bottleneck dataset's story is about within-group dispersion. An analyst looking at this popover would choose Step 3 (37%) over Step 2 (0%), which is the wrong choice. The popover actively misleads for dispersion-dominant scenarios.\n\n### 1.3 CategoryPopover for Shift\n\n| Category | Contribution |\n| --------- | ------------ |\n| Morning | 0% |\n| Afternoon | 0% |\n\nBoth categories show 0% — Shift has no meaningful contribution to variation. This is correct. However, the Shift node shows 58% contribution on the Mindmap — a confusing contradiction. The node percentage and popover percentages appear to measure different things.\n\n### 1.4 After Drilling Step 2\n\n**Measured values:**\n\n- Filter chip: \"Step: Step 2 38%\"\n- Step node: active (blue), 38%\n- Shift node: **still suggested (green pulse)**, 71%\n- Drill path: \"Step 38%\"\n- Progress: \"Focused on 38% of variation\"\n\n**Finding: No dead-end signal after Step 2 drill.**\nAfter filtering to Step 2 (n=30), Shift's contribution jumps to 71% and it still pulses green, suggesting deeper investigation. In reality, with only 2 shift categories and 15 observations each, any apparent Shift effect within Step 2 is likely noise. The analyst is guided toward a second drill that won't yield actionable insight.\n\nThe \"implicit dead-end\" design (no pulse = dead end) doesn't activate here because Shift's recalculated maxContribution on the filtered subset happens to exceed the suggestion threshold. This is a false positive that could waste analyst time.\n\n### 1.5 Step 2 vs Step 3 I-Chart Contrast\n\n**Measured values:**\n\n- Step 2: mean=36.20, std=9.89\n- Step 3: mean=45.17, std=1.94\n- Ratio: 5.1x variance difference\n\n**Working well:** The I-Chart contrast between Step 2 (chaotic, wide control limits) and Step 3 (stable, tight band around 45s) is dramatic and immediately visible. The Mindmap's drill-and-compare workflow makes it easy to see both charts sequentially. The filter chip shows \"38% in focus\" and the Mindmap node updates to \"= Step 2\" / \"= Step 3\" text labels.\n\n**Gap:** There is no side-by-side comparison view. The analyst must remember Step 2's I-Chart while looking at Step 3's. The Mindmap provides the drill path breadcrumb but no mechanism to hold both views simultaneously.\n\n---\n\n## Scenario 2: Hospital Ward Dataset\n\n### 2.1 Initial State\n\n**Measured values:**\n\n- Time_Period node: 47% contribution, state: `suggested` (green pulse)\n- Day_of_Week node: 16% contribution, state: `available`\n- Progress bar: \"Focused on -- of variation\"\n\n**Working correctly:** Time_Period is correctly suggested. The 47% vs 16% split clearly identifies Time_Period as the dominant factor. The green pulse draws the analyst's attention to the right node.\n\n### 2.2 CategoryPopover — Night and Afternoon Contrast\n\n**Measured values (sorted by contribution):**\n| Category | Contribution |\n|----------|-------------|\n| Night | 46% |\n| Afternoon | 35% |\n| Evening | 7% |\n| Morning | 3% |\n\n**Key success:** Both Night (46%) and Afternoon (35%) are visible in the same popover before drilling. The analyst can see that two time periods dominate before committing to a drill. This is a significant advantage over the boxplot-only workflow, where the analyst would drill Night, see the crisis, and might not return to check Afternoon.\n\n**This is the CategoryPopover's strongest contribution to the investigation workflow.** It provides pre-drill context that the boxplot alone cannot — the analyst sees the full landscape of category contributions before filtering. For the Hospital Ward aggregation trap, this pre-drill view is the moment where the analyst can plan a multi-step investigation.\n\n### 2.3 Night Drill — Crisis Level\n\n**Measured values:**\n\n- Night mean: 94.02% (vs 75% overall)\n- Time_Period node: active, 47%\n- Day_of_Week: suggested (green pulse), 17%\n- Drill path: \"Time_Period 47%\"\n- Progress: \"Focused on 47% of variation\"\n\n**Finding: Day_of_Week still pulses after Night drill.**\nWith Night selected (n=252), Day_of_Week shows 17% contribution and still pulses green. This is a mild false positive — Day_of_Week has 7 categories (Mon-Sun) and some day-to-day variation within Night is expected (weekday staffing differences), but it's not the primary story. An analyst following the pulse would drill further when the investigation for Night is essentially complete.\n\n### 2.4 Afternoon Drill — Waste Level\n\n**Measured values:**\n\n- Afternoon mean: 46.68% (vs 75% overall)\n- Time_Period: active, 36%\n- Day_of_Week: suggested, 22%\n- Progress: \"Focused on 36% of variation\"\n\nThe 94% vs 47% contrast (Night vs Afternoon) is the aggregation trap discovery. The Mindmap makes it easy to drill each category and see the dramatic difference. The progress bar shows 36% for Afternoon (lower than Night's 47%) — this makes sense since Afternoon has fewer observations and less total impact.\n\n**Note:** The aggregation trap itself — that the overall 75% mean represents neither Night nor Afternoon — is not explicitly called out. The analyst must make this connection by comparing the drill results with the overall stats. A \"contrast summary\" or \"aggregation warning\" would complete the story.\n\n### 2.5 Narrative Mode\n\n**Working:** Narrative mode activates after a single drill. The panel shows:\n\n- Step 1: Time_Period node (47%), blue circle\n- \"Time_Period = Night\"\n- \"47% of variation in scope\"\n- \"Mean: 75.2 -> 94.0\" (before/after)\n- \"Cpk: 0.64 -> -0.45\" (dramatic capability drop — Night is out of spec)\n- \"n: 672 -> 252\"\n- \"+ Add note\" prompt for analyst annotations\n- Conclusion panel: \"Focused on 47% of variation / 53% outside scope — consider additional factors\"\n- \"Model improvements ->\" button linking to What-If\n\n**This is the Narrative mode's strongest moment.** The before/after comparison (Mean, Cpk, n) provides exactly the context the flow map evaluations identified as missing. The analyst can document findings and see the aggregate picture. The Cpk change from 0.64 to -0.45 is a powerful visual indicator that Night is a crisis.\n\n**Gap:** Narrative mode captures one drill per factor. The Hospital Ward investigation requires drilling Time_Period twice (Night + Afternoon) to reveal the aggregation trap. The current Narrative mode can only show one category selection per factor node. There's no mechanism to capture \"I investigated Night AND Afternoon and found the contrast.\"\n\n---\n\n## Cross-Cutting Findings\n\n### Mode Toggle States\n\n| Condition | Drilldown | Interactions | Narrative |\n| ------------------ | --------- | --------------------------- | ------------ |\n| Initial (no drill) | Enabled | Enabled (2 factors, n >= 5) | **Disabled** |\n| After 1 drill | Enabled | Enabled | **Enabled** |\n\nInteractions mode is available from the start with the Bottleneck dataset (2 factors, n=150), which is correct. Narrative requires at least 1 drill, which makes sense — there's nothing to narrate before the first investigation step.\n\n### Panel Close Mechanisms\n\nBoth Escape key and close button work reliably. The backdrop click also works. No issues found.\n\n### Investigation Prompt Nudge\n\nAfter the first boxplot drill (without the Mindmap open), a blue nudge bar appears: \"Tracking your investigation — open the Investigation panel to see the full picture.\" This is excellent for discoverability — it appears at exactly the right moment when the analyst is already engaged in investigation.\n\n### Panel Backdrop Blocks Filter Chips\n\nWhen the Mindmap panel is open, its backdrop overlay (`position: fixed; inset: 0; bg-black/40`) covers the main content area. This prevents clicking the filter chip remove buttons in the header bar. The analyst must close the Mindmap panel to undo a drill, then reopen it to continue investigating. This is a workflow friction point — the panel should not block header interactions.\n\n---\n\n## Summary: What the Mindmap Adds\n\n### Working Well\n\n1. **CategoryPopover provides pre-drill context** — the analyst sees all category contributions before committing to a filter. This is the Mindmap's most significant contribution, especially for the Hospital Ward scenario where Night and Afternoon are both visible at 46%/35%.\n\n2. **Active node state tracking** — after drilling, the node turns blue with \"= Step 2\" label, providing clear visual confirmation of what's filtered. The trail line from Start to active node reinforces the drill path.\n\n3. **Progress bar toward 70% target** — \"Focused on 38% of variation\" with a visual bar toward 70% gives the analyst a quantitative sense of investigation completeness.\n\n4. **Drill path footer** — \"Step 38%\" chip provides a persistent breadcrumb of the investigation trail.\n\n5. **Narrative mode's before/after comparison** — Mean, Cpk, and n changes are shown explicitly, which is exactly the context missing from the boxplot-only workflow.\n\n6. **Investigation prompt nudge** — appears after first drill, excellent discoverability.\n\n### Gaps That Remain\n\n1. **Suggestion metric misleads for dispersion-dominated scenarios** — Shift (58%) suggested over Step (38%) in Bottleneck data because `maxContribution` measures location, not dispersion.\n\n2. **Step 2 shows 0% in CategoryPopover** — the hidden bottleneck (high variance, near-average mean) is invisible in the popover's contribution ranking. This is the most critical analytical failure for the Bottleneck use case.\n\n3. **No explicit dead-end signal** — after drilling Step 2, Shift still pulses green at 71%. The implicit \"no pulse = dead end\" design doesn't activate because the recalculated metric exceeds the threshold on filtered data.\n\n4. **No aggregation trap warning** — the Hospital Ward's overall mean (75%) represents neither Night (94%) nor Afternoon (47%), but nothing in the Mindmap flags this. The analyst must make the connection manually.\n\n5. **Narrative can't capture multi-category contrast** — the Hospital Ward investigation requires comparing Night vs Afternoon within Time_Period, but Narrative mode shows only one drill per factor node.\n\n6. **Panel backdrop blocks filter chip interactions** — must close the panel to undo drills, creating workflow friction.\n\n7. **No side-by-side comparison** — after drilling Step 2, the analyst must remember its I-Chart while drilling Step 3. No mechanism to hold both views simultaneously.\n\n### Bugs\n\n1. **Contribution metric inconsistency**: The Shift node shows 58% on the Mindmap but both Shift categories show 0% in the CategoryPopover. **Root cause confirmed**: The node circle uses `calculateCategoryTotalSS` (total SS including within-group spread) while the popover uses `getCategoryStats` (between-group SS only — `n_j * (mean_j - overall_mean)²`). These are fundamentally different formulas producing contradictory results. Code: `packages/core/src/variation/contributions.ts` and `packages/core/src/variation/suggestions.ts`.\n\n2. **Step 2 at 0% in popover**: The popover's between-group-only metric `n_j * (mean_j - overall_mean)²` produces 0% for Step 2 because its group mean (~37) is close to the overall mean (~35). The high within-group variance (std=10) is invisible to this metric. This is the most analytically damaging bug for the Bottleneck use case — the popover actively hides the hidden bottleneck.\n\n---\n\n## Recommendations\n\n### Priority 1: Fix Contribution Metrics\n\n**Root cause analysis:** Two different metrics are used, and both have problems:\n\n1. **Node circle %** (`getMaxCategoryContribution` -> `calculateCategoryTotalSS`): Computes `Σ(x_ij - overall_mean)² / SS_total` for the single largest category. This includes both mean deviation AND within-group spread, which is correct in principle. But using the _single largest category_ favors factors with fewer categories (Shift's 2 buckets > Step's 5 buckets), even when the factor itself explains little between-group variance.\n\n2. **Popover category %** (`getCategoryStats`): Computes `n_j × (mean_j - overall_mean)² / SS_total` — a between-group-only metric. This misses within-group spread entirely, which is why Step 2 (mean ~37, close to overall ~35) shows 0% despite having the highest variance (std=10).\n\n**The two metrics use fundamentally different formulas**, creating a contradiction: Shift node shows 58% but both Shift categories show 0% in the popover.\n\n**Recommended fix:**\n\n- **For node suggestion ranking**: Use ANOVA eta-squared (SS_between / SS_total for each factor). This correctly identifies Step as the dominant factor because Step's categories have diverse means AND diverse spreads.\n- **For popover category ranking**: Show a _spread-aware_ metric — either within-category contribution to Total SS (the current `calculateCategoryTotalSS` formula, which already includes spread), or IQR/sigma alongside the existing between-group %. This would make Step 2's high variance visible in the popover.\n- **Ensure consistency**: The node circle % and popover % sum should be reconcilable — either both use Total SS partitioning or both use between-group SS.\n\n### Priority 2: Explicit Dead-End Signal\n\nWhen a remaining factor's contribution drops below a threshold (e.g., 5%) after drilling, show an explicit indicator:\n\n- Grey out the node\n- Show \"exhausted\" text or icon\n- Add a tooltip: \"This factor explains \u003C 5% of remaining variation\"\n\n### Priority 3: Aggregation Trap Alert\n\nWhen category means span a wide range relative to the overall mean, show a warning:\n\n- \"Night (94%) and Afternoon (47%) are far from the overall mean (75%)\"\n- \"The overall mean does not represent either subgroup\"\n\n### Priority 4: Multi-Category Narrative\n\nAllow Narrative mode to capture multiple category drills within the same factor:\n\n- \"Step 1: Time_Period — investigated Night (94%) and Afternoon (47%), found 47-point gap\"\n\n---\n\n## Test Data Reference\n\nAll measurements from `apps/pwa/e2e/mindmap-evaluation.spec.ts` (13 tests, all passing):\n\n| Test | Dataset | Key Measurement |\n| ---- | ------------- | --------------------------------------------------------------- |\n| 1.1 | Bottleneck | Step 38%, Shift 58% (suggested) |\n| 1.2 | Bottleneck | Step popover: Step 3=37%, Step 2=0% |\n| 1.3 | Bottleneck | Shift popover: Morning=0%, Afternoon=0% |\n| 1.4 | Bottleneck | After Step 2 drill: Shift still pulses at 71% |\n| 1.5 | Bottleneck | Step 2 sigma=9.89, Step 3 sigma=1.94 (5.1x ratio) |\n| 2.1 | Hospital Ward | Time_Period 47%, Day_of_Week 16% |\n| 2.2 | Hospital Ward | Popover: Night=46%, Afternoon=35% |\n| 2.3 | Hospital Ward | Night mean=94.02, Day_of_Week still pulses at 17% |\n| 2.4 | Hospital Ward | Afternoon mean=46.68, Day_of_Week pulses at 22% |\n| 2.5 | Hospital Ward | Narrative: Mean 75.2->94.0, Cpk 0.64->-0.45 |\n| 3.1 | Bottleneck | Mode states: Interactions initially enabled, Narrative disabled |\n| 3.2 | Bottleneck | Panel close: Escape and button both work |\n| 3.3 | Bottleneck | Investigation prompt appears after first boxplot drill |", + "src/content/docs/01-vision/evaluations/mindmap-chrome-evaluation.md", + "666c880286d60714", + { "html": 5786, "metadata": 5787 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"chrome-evaluation-mindmap-with-bottleneck--hospital-ward\">Chrome Evaluation: Mindmap with Bottleneck & Hospital Ward\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#chrome-evaluation-mindmap-with-bottleneck--hospital-ward\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chrome Evaluation: Mindmap with Bottleneck & Hospital Ward”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Automated Playwright evaluation (13 tests, all passing) of the Investigation Mindmap panel with both Bottleneck and Hospital Ward case study datasets. Evaluates how the Mindmap contributes to the investigation workflow, documenting working features, UX gaps, and bugs. Screenshots in \u003Ccode dir=\"auto\">apps/pwa/e2e/screenshots/mindmap-eval/\u003C/code>. E2E spec: \u003Ccode dir=\"auto\">apps/pwa/e2e/mindmap-evaluation.spec.ts\u003C/code>.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"summary-of-findings\">Summary of Findings\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#summary-of-findings\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Summary of Findings”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Area\u003C/th>\u003Cth>Finding\u003C/th>\u003Cth>Severity\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Suggestion metric\u003C/td>\u003Ctd>Shift suggested over Step in Bottleneck (58% vs 38%) — misleading for the pedagogical story\u003C/td>\u003Ctd>\u003Cstrong>High\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CategoryPopover\u003C/td>\u003Ctd>Correctly shows all categories with contribution % before drilling\u003C/td>\u003Ctd>Working\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Dead-end signal\u003C/td>\u003Ctd>No dead-end after Bottleneck Step 2 drill — Shift still pulses at 71%\u003C/td>\u003Ctd>\u003Cstrong>Medium\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hospital Ward popover\u003C/td>\u003Ctd>Night 46% + Afternoon 35% visible together — analyst CAN see contrast before drilling\u003C/td>\u003Ctd>Working\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Day_of_Week after Night\u003C/td>\u003Ctd>Day_of_Week still pulses at 17% — mild false positive\u003C/td>\u003Ctd>\u003Cstrong>Low\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Narrative mode\u003C/td>\u003Ctd>Works after single drill, shows mean/Cpk before/after, conclusion panel, ”+ Add note”\u003C/td>\u003Ctd>Working\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Progress bar\u003C/td>\u003Ctd>Shows “Focused on X% of variation” with 70% target — clear visual progress\u003C/td>\u003Ctd>Working\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Drill path footer\u003C/td>\u003Ctd>Shows factor name + contribution % — useful breadcrumb\u003C/td>\u003Ctd>Working\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Panel close mechanisms\u003C/td>\u003Ctd>Escape and close button both work correctly\u003C/td>\u003Ctd>Working\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Investigation prompt\u003C/td>\u003Ctd>Blue nudge bar appears after first boxplot drill — good discoverability\u003C/td>\u003Ctd>Working\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CategoryPopover truncation\u003C/td>\u003Ctd>Category labels truncated at 110px — some text clipped (visible in screenshots)\u003C/td>\u003Ctd>\u003Cstrong>Low\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Panel backdrop\u003C/td>\u003Ctd>Blocks filter chip remove buttons when panel is open — must close panel to undo drill\u003C/td>\u003Ctd>\u003Cstrong>Medium\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step 2 contribution 0%\u003C/td>\u003Ctd>Step 2 shows 0% contribution in CategoryPopover — counterintuitive for the “hidden bottleneck”\u003C/td>\u003Ctd>\u003Cstrong>Bug\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"scenario-1-bottleneck-dataset\">Scenario 1: Bottleneck Dataset\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#scenario-1-bottleneck-dataset\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario 1: Bottleneck Dataset”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"11-initial-state\">1.1 Initial State\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#11-initial-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1.1 Initial State”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Measured values:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Step node: 38% contribution, state: \u003Ccode dir=\"auto\">available\u003C/code>\u003C/li>\n\u003Cli>Shift node: 58% contribution, state: \u003Ccode dir=\"auto\">suggested\u003C/code> (green pulse)\u003C/li>\n\u003Cli>Progress bar: “Focused on — of variation”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Finding: Shift is suggested instead of Step.\u003C/strong>\nThe \u003Ccode dir=\"auto\">maxContribution\u003C/code> metric (single largest category’s Total SS %) favors Shift because Shift has only 2 categories (Morning/Afternoon) and one of them carries a high relative proportion of the within-shift variance. Step has 5 categories that divide the variance more evenly. This means the suggestion metric recommends Shift first, which leads the analyst away from the interesting story (Step 2’s high variance).\u003C/p>\n\u003Cp>This is a significant mismatch between the suggestion algorithm and the pedagogical intent. In the Bottleneck dataset, Step is the dominant factor by any ANOVA measure (F-statistic, eta-squared), yet the max-single-category heuristic suggests Shift. An analyst following the green pulse would drill Shift first, which is a dead end — Morning and Afternoon both show 0% contribution.\u003C/p>\n\u003Cp>\u003Cstrong>Recommendation:\u003C/strong> Consider using the ANOVA F-statistic or eta-squared for suggestion ranking instead of max single-category contribution. The factor that explains the most between-group variance is the more analytically productive first drill.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"12-categorypopover-for-step\">1.2 CategoryPopover for Step\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#12-categorypopover-for-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1.2 CategoryPopover for Step”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Measured values (sorted by contribution):\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Category\u003C/th>\u003Cth>Contribution\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Step 3\u003C/td>\u003Ctd>37%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step 5\u003C/td>\u003Ctd>13%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step 1\u003C/td>\u003Ctd>5%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step 4\u003C/td>\u003Ctd>1%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step 2\u003C/td>\u003Ctd>\u003Cstrong>0%\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Bug: Step 2 shows 0% contribution.\u003C/strong>\nStep 2 is the hidden bottleneck — it has the highest variance (std ~10 vs std ~2 for other steps). However, the \u003Ccode dir=\"auto\">maxContribution\u003C/code> metric measures contribution to Total SS differently than expected. The popover shows Step 3 (37%) as the dominant category, which aligns with its high mean (45s vs 35s overall mean) but misses the variation story entirely.\u003C/p>\n\u003Cp>This is because \u003Ccode dir=\"auto\">maxContribution\u003C/code> for individual categories appears to measure the deviation of the category mean from the overall mean (between-group effect), not the within-group spread. Step 2’s mean (~37s) is close to the overall mean (~35s), so its contribution registers as 0%. Step 3’s mean (~45s) is 10s above overall, giving it the highest between-group contribution.\u003C/p>\n\u003Cp>\u003Cstrong>The core problem:\u003C/strong> The metric visible in the CategoryPopover is a between-group location metric, but the Bottleneck dataset’s story is about within-group dispersion. An analyst looking at this popover would choose Step 3 (37%) over Step 2 (0%), which is the wrong choice. The popover actively misleads for dispersion-dominant scenarios.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"13-categorypopover-for-shift\">1.3 CategoryPopover for Shift\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#13-categorypopover-for-shift\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1.3 CategoryPopover for Shift”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Category\u003C/th>\u003Cth>Contribution\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Morning\u003C/td>\u003Ctd>0%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Afternoon\u003C/td>\u003Ctd>0%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Both categories show 0% — Shift has no meaningful contribution to variation. This is correct. However, the Shift node shows 58% contribution on the Mindmap — a confusing contradiction. The node percentage and popover percentages appear to measure different things.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"14-after-drilling-step-2\">1.4 After Drilling Step 2\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#14-after-drilling-step-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1.4 After Drilling Step 2”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Measured values:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Filter chip: “Step: Step 2 38%”\u003C/li>\n\u003Cli>Step node: active (blue), 38%\u003C/li>\n\u003Cli>Shift node: \u003Cstrong>still suggested (green pulse)\u003C/strong>, 71%\u003C/li>\n\u003Cli>Drill path: “Step 38%”\u003C/li>\n\u003Cli>Progress: “Focused on 38% of variation”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Finding: No dead-end signal after Step 2 drill.\u003C/strong>\nAfter filtering to Step 2 (n=30), Shift’s contribution jumps to 71% and it still pulses green, suggesting deeper investigation. In reality, with only 2 shift categories and 15 observations each, any apparent Shift effect within Step 2 is likely noise. The analyst is guided toward a second drill that won’t yield actionable insight.\u003C/p>\n\u003Cp>The “implicit dead-end” design (no pulse = dead end) doesn’t activate here because Shift’s recalculated maxContribution on the filtered subset happens to exceed the suggestion threshold. This is a false positive that could waste analyst time.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"15-step-2-vs-step-3-i-chart-contrast\">1.5 Step 2 vs Step 3 I-Chart Contrast\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#15-step-2-vs-step-3-i-chart-contrast\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1.5 Step 2 vs Step 3 I-Chart Contrast”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Measured values:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Step 2: mean=36.20, std=9.89\u003C/li>\n\u003Cli>Step 3: mean=45.17, std=1.94\u003C/li>\n\u003Cli>Ratio: 5.1x variance difference\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Working well:\u003C/strong> The I-Chart contrast between Step 2 (chaotic, wide control limits) and Step 3 (stable, tight band around 45s) is dramatic and immediately visible. The Mindmap’s drill-and-compare workflow makes it easy to see both charts sequentially. The filter chip shows “38% in focus” and the Mindmap node updates to ”= Step 2” / ”= Step 3” text labels.\u003C/p>\n\u003Cp>\u003Cstrong>Gap:\u003C/strong> There is no side-by-side comparison view. The analyst must remember Step 2’s I-Chart while looking at Step 3’s. The Mindmap provides the drill path breadcrumb but no mechanism to hold both views simultaneously.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"scenario-2-hospital-ward-dataset\">Scenario 2: Hospital Ward Dataset\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#scenario-2-hospital-ward-dataset\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario 2: Hospital Ward Dataset”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"21-initial-state\">2.1 Initial State\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#21-initial-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2.1 Initial State”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Measured values:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Time_Period node: 47% contribution, state: \u003Ccode dir=\"auto\">suggested\u003C/code> (green pulse)\u003C/li>\n\u003Cli>Day_of_Week node: 16% contribution, state: \u003Ccode dir=\"auto\">available\u003C/code>\u003C/li>\n\u003Cli>Progress bar: “Focused on — of variation”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Working correctly:\u003C/strong> Time_Period is correctly suggested. The 47% vs 16% split clearly identifies Time_Period as the dominant factor. The green pulse draws the analyst’s attention to the right node.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"22-categorypopover--night-and-afternoon-contrast\">2.2 CategoryPopover — Night and Afternoon Contrast\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#22-categorypopover--night-and-afternoon-contrast\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2.2 CategoryPopover — Night and Afternoon Contrast”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Measured values (sorted by contribution):\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Category\u003C/th>\u003Cth>Contribution\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Night\u003C/td>\u003Ctd>46%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Afternoon\u003C/td>\u003Ctd>35%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evening\u003C/td>\u003Ctd>7%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Morning\u003C/td>\u003Ctd>3%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key success:\u003C/strong> Both Night (46%) and Afternoon (35%) are visible in the same popover before drilling. The analyst can see that two time periods dominate before committing to a drill. This is a significant advantage over the boxplot-only workflow, where the analyst would drill Night, see the crisis, and might not return to check Afternoon.\u003C/p>\n\u003Cp>\u003Cstrong>This is the CategoryPopover’s strongest contribution to the investigation workflow.\u003C/strong> It provides pre-drill context that the boxplot alone cannot — the analyst sees the full landscape of category contributions before filtering. For the Hospital Ward aggregation trap, this pre-drill view is the moment where the analyst can plan a multi-step investigation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"23-night-drill--crisis-level\">2.3 Night Drill — Crisis Level\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#23-night-drill--crisis-level\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2.3 Night Drill — Crisis Level”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Measured values:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Night mean: 94.02% (vs 75% overall)\u003C/li>\n\u003Cli>Time_Period node: active, 47%\u003C/li>\n\u003Cli>Day_of_Week: suggested (green pulse), 17%\u003C/li>\n\u003Cli>Drill path: “Time_Period 47%”\u003C/li>\n\u003Cli>Progress: “Focused on 47% of variation”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Finding: Day_of_Week still pulses after Night drill.\u003C/strong>\nWith Night selected (n=252), Day_of_Week shows 17% contribution and still pulses green. This is a mild false positive — Day_of_Week has 7 categories (Mon-Sun) and some day-to-day variation within Night is expected (weekday staffing differences), but it’s not the primary story. An analyst following the pulse would drill further when the investigation for Night is essentially complete.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"24-afternoon-drill--waste-level\">2.4 Afternoon Drill — Waste Level\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#24-afternoon-drill--waste-level\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2.4 Afternoon Drill — Waste Level”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Measured values:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Afternoon mean: 46.68% (vs 75% overall)\u003C/li>\n\u003Cli>Time_Period: active, 36%\u003C/li>\n\u003Cli>Day_of_Week: suggested, 22%\u003C/li>\n\u003Cli>Progress: “Focused on 36% of variation”\u003C/li>\n\u003C/ul>\n\u003Cp>The 94% vs 47% contrast (Night vs Afternoon) is the aggregation trap discovery. The Mindmap makes it easy to drill each category and see the dramatic difference. The progress bar shows 36% for Afternoon (lower than Night’s 47%) — this makes sense since Afternoon has fewer observations and less total impact.\u003C/p>\n\u003Cp>\u003Cstrong>Note:\u003C/strong> The aggregation trap itself — that the overall 75% mean represents neither Night nor Afternoon — is not explicitly called out. The analyst must make this connection by comparing the drill results with the overall stats. A “contrast summary” or “aggregation warning” would complete the story.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"25-narrative-mode\">2.5 Narrative Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#25-narrative-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2.5 Narrative Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Working:\u003C/strong> Narrative mode activates after a single drill. The panel shows:\u003C/p>\n\u003Cul>\n\u003Cli>Step 1: Time_Period node (47%), blue circle\u003C/li>\n\u003Cli>“Time_Period = Night”\u003C/li>\n\u003Cli>“47% of variation in scope”\u003C/li>\n\u003Cli>“Mean: 75.2 -> 94.0” (before/after)\u003C/li>\n\u003Cli>“Cpk: 0.64 -> -0.45” (dramatic capability drop — Night is out of spec)\u003C/li>\n\u003Cli>“n: 672 -> 252”\u003C/li>\n\u003Cli>”+ Add note” prompt for analyst annotations\u003C/li>\n\u003Cli>Conclusion panel: “Focused on 47% of variation / 53% outside scope — consider additional factors”\u003C/li>\n\u003Cli>“Model improvements ->” button linking to What-If\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>This is the Narrative mode’s strongest moment.\u003C/strong> The before/after comparison (Mean, Cpk, n) provides exactly the context the flow map evaluations identified as missing. The analyst can document findings and see the aggregate picture. The Cpk change from 0.64 to -0.45 is a powerful visual indicator that Night is a crisis.\u003C/p>\n\u003Cp>\u003Cstrong>Gap:\u003C/strong> Narrative mode captures one drill per factor. The Hospital Ward investigation requires drilling Time_Period twice (Night + Afternoon) to reveal the aggregation trap. The current Narrative mode can only show one category selection per factor node. There’s no mechanism to capture “I investigated Night AND Afternoon and found the contrast.”\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-cutting-findings\">Cross-Cutting Findings\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-cutting-findings\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Cutting Findings”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mode-toggle-states\">Mode Toggle States\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mode-toggle-states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mode Toggle States”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Condition\u003C/th>\u003Cth>Drilldown\u003C/th>\u003Cth>Interactions\u003C/th>\u003Cth>Narrative\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Initial (no drill)\u003C/td>\u003Ctd>Enabled\u003C/td>\u003Ctd>Enabled (2 factors, n >= 5)\u003C/td>\u003Ctd>\u003Cstrong>Disabled\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>After 1 drill\u003C/td>\u003Ctd>Enabled\u003C/td>\u003Ctd>Enabled\u003C/td>\u003Ctd>\u003Cstrong>Enabled\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Interactions mode is available from the start with the Bottleneck dataset (2 factors, n=150), which is correct. Narrative requires at least 1 drill, which makes sense — there’s nothing to narrate before the first investigation step.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"panel-close-mechanisms\">Panel Close Mechanisms\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#panel-close-mechanisms\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Panel Close Mechanisms”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both Escape key and close button work reliably. The backdrop click also works. No issues found.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"investigation-prompt-nudge\">Investigation Prompt Nudge\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-prompt-nudge\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation Prompt Nudge”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After the first boxplot drill (without the Mindmap open), a blue nudge bar appears: “Tracking your investigation — open the Investigation panel to see the full picture.” This is excellent for discoverability — it appears at exactly the right moment when the analyst is already engaged in investigation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"panel-backdrop-blocks-filter-chips\">Panel Backdrop Blocks Filter Chips\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#panel-backdrop-blocks-filter-chips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Panel Backdrop Blocks Filter Chips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When the Mindmap panel is open, its backdrop overlay (\u003Ccode dir=\"auto\">position: fixed; inset: 0; bg-black/40\u003C/code>) covers the main content area. This prevents clicking the filter chip remove buttons in the header bar. The analyst must close the Mindmap panel to undo a drill, then reopen it to continue investigating. This is a workflow friction point — the panel should not block header interactions.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"summary-what-the-mindmap-adds\">Summary: What the Mindmap Adds\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#summary-what-the-mindmap-adds\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Summary: What the Mindmap Adds”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"working-well\">Working Well\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#working-well\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Working Well”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>CategoryPopover provides pre-drill context\u003C/strong> — the analyst sees all category contributions before committing to a filter. This is the Mindmap’s most significant contribution, especially for the Hospital Ward scenario where Night and Afternoon are both visible at 46%/35%.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Active node state tracking\u003C/strong> — after drilling, the node turns blue with ”= Step 2” label, providing clear visual confirmation of what’s filtered. The trail line from Start to active node reinforces the drill path.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Progress bar toward 70% target\u003C/strong> — “Focused on 38% of variation” with a visual bar toward 70% gives the analyst a quantitative sense of investigation completeness.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Drill path footer\u003C/strong> — “Step 38%” chip provides a persistent breadcrumb of the investigation trail.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Narrative mode’s before/after comparison\u003C/strong> — Mean, Cpk, and n changes are shown explicitly, which is exactly the context missing from the boxplot-only workflow.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Investigation prompt nudge\u003C/strong> — appears after first drill, excellent discoverability.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"gaps-that-remain\">Gaps That Remain\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#gaps-that-remain\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Gaps That Remain”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Suggestion metric misleads for dispersion-dominated scenarios\u003C/strong> — Shift (58%) suggested over Step (38%) in Bottleneck data because \u003Ccode dir=\"auto\">maxContribution\u003C/code> measures location, not dispersion.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Step 2 shows 0% in CategoryPopover\u003C/strong> — the hidden bottleneck (high variance, near-average mean) is invisible in the popover’s contribution ranking. This is the most critical analytical failure for the Bottleneck use case.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>No explicit dead-end signal\u003C/strong> — after drilling Step 2, Shift still pulses green at 71%. The implicit “no pulse = dead end” design doesn’t activate because the recalculated metric exceeds the threshold on filtered data.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>No aggregation trap warning\u003C/strong> — the Hospital Ward’s overall mean (75%) represents neither Night (94%) nor Afternoon (47%), but nothing in the Mindmap flags this. The analyst must make the connection manually.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Narrative can’t capture multi-category contrast\u003C/strong> — the Hospital Ward investigation requires comparing Night vs Afternoon within Time_Period, but Narrative mode shows only one drill per factor node.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Panel backdrop blocks filter chip interactions\u003C/strong> — must close the panel to undo drills, creating workflow friction.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>No side-by-side comparison\u003C/strong> — after drilling Step 2, the analyst must remember its I-Chart while drilling Step 3. No mechanism to hold both views simultaneously.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"bugs\">Bugs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#bugs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Bugs”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Contribution metric inconsistency\u003C/strong>: The Shift node shows 58% on the Mindmap but both Shift categories show 0% in the CategoryPopover. \u003Cstrong>Root cause confirmed\u003C/strong>: The node circle uses \u003Ccode dir=\"auto\">calculateCategoryTotalSS\u003C/code> (total SS including within-group spread) while the popover uses \u003Ccode dir=\"auto\">getCategoryStats\u003C/code> (between-group SS only — \u003Ccode dir=\"auto\">n_j * (mean_j - overall_mean)²\u003C/code>). These are fundamentally different formulas producing contradictory results. Code: \u003Ccode dir=\"auto\">packages/core/src/variation/contributions.ts\u003C/code> and \u003Ccode dir=\"auto\">packages/core/src/variation/suggestions.ts\u003C/code>.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Step 2 at 0% in popover\u003C/strong>: The popover’s between-group-only metric \u003Ccode dir=\"auto\">n_j * (mean_j - overall_mean)²\u003C/code> produces 0% for Step 2 because its group mean (~37) is close to the overall mean (~35). The high within-group variance (std=10) is invisible to this metric. This is the most analytically damaging bug for the Bottleneck use case — the popover actively hides the hidden bottleneck.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"recommendations\">Recommendations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#recommendations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Recommendations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"priority-1-fix-contribution-metrics\">Priority 1: Fix Contribution Metrics\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#priority-1-fix-contribution-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Priority 1: Fix Contribution Metrics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Root cause analysis:\u003C/strong> Two different metrics are used, and both have problems:\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Node circle %\u003C/strong> (\u003Ccode dir=\"auto\">getMaxCategoryContribution\u003C/code> -> \u003Ccode dir=\"auto\">calculateCategoryTotalSS\u003C/code>): Computes \u003Ccode dir=\"auto\">Σ(x_ij - overall_mean)² / SS_total\u003C/code> for the single largest category. This includes both mean deviation AND within-group spread, which is correct in principle. But using the \u003Cem>single largest category\u003C/em> favors factors with fewer categories (Shift’s 2 buckets > Step’s 5 buckets), even when the factor itself explains little between-group variance.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Popover category %\u003C/strong> (\u003Ccode dir=\"auto\">getCategoryStats\u003C/code>): Computes \u003Ccode dir=\"auto\">n_j × (mean_j - overall_mean)² / SS_total\u003C/code> — a between-group-only metric. This misses within-group spread entirely, which is why Step 2 (mean ~37, close to overall ~35) shows 0% despite having the highest variance (std=10).\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>The two metrics use fundamentally different formulas\u003C/strong>, creating a contradiction: Shift node shows 58% but both Shift categories show 0% in the popover.\u003C/p>\n\u003Cp>\u003Cstrong>Recommended fix:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>For node suggestion ranking\u003C/strong>: Use ANOVA eta-squared (SS_between / SS_total for each factor). This correctly identifies Step as the dominant factor because Step’s categories have diverse means AND diverse spreads.\u003C/li>\n\u003Cli>\u003Cstrong>For popover category ranking\u003C/strong>: Show a \u003Cem>spread-aware\u003C/em> metric — either within-category contribution to Total SS (the current \u003Ccode dir=\"auto\">calculateCategoryTotalSS\u003C/code> formula, which already includes spread), or IQR/sigma alongside the existing between-group %. This would make Step 2’s high variance visible in the popover.\u003C/li>\n\u003Cli>\u003Cstrong>Ensure consistency\u003C/strong>: The node circle % and popover % sum should be reconcilable — either both use Total SS partitioning or both use between-group SS.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"priority-2-explicit-dead-end-signal\">Priority 2: Explicit Dead-End Signal\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#priority-2-explicit-dead-end-signal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Priority 2: Explicit Dead-End Signal”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When a remaining factor’s contribution drops below a threshold (e.g., 5%) after drilling, show an explicit indicator:\u003C/p>\n\u003Cul>\n\u003Cli>Grey out the node\u003C/li>\n\u003Cli>Show “exhausted” text or icon\u003C/li>\n\u003Cli>Add a tooltip: “This factor explains < 5% of remaining variation”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"priority-3-aggregation-trap-alert\">Priority 3: Aggregation Trap Alert\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#priority-3-aggregation-trap-alert\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Priority 3: Aggregation Trap Alert”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When category means span a wide range relative to the overall mean, show a warning:\u003C/p>\n\u003Cul>\n\u003Cli>“Night (94%) and Afternoon (47%) are far from the overall mean (75%)”\u003C/li>\n\u003Cli>“The overall mean does not represent either subgroup”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"priority-4-multi-category-narrative\">Priority 4: Multi-Category Narrative\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#priority-4-multi-category-narrative\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Priority 4: Multi-Category Narrative”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Allow Narrative mode to capture multiple category drills within the same factor:\u003C/p>\n\u003Cul>\n\u003Cli>“Step 1: Time_Period — investigated Night (94%) and Afternoon (47%), found 47-point gap”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"test-data-reference\">Test Data Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#test-data-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Test Data Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All measurements from \u003Ccode dir=\"auto\">apps/pwa/e2e/mindmap-evaluation.spec.ts\u003C/code> (13 tests, all passing):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Test\u003C/th>\u003Cth>Dataset\u003C/th>\u003Cth>Key Measurement\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1.1\u003C/td>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>Step 38%, Shift 58% (suggested)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.2\u003C/td>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>Step popover: Step 3=37%, Step 2=0%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.3\u003C/td>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>Shift popover: Morning=0%, Afternoon=0%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.4\u003C/td>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>After Step 2 drill: Shift still pulses at 71%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.5\u003C/td>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>Step 2 sigma=9.89, Step 3 sigma=1.94 (5.1x ratio)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2.1\u003C/td>\u003Ctd>Hospital Ward\u003C/td>\u003Ctd>Time_Period 47%, Day_of_Week 16%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2.2\u003C/td>\u003Ctd>Hospital Ward\u003C/td>\u003Ctd>Popover: Night=46%, Afternoon=35%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2.3\u003C/td>\u003Ctd>Hospital Ward\u003C/td>\u003Ctd>Night mean=94.02, Day_of_Week still pulses at 17%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2.4\u003C/td>\u003Ctd>Hospital Ward\u003C/td>\u003Ctd>Afternoon mean=46.68, Day_of_Week pulses at 22%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2.5\u003C/td>\u003Ctd>Hospital Ward\u003C/td>\u003Ctd>Narrative: Mean 75.2->94.0, Cpk 0.64->-0.45\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3.1\u003C/td>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>Mode states: Interactions initially enabled, Narrative disabled\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3.2\u003C/td>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>Panel close: Escape and button both work\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3.3\u003C/td>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>Investigation prompt appears after first boxplot drill\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 5788, + "localImagePaths": 5875, + "remoteImagePaths": 5876, + "frontmatter": 5877, + "imagePaths": 5878 + }, + [ + 5789, 5791, 5794, 5797, 5800, 5803, 5806, 5809, 5812, 5815, 5818, 5821, 5824, 5827, 5830, 5833, + 5836, 5839, 5842, 5845, 5848, 5851, 5854, 5857, 5860, 5863, 5866, 5869, 5872 + ], + { "depth": 30, "slug": 5790, "text": 5778 }, + "chrome-evaluation-mindmap-with-bottleneck--hospital-ward", + { "depth": 33, "slug": 5792, "text": 5793 }, + "summary-of-findings", + "Summary of Findings", + { "depth": 33, "slug": 5795, "text": 5796 }, + "scenario-1-bottleneck-dataset", + "Scenario 1: Bottleneck Dataset", + { "depth": 79, "slug": 5798, "text": 5799 }, + "11-initial-state", + "1.1 Initial State", + { "depth": 79, "slug": 5801, "text": 5802 }, + "12-categorypopover-for-step", + "1.2 CategoryPopover for Step", + { "depth": 79, "slug": 5804, "text": 5805 }, + "13-categorypopover-for-shift", + "1.3 CategoryPopover for Shift", + { "depth": 79, "slug": 5807, "text": 5808 }, + "14-after-drilling-step-2", + "1.4 After Drilling Step 2", + { "depth": 79, "slug": 5810, "text": 5811 }, + "15-step-2-vs-step-3-i-chart-contrast", + "1.5 Step 2 vs Step 3 I-Chart Contrast", + { "depth": 33, "slug": 5813, "text": 5814 }, + "scenario-2-hospital-ward-dataset", + "Scenario 2: Hospital Ward Dataset", + { "depth": 79, "slug": 5816, "text": 5817 }, + "21-initial-state", + "2.1 Initial State", + { "depth": 79, "slug": 5819, "text": 5820 }, + "22-categorypopover--night-and-afternoon-contrast", + "2.2 CategoryPopover — Night and Afternoon Contrast", + { "depth": 79, "slug": 5822, "text": 5823 }, + "23-night-drill--crisis-level", + "2.3 Night Drill — Crisis Level", + { "depth": 79, "slug": 5825, "text": 5826 }, + "24-afternoon-drill--waste-level", + "2.4 Afternoon Drill — Waste Level", + { "depth": 79, "slug": 5828, "text": 5829 }, + "25-narrative-mode", + "2.5 Narrative Mode", + { "depth": 33, "slug": 5831, "text": 5832 }, + "cross-cutting-findings", + "Cross-Cutting Findings", + { "depth": 79, "slug": 5834, "text": 5835 }, + "mode-toggle-states", + "Mode Toggle States", + { "depth": 79, "slug": 5837, "text": 5838 }, + "panel-close-mechanisms", + "Panel Close Mechanisms", + { "depth": 79, "slug": 5840, "text": 5841 }, + "investigation-prompt-nudge", + "Investigation Prompt Nudge", + { "depth": 79, "slug": 5843, "text": 5844 }, + "panel-backdrop-blocks-filter-chips", + "Panel Backdrop Blocks Filter Chips", + { "depth": 33, "slug": 5846, "text": 5847 }, + "summary-what-the-mindmap-adds", + "Summary: What the Mindmap Adds", + { "depth": 79, "slug": 5849, "text": 5850 }, + "working-well", + "Working Well", + { "depth": 79, "slug": 5852, "text": 5853 }, + "gaps-that-remain", + "Gaps That Remain", + { "depth": 79, "slug": 5855, "text": 5856 }, + "bugs", + "Bugs", + { "depth": 33, "slug": 5858, "text": 5859 }, + "recommendations", + "Recommendations", + { "depth": 79, "slug": 5861, "text": 5862 }, + "priority-1-fix-contribution-metrics", + "Priority 1: Fix Contribution Metrics", + { "depth": 79, "slug": 5864, "text": 5865 }, + "priority-2-explicit-dead-end-signal", + "Priority 2: Explicit Dead-End Signal", + { "depth": 79, "slug": 5867, "text": 5868 }, + "priority-3-aggregation-trap-alert", + "Priority 3: Aggregation Trap Alert", + { "depth": 79, "slug": 5870, "text": 5871 }, + "priority-4-multi-category-narrative", + "Priority 4: Multi-Category Narrative", + { "depth": 33, "slug": 5873, "text": 5874 }, + "test-data-reference", + "Test Data Reference", + [], + [], + { "title": 5778 }, + [], + "01-vision/two-voices/control-limits", + { "id": 5879, "data": 5881, "body": 5886, "filePath": 5887, "digest": 5888, "rendered": 5889 }, + { + "title": 5882, + "editUrl": 16, + "head": 5883, + "template": 18, + "sidebar": 5884, + "pagefind": 16, + "draft": 20 + }, + "Voice of the Process: Control Limits", + [], + { "hidden": 20, "attrs": 5885 }, + {}, + "# Voice of the Process: Control Limits\n\n---\n\n## Visualization\n\n```\nUCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Upper Control Limit\n\n ● ● ● ●\n ● ● ● ● Data points\n ● ● ●\nx̄ ═══════════════════════════ Process Mean\n ● ● ●\n ● ● ● ●\n ● ●\n\nLCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Lower Control Limit\n```\n\n---\n\n## What Control Limits Tell You\n\n| Question | Answer |\n| ------------------------ | ------------------------------------------------ |\n| Where do they come from? | **Calculated from your data** (typically x̄ ± 3σ) |\n| What do they represent? | The natural variation of YOUR process |\n| Who sets them? | The process itself — through its behavior |\n| Can you change them? | Only by changing the process |\n\n---\n\n## The Voice of the Process Says:\n\n> \"Given how I currently operate, this is the range of output you can expect from me. Points within my control limits are my normal behavior. Points outside mean something has changed.\"\n\n---\n\n## Control Limits Are NOT:\n\n- ❌ Goals or targets\n- ❌ What you want the process to do\n- ❌ Customer requirements\n- ❌ Arbitrary lines you can move\n- ❌ Good/bad boundaries\n\n---\n\n## Control Limits ARE:\n\n- ✅ Calculated from actual process data\n- ✅ The process speaking for itself\n- ✅ Stability indicators\n- ✅ A baseline for detecting change\n- ✅ Unique to YOUR process\n\n---\n\n## See Also\n\n- [Two Voices Overview](index.md)\n- [Spec Limits](spec-limits.md) — Voice of the customer\n- [Variation Types](variation-types.md) — Special vs common cause variation", + "src/content/docs/01-vision/two-voices/control-limits.md", + "4816d178473eb066", + { "html": 5890, "metadata": 5891 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"voice-of-the-process-control-limits\">Voice of the Process: Control Limits\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#voice-of-the-process-control-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Voice of the Process: Control Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visualization\">Visualization\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visualization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visualization”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Upper Control Limit\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ● Data points\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">x̄ ═══════════════════════════ Process Mean\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Lower Control Limit\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Upper Control Limit ● ● ● ● ● ● ● ● Data points ● ● ●x̄ ═══════════════════════════ Process Mean ● ● ● ● ● ● ● ● ●LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Lower Control Limit\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-control-limits-tell-you\">What Control Limits Tell You\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-control-limits-tell-you\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Control Limits Tell You”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Question\u003C/th>\u003Cth>Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Where do they come from?\u003C/td>\u003Ctd>\u003Cstrong>Calculated from your data\u003C/strong> (typically x̄ ± 3σ)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>What do they represent?\u003C/td>\u003Ctd>The natural variation of YOUR process\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Who sets them?\u003C/td>\u003Ctd>The process itself — through its behavior\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Can you change them?\u003C/td>\u003Ctd>Only by changing the process\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-voice-of-the-process-says\">The Voice of the Process Says:\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-voice-of-the-process-says\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Voice of the Process Says:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“Given how I currently operate, this is the range of output you can expect from me. Points within my control limits are my normal behavior. Points outside mean something has changed.”\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"control-limits-are-not\">Control Limits Are NOT:\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#control-limits-are-not\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Control Limits Are NOT:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>❌ Goals or targets\u003C/li>\n\u003Cli>❌ What you want the process to do\u003C/li>\n\u003Cli>❌ Customer requirements\u003C/li>\n\u003Cli>❌ Arbitrary lines you can move\u003C/li>\n\u003Cli>❌ Good/bad boundaries\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"control-limits-are\">Control Limits ARE:\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#control-limits-are\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Control Limits ARE:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ Calculated from actual process data\u003C/li>\n\u003Cli>✅ The process speaking for itself\u003C/li>\n\u003Cli>✅ Stability indicators\u003C/li>\n\u003Cli>✅ A baseline for detecting change\u003C/li>\n\u003Cli>✅ Unique to YOUR process\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Two Voices Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"spec-limits.md\">Spec Limits\u003C/a> — Voice of the customer\u003C/li>\n\u003Cli>\u003Ca href=\"variation-types.md\">Variation Types\u003C/a> — Special vs common cause variation\u003C/li>\n\u003C/ul>", + { + "headings": 5892, + "localImagePaths": 5911, + "remoteImagePaths": 5912, + "frontmatter": 5913, + "imagePaths": 5914 + }, + [5893, 5895, 5898, 5901, 5904, 5907, 5910], + { "depth": 30, "slug": 5894, "text": 5882 }, + "voice-of-the-process-control-limits", + { "depth": 33, "slug": 5896, "text": 5897 }, + "visualization", + "Visualization", + { "depth": 33, "slug": 5899, "text": 5900 }, + "what-control-limits-tell-you", + "What Control Limits Tell You", + { "depth": 33, "slug": 5902, "text": 5903 }, + "the-voice-of-the-process-says", + "The Voice of the Process Says:", + { "depth": 33, "slug": 5905, "text": 5906 }, + "control-limits-are-not", + "Control Limits Are NOT:", + { "depth": 33, "slug": 5908, "text": 5909 }, + "control-limits-are", + "Control Limits ARE:", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 5882 }, + [], + "01-vision/two-voices", + { "id": 5915, "data": 5917, "body": 5922, "filePath": 5923, "digest": 5924, "rendered": 5925 }, + { + "title": 5918, + "editUrl": 16, + "head": 5919, + "template": 18, + "sidebar": 5920, + "pagefind": 16, + "draft": 20 + }, + "Two Voices: Control Limits vs Specification Limits", + [], + { "hidden": 20, "attrs": 5921 }, + {}, + "# Two Voices: Control Limits vs Specification Limits\n\n> A VariScout educational resource based on ITC Quality Control principles\n\n---\n\n## The Two Voices\n\nEvery process has two voices speaking at the same time:\n\n| Voice | What It Says | Expressed As |\n| ------------------------- | --------------------------------- | ------------------------------ |\n| **Voice of the Process** | \"This is what I actually produce\" | Control Limits (UCL/LCL) |\n| **Voice of the Customer** | \"This is what I need\" | Specification Limits (USL/LSL) |\n\n**The critical insight:** These two voices are independent. The process doesn't know what the customer wants. The customer doesn't know what the process can do.\n\n---\n\n## The Two Voices Together\n\nThe power comes from listening to BOTH voices — and the **goal** is getting them aligned:\n\n```\n VOICE OF CUSTOMER\nUSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nUCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐\n ● ● │\n ● ● ● ● │ VOICE OF\n ● ● ● ● ● │ PROCESS\nx̄ ════════════════════════════════════════════ │ (inside\n ● ● ● ● │ customer\n ● ● ● ● │ requirements)\n ● │\nLCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘\n\nLSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n VOICE OF CUSTOMER\n```\n\n---\n\n## The Goal: Control Limits Within Spec Limits\n\nThe ultimate objective of process improvement:\n\n```\nUSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Voice of Customer\n\n\n UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Voice of Process\n ●●●●●●●●●●●● (INSIDE customer\n x̄ ══════════════════════════ requirements)\n ●●●●●●●●●●●●\n LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\n\n\nLSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Voice of Customer\n```\n\n**When control limits fit within spec limits:**\n\n- Process naturally produces what customer needs\n- No inspection needed — every unit is good\n- Stable AND capable = predictable quality\n- This is the target state\n\n**The journey:**\n\n| State | What It Means | Action |\n| -------------------------------- | ----------------------------------------- | ------------------------------ |\n| Control limits outside specs | Process can't meet requirements naturally | Fundamental improvement needed |\n| Control limits touch specs | Barely capable, at risk | Reduce variation |\n| Control limits within specs | Process naturally meets requirements | ✅ Maintain |\n| Control limits well within specs | Robust capability, room for drift | Ideal state |\n\n---\n\n## The Critical Sequence\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│ │\n│ STEP 1: LISTEN TO THE PROCESS │\n│ │\n│ \"Is it stable?\" │\n│ → Plot I-Chart with Control Limits │\n│ → Look for patterns, trends, out-of-control points │\n│ │\n│ If NOT stable → Find and remove special causes FIRST │\n│ │\n├─────────────────────────────────────────────────────────────────┤\n│ │\n│ STEP 2: LISTEN TO THE CUSTOMER │\n│ │\n│ \"Does it meet specs?\" │\n│ → Plot Capability with Specification Limits │\n│ → Calculate what % falls within specs │\n│ │\n│ If NOT capable → Fundamental process change needed │\n│ │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n**Why this sequence matters:**\n\n| Order | What Happens |\n| ------------------------- | ------------------------------------------------------------------------------------- |\n| Stability THEN Capability | You understand what the process naturally does, then compare to requirements |\n| Capability THEN Stability | You chase numbers without understanding the process — any \"improvement\" is accidental |\n\n---\n\n## Summary\n\n| Concept | Control Limits | Specification Limits |\n| ------------------ | ------------------------ | ----------------------------------------- |\n| **Voice** | Process | Customer |\n| **Source** | Calculated from data | Defined by requirements |\n| **Question** | \"Is it stable?\" | \"Does it meet needs?\" |\n| **Chart** | I-Chart | Capability (and I-Chart when specs added) |\n| **Can change?** | Only by changing process | Only by negotiating |\n| **VariScout Lens** | CHANGE | VALUE |\n\n**The key insight:**\n\n> Listen to both voices. The process tells you what it CAN do. The customer tells you what it MUST do. The goal is alignment — control limits within spec limits. VariScout helps you see both voices and find WHERE to focus when they don't align.\n\n---\n\n## Learn More\n\n- [Control Limits](control-limits.md) — Voice of the process\n- [Spec Limits](spec-limits.md) — Voice of the customer\n- [Variation Types](variation-types.md) — Special vs common cause\n- [Four Scenarios](scenarios.md) — When voices align (or don't)\n\n---\n\n## Reference\n\nBased on quality control principles as documented in:\n\n- ITC Quality Control Manual for Coffee\n- Shewhart's foundational work on control charts\n- Wheeler's \"Understanding Variation\"\n- Watson's Four Lenses of Process Knowledge\n\n---\n\n_\"Control limits are the voice of the process. Specification limits are the voice of the customer. The goal is to get the process voice inside the customer voice — then quality happens naturally.\"_", + "src/content/docs/01-vision/two-voices/index.md", + "2122877bb36851ba", + { "html": 5926, "metadata": 5927 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"two-voices-control-limits-vs-specification-limits\">Two Voices: Control Limits vs Specification Limits\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#two-voices-control-limits-vs-specification-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two Voices: Control Limits vs Specification Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>A VariScout educational resource based on ITC Quality Control principles\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-two-voices\">The Two Voices\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-two-voices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Two Voices”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every process has two voices speaking at the same time:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Voice\u003C/th>\u003Cth>What It Says\u003C/th>\u003Cth>Expressed As\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Voice of the Process\u003C/strong>\u003C/td>\u003Ctd>”This is what I actually produce”\u003C/td>\u003Ctd>Control Limits (UCL/LCL)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Voice of the Customer\u003C/strong>\u003C/td>\u003Ctd>”This is what I need”\u003C/td>\u003Ctd>Specification Limits (USL/LSL)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>The critical insight:\u003C/strong> These two voices are independent. The process doesn’t know what the customer wants. The customer doesn’t know what the process can do.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-two-voices-together\">The Two Voices Together\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-two-voices-together\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Two Voices Together”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The power comes from listening to BOTH voices — and the \u003Cstrong>goal\u003C/strong> is getting them aligned:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">VOICE OF CUSTOMER\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ● │ VOICE OF\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ● ● │ PROCESS\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">x̄ ════════════════════════════════════════════ │ (inside\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ● │ customer\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ● │ requirements)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">VOICE OF CUSTOMER\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" VOICE OF CUSTOMERUSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ● ● │ ● ● ● ● │ VOICE OF ● ● ● ● ● │ PROCESSx̄ ════════════════════════════════════════════ │ (inside ● ● ● ● │ customer ● ● ● ● │ requirements) ● │LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ VOICE OF CUSTOMER\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-goal-control-limits-within-spec-limits\">The Goal: Control Limits Within Spec Limits\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-goal-control-limits-within-spec-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Goal: Control Limits Within Spec Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The ultimate objective of process improvement:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Voice of Customer\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Voice of Process\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">●●●●●●●●●●●● (INSIDE customer\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">x̄ ══════════════════════════ requirements)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">●●●●●●●●●●●●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Voice of Customer\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Voice of Customer UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Voice of Process ●●●●●●●●●●●● (INSIDE customer x̄ ══════════════════════════ requirements) ●●●●●●●●●●●● LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Voice of Customer\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>When control limits fit within spec limits:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Process naturally produces what customer needs\u003C/li>\n\u003Cli>No inspection needed — every unit is good\u003C/li>\n\u003Cli>Stable AND capable = predictable quality\u003C/li>\n\u003Cli>This is the target state\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>The journey:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>State\u003C/th>\u003Cth>What It Means\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Control limits outside specs\u003C/td>\u003Ctd>Process can’t meet requirements naturally\u003C/td>\u003Ctd>Fundamental improvement needed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Control limits touch specs\u003C/td>\u003Ctd>Barely capable, at risk\u003C/td>\u003Ctd>Reduce variation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Control limits within specs\u003C/td>\u003Ctd>Process naturally meets requirements\u003C/td>\u003Ctd>✅ Maintain\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Control limits well within specs\u003C/td>\u003Ctd>Robust capability, room for drift\u003C/td>\u003Ctd>Ideal state\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-critical-sequence\">The Critical Sequence\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-critical-sequence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Critical Sequence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ STEP 1: LISTEN TO THE PROCESS │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Is it stable?\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ → Plot I-Chart with Control Limits │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ → Look for patterns, trends, out-of-control points │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ If NOT stable → Find and remove special causes FIRST │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ STEP 2: LISTEN TO THE CUSTOMER │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Does it meet specs?\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ → Plot Capability with Specification Limits │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ → Calculate what % falls within specs │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ If NOT capable → Fundamental process change needed │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────┐│ ││ STEP 1: LISTEN TO THE PROCESS ││ ││ "Is it stable?" ││ → Plot I-Chart with Control Limits ││ → Look for patterns, trends, out-of-control points ││ ││ If NOT stable → Find and remove special causes FIRST ││ │├─────────────────────────────────────────────────────────────────┤│ ││ STEP 2: LISTEN TO THE CUSTOMER ││ ││ "Does it meet specs?" ││ → Plot Capability with Specification Limits ││ → Calculate what % falls within specs ││ ││ If NOT capable → Fundamental process change needed ││ │└─────────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Why this sequence matters:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Order\u003C/th>\u003Cth>What Happens\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Stability THEN Capability\u003C/td>\u003Ctd>You understand what the process naturally does, then compare to requirements\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability THEN Stability\u003C/td>\u003Ctd>You chase numbers without understanding the process — any “improvement” is accidental\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"summary\">Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Summary”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Concept\u003C/th>\u003Cth>Control Limits\u003C/th>\u003Cth>Specification Limits\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Voice\u003C/strong>\u003C/td>\u003Ctd>Process\u003C/td>\u003Ctd>Customer\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Source\u003C/strong>\u003C/td>\u003Ctd>Calculated from data\u003C/td>\u003Ctd>Defined by requirements\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Question\u003C/strong>\u003C/td>\u003Ctd>”Is it stable?\"\u003C/td>\u003Ctd>\"Does it meet needs?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Chart\u003C/strong>\u003C/td>\u003Ctd>I-Chart\u003C/td>\u003Ctd>Capability (and I-Chart when specs added)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Can change?\u003C/strong>\u003C/td>\u003Ctd>Only by changing process\u003C/td>\u003Ctd>Only by negotiating\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>VariScout Lens\u003C/strong>\u003C/td>\u003Ctd>CHANGE\u003C/td>\u003Ctd>VALUE\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>The key insight:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>Listen to both voices. The process tells you what it CAN do. The customer tells you what it MUST do. The goal is alignment — control limits within spec limits. VariScout helps you see both voices and find WHERE to focus when they don’t align.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"learn-more\">Learn More\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#learn-more\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Learn More”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"control-limits.md\">Control Limits\u003C/a> — Voice of the process\u003C/li>\n\u003Cli>\u003Ca href=\"spec-limits.md\">Spec Limits\u003C/a> — Voice of the customer\u003C/li>\n\u003Cli>\u003Ca href=\"variation-types.md\">Variation Types\u003C/a> — Special vs common cause\u003C/li>\n\u003Cli>\u003Ca href=\"scenarios.md\">Four Scenarios\u003C/a> — When voices align (or don’t)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"reference\">Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Based on quality control principles as documented in:\u003C/p>\n\u003Cul>\n\u003Cli>ITC Quality Control Manual for Coffee\u003C/li>\n\u003Cli>Shewhart’s foundational work on control charts\u003C/li>\n\u003Cli>Wheeler’s “Understanding Variation”\u003C/li>\n\u003Cli>Watson’s Four Lenses of Process Knowledge\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cem>“Control limits are the voice of the process. Specification limits are the voice of the customer. The goal is to get the process voice inside the customer voice — then quality happens naturally.”\u003C/em>\u003C/p>", + { + "headings": 5928, + "localImagePaths": 5950, + "remoteImagePaths": 5951, + "frontmatter": 5952, + "imagePaths": 5953 + }, + [5929, 5931, 5934, 5937, 5940, 5943, 5944, 5947], + { "depth": 30, "slug": 5930, "text": 5918 }, + "two-voices-control-limits-vs-specification-limits", + { "depth": 33, "slug": 5932, "text": 5933 }, + "the-two-voices", + "The Two Voices", + { "depth": 33, "slug": 5935, "text": 5936 }, + "the-two-voices-together", + "The Two Voices Together", + { "depth": 33, "slug": 5938, "text": 5939 }, + "the-goal-control-limits-within-spec-limits", + "The Goal: Control Limits Within Spec Limits", + { "depth": 33, "slug": 5941, "text": 5942 }, + "the-critical-sequence", + "The Critical Sequence", + { "depth": 33, "slug": 1450, "text": 1451 }, + { "depth": 33, "slug": 5945, "text": 5946 }, + "learn-more", + "Learn More", + { "depth": 33, "slug": 5948, "text": 5949 }, + "reference", + "Reference", + [], + [], + { "title": 5918 }, + [], + "01-vision/two-voices/scenarios", + { "id": 5954, "data": 5956, "body": 5961, "filePath": 5962, "digest": 5963, "rendered": 5964 }, + { + "title": 5957, + "editUrl": 16, + "head": 5958, + "template": 18, + "sidebar": 5959, + "pagefind": 16, + "draft": 20 + }, + "Four Scenarios: When the Voices Align (or Don't)", + [], + { "hidden": 20, "attrs": 5960 }, + {}, + "# Four Scenarios: When the Voices Align (or Don't)\n\n---\n\n## Scenario 1: Stable AND Capable ✅\n\n```\nUSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nUCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\n ●●●●●●●●●●●●\nx̄ ══════════════════════════════\n ●●●●●●●●●●●●\nLCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\nLSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n```\n\n| Voice of Process | Voice of Customer | Status |\n| ---------------- | ------------------- | -------------- |\n| \"I'm stable\" | \"You meet my needs\" | ✅ Ideal state |\n\n**Action:** Maintain. Monitor. Don't over-adjust.\n\n---\n\n## Scenario 2: Stable but NOT Capable ⚠️\n\n```\nUSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n ●●●●●●●●●●●● } Some output\nx̄ ══════════════════════════════ } exceeds specs\n ●●●●●●●●●●●● }\nLSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n```\n\n| Voice of Process | Voice of Customer | Status |\n| ------------------------------ | ------------------------- | ---------------------- |\n| \"I'm stable — this is my best\" | \"You don't meet my needs\" | ⚠️ Fundamental problem |\n\n**Action:** The process IS stable — this is what it naturally produces. You cannot \"try harder.\" You must **fundamentally change the process** (equipment, method, materials) or **renegotiate specs** with customer.\n\n---\n\n## Scenario 3: Capable but NOT Stable ⚠️\n\n```\nUSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n ● } Unstable points\n ●●●●●●●●●● } but within\nx̄ ══════════════════════════════ } spec limits\n ●●●●●●●●● }\n ● }\nLSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n```\n\n| Voice of Process | Voice of Customer | Status |\n| ------------------- | ----------------------------- | -------- |\n| \"I'm unpredictable\" | \"You meet my needs (for now)\" | ⚠️ Risky |\n\n**Action:** Dangerous situation! Currently meeting specs but not predictable. A special cause could push output outside specs at any time. **Find and remove the instability sources** before disaster.\n\n---\n\n## Scenario 4: Neither Stable NOR Capable ❌\n\n```\n ● } Chaos\nUSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n ● ● } AND\n ● ● ● } failing\nx̄ ══════════════════════════════ } specs\n ● ● ● }\n ● }\nLSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n ● }\n```\n\n| Voice of Process | Voice of Customer | Status |\n| ------------------- | ------------------------- | --------- |\n| \"I'm unpredictable\" | \"You don't meet my needs\" | ❌ Crisis |\n\n**Action:** **Stabilize first, then improve capability.** Trying to fix capability while unstable is futile — you're chasing variation, not understanding it.\n\n---\n\n## Common Mistakes\n\n### Mistake 1: Confusing the Two Limits\n\n❌ \"Our UCL is 15 because that's the max the customer accepts\"\n\n✅ \"Our USL is 15 (customer requirement). Our UCL is 13.2 (calculated from our data).\"\n\n---\n\n### Mistake 2: Adjusting Process to Hit Spec Limits\n\n❌ \"We're at 14.8, getting close to the USL of 15. Better adjust down!\"\n\n✅ \"Is that point within our control limits? If yes, it's normal variation — don't adjust. If no, find out why.\"\n\n:::caution\n**Tampering with a stable process increases variation.**\n:::\n\n---\n\n### Mistake 3: Celebrating When Within Spec\n\n❌ \"All our output is within spec! We're done!\"\n\n✅ \"Is the process stable? If not, we're lucky today but at risk tomorrow.\"\n\n---\n\n### Mistake 4: Setting Control Limits from Specs\n\n❌ \"Let's set our control limits at ±10% of the spec limit\"\n\n✅ \"Control limits must be calculated from actual process data. They cannot be chosen.\"\n\n---\n\n## See Also\n\n- [Two Voices Overview](index.md)\n- [Variation Types](variation-types.md) — Special vs common cause", + "src/content/docs/01-vision/two-voices/scenarios.md", + "d5940024a5e2a64b", + { "html": 5965, "metadata": 5966 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"four-scenarios-when-the-voices-align-or-dont\">Four Scenarios: When the Voices Align (or Don’t)\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#four-scenarios-when-the-voices-align-or-dont\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Four Scenarios: When the Voices Align (or Don’t)”\u003C/span>\u003C/a>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"scenario-1-stable-and-capable\">Scenario 1: Stable AND Capable ✅\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#scenario-1-stable-and-capable\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario 1: Stable AND Capable ✅”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">●●●●●●●●●●●●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">x̄ ══════════════════════════════\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">●●●●●●●●●●●●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ●●●●●●●●●●●●x̄ ══════════════════════════════ ●●●●●●●●●●●●LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Voice of Process\u003C/th>\u003Cth>Voice of Customer\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”I’m stable\"\u003C/td>\u003Ctd>\"You meet my needs”\u003C/td>\u003Ctd>✅ Ideal state\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Action:\u003C/strong> Maintain. Monitor. Don’t over-adjust.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"scenario-2-stable-but-not-capable-️\">Scenario 2: Stable but NOT Capable ⚠️\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#scenario-2-stable-but-not-capable-️\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario 2: Stable but NOT Capable ⚠️”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">●●●●●●●●●●●● } Some output\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">x̄ ══════════════════════════════ } exceeds specs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">●●●●●●●●●●●● }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ●●●●●●●●●●●● } Some outputx̄ ══════════════════════════════ } exceeds specs ●●●●●●●●●●●● }LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Voice of Process\u003C/th>\u003Cth>Voice of Customer\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”I’m stable — this is my best\"\u003C/td>\u003Ctd>\"You don’t meet my needs”\u003C/td>\u003Ctd>⚠️ Fundamental problem\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Action:\u003C/strong> The process IS stable — this is what it naturally produces. You cannot “try harder.” You must \u003Cstrong>fundamentally change the process\u003C/strong> (equipment, method, materials) or \u003Cstrong>renegotiate specs\u003C/strong> with customer.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"scenario-3-capable-but-not-stable-️\">Scenario 3: Capable but NOT Stable ⚠️\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#scenario-3-capable-but-not-stable-️\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario 3: Capable but NOT Stable ⚠️”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● } Unstable points\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">●●●●●●●●●● } but within\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">x̄ ══════════════════════════════ } spec limits\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">●●●●●●●●● }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ● } Unstable points ●●●●●●●●●● } but withinx̄ ══════════════════════════════ } spec limits ●●●●●●●●● } ● }LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Voice of Process\u003C/th>\u003Cth>Voice of Customer\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”I’m unpredictable\"\u003C/td>\u003Ctd>\"You meet my needs (for now)“\u003C/td>\u003Ctd>⚠️ Risky\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Action:\u003C/strong> Dangerous situation! Currently meeting specs but not predictable. A special cause could push output outside specs at any time. \u003Cstrong>Find and remove the instability sources\u003C/strong> before disaster.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"scenario-4-neither-stable-nor-capable\">Scenario 4: Neither Stable NOR Capable ❌\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#scenario-4-neither-stable-nor-capable\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario 4: Neither Stable NOR Capable ❌”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● } Chaos\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● } AND\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● } failing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">x̄ ══════════════════════════════ } specs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● }\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" ● } ChaosUSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ● ● } AND ● ● ● } failingx̄ ══════════════════════════════ } specs ● ● ● } ● }LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ● }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Voice of Process\u003C/th>\u003Cth>Voice of Customer\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”I’m unpredictable\"\u003C/td>\u003Ctd>\"You don’t meet my needs”\u003C/td>\u003Ctd>❌ Crisis\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Action:\u003C/strong> \u003Cstrong>Stabilize first, then improve capability.\u003C/strong> Trying to fix capability while unstable is futile — you’re chasing variation, not understanding it.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"common-mistakes\">Common Mistakes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#common-mistakes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Mistakes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mistake-1-confusing-the-two-limits\">Mistake 1: Confusing the Two Limits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mistake-1-confusing-the-two-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mistake 1: Confusing the Two Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>❌ “Our UCL is 15 because that’s the max the customer accepts”\u003C/p>\n\u003Cp>✅ “Our USL is 15 (customer requirement). Our UCL is 13.2 (calculated from our data).”\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mistake-2-adjusting-process-to-hit-spec-limits\">Mistake 2: Adjusting Process to Hit Spec Limits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mistake-2-adjusting-process-to-hit-spec-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mistake 2: Adjusting Process to Hit Spec Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>❌ “We’re at 14.8, getting close to the USL of 15. Better adjust down!”\u003C/p>\n\u003Cp>✅ “Is that point within our control limits? If yes, it’s normal variation — don’t adjust. If no, find out why.”\u003C/p>\n\u003Caside aria-label=\"Caution\" class=\"starlight-aside starlight-aside--caution\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath d=\"M12 16C11.8022 16 11.6089 16.0587 11.4444 16.1686C11.28 16.2784 11.1518 16.4346 11.0761 16.6173C11.0004 16.8001 10.9806 17.0011 11.0192 17.1951C11.0578 17.3891 11.153 17.5673 11.2929 17.7071C11.4327 17.847 11.6109 17.9422 11.8049 17.9808C11.9989 18.0194 12.2 17.9996 12.3827 17.9239C12.5654 17.8482 12.7216 17.72 12.8315 17.5556C12.9413 17.3911 13 17.1978 13 17C13 16.7348 12.8946 16.4805 12.7071 16.2929C12.5196 16.1054 12.2652 16 12 16ZM22.67 17.47L14.62 3.47003C14.3598 3.00354 13.9798 2.61498 13.5192 2.3445C13.0586 2.07401 12.5341 1.9314 12 1.9314C11.4659 1.9314 10.9414 2.07401 10.4808 2.3445C10.0202 2.61498 9.64019 3.00354 9.38 3.47003L1.38 17.47C1.11079 17.924 0.966141 18.441 0.960643 18.9688C0.955144 19.4966 1.089 20.0166 1.34868 20.4761C1.60837 20.9356 1.9847 21.3185 2.43968 21.5861C2.89466 21.8536 3.41218 21.9964 3.94 22H20.06C20.5921 22.0053 21.1159 21.8689 21.5779 21.6049C22.0399 21.341 22.4234 20.9589 22.689 20.4978C22.9546 20.0368 23.0928 19.5134 23.0895 18.9814C23.0862 18.4493 22.9414 17.9277 22.67 17.47ZM20.94 19.47C20.8523 19.626 20.7245 19.7556 20.5697 19.8453C20.4149 19.935 20.2389 19.9815 20.06 19.98H3.94C3.76111 19.9815 3.5851 19.935 3.43032 19.8453C3.27553 19.7556 3.14765 19.626 3.06 19.47C2.97223 19.318 2.92602 19.1456 2.92602 18.97C2.92602 18.7945 2.97223 18.622 3.06 18.47L11.06 4.47003C11.1439 4.30623 11.2714 4.16876 11.4284 4.07277C11.5855 3.97678 11.766 3.92599 11.95 3.92599C12.134 3.92599 12.3145 3.97678 12.4716 4.07277C12.6286 4.16876 12.7561 4.30623 12.84 4.47003L20.89 18.47C20.9892 18.6199 21.0462 18.7937 21.055 18.9732C21.0638 19.1527 21.0241 19.3312 20.94 19.49V19.47ZM12 8.00003C11.7348 8.00003 11.4804 8.10538 11.2929 8.29292C11.1054 8.48046 11 8.73481 11 9.00003V13C11 13.2652 11.1054 13.5196 11.2929 13.7071C11.4804 13.8947 11.7348 14 12 14C12.2652 14 12.5196 13.8947 12.7071 13.7071C12.8946 13.5196 13 13.2652 13 13V9.00003C13 8.73481 12.8946 8.48046 12.7071 8.29292C12.5196 8.10538 12.2652 8.00003 12 8.00003Z\">\u003C/path>\u003C/svg>Caution\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>\u003Cstrong>Tampering with a stable process increases variation.\u003C/strong>\u003C/p>\u003C/div>\u003C/aside>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mistake-3-celebrating-when-within-spec\">Mistake 3: Celebrating When Within Spec\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mistake-3-celebrating-when-within-spec\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mistake 3: Celebrating When Within Spec”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>❌ “All our output is within spec! We’re done!”\u003C/p>\n\u003Cp>✅ “Is the process stable? If not, we’re lucky today but at risk tomorrow.”\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mistake-4-setting-control-limits-from-specs\">Mistake 4: Setting Control Limits from Specs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mistake-4-setting-control-limits-from-specs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mistake 4: Setting Control Limits from Specs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>❌ “Let’s set our control limits at ±10% of the spec limit”\u003C/p>\n\u003Cp>✅ “Control limits must be calculated from actual process data. They cannot be chosen.”\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Two Voices Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"variation-types.md\">Variation Types\u003C/a> — Special vs common cause\u003C/li>\n\u003C/ul>", + { + "headings": 5967, + "localImagePaths": 5999, + "remoteImagePaths": 6000, + "frontmatter": 6001, + "imagePaths": 6002 + }, + [5968, 5971, 5974, 5977, 5980, 5983, 5986, 5989, 5992, 5995, 5998], + { "depth": 30, "slug": 5969, "text": 5970 }, + "four-scenarios-when-the-voices-align-or-dont", + "Four Scenarios: When the Voices Align (or Don’t)", + { "depth": 33, "slug": 5972, "text": 5973 }, + "scenario-1-stable-and-capable", + "Scenario 1: Stable AND Capable ✅", + { "depth": 33, "slug": 5975, "text": 5976 }, + "scenario-2-stable-but-not-capable-️", + "Scenario 2: Stable but NOT Capable ⚠️", + { "depth": 33, "slug": 5978, "text": 5979 }, + "scenario-3-capable-but-not-stable-️", + "Scenario 3: Capable but NOT Stable ⚠️", + { "depth": 33, "slug": 5981, "text": 5982 }, + "scenario-4-neither-stable-nor-capable", + "Scenario 4: Neither Stable NOR Capable ❌", + { "depth": 33, "slug": 5984, "text": 5985 }, + "common-mistakes", + "Common Mistakes", + { "depth": 79, "slug": 5987, "text": 5988 }, + "mistake-1-confusing-the-two-limits", + "Mistake 1: Confusing the Two Limits", + { "depth": 79, "slug": 5990, "text": 5991 }, + "mistake-2-adjusting-process-to-hit-spec-limits", + "Mistake 2: Adjusting Process to Hit Spec Limits", + { "depth": 79, "slug": 5993, "text": 5994 }, + "mistake-3-celebrating-when-within-spec", + "Mistake 3: Celebrating When Within Spec", + { "depth": 79, "slug": 5996, "text": 5997 }, + "mistake-4-setting-control-limits-from-specs", + "Mistake 4: Setting Control Limits from Specs", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 5957 }, + [], + "01-vision/two-voices/spec-limits", + { "id": 6003, "data": 6005, "body": 6010, "filePath": 6011, "digest": 6012, "rendered": 6013 }, + { + "title": 6006, + "editUrl": 16, + "head": 6007, + "template": 18, + "sidebar": 6008, + "pagefind": 16, + "draft": 20 + }, + "Voice of the Customer: Specification Limits", + [], + { "hidden": 20, "attrs": 6009 }, + {}, + "# Voice of the Customer: Specification Limits\n\n---\n\n## Visualization\n\n```\nUSL ━━━━━━━━━━━━━━━━━━━━━━━━━ Upper Specification Limit\n \"Maximum acceptable\"\n\n\n █████████████████████\n ███████████████████████ Distribution of\n █████████████████████████ process output\n ███████████████████████████\n\n\nLSL ━━━━━━━━━━━━━━━━━━━━━━━━━ Lower Specification Limit\n \"Minimum acceptable\"\n```\n\n---\n\n## What Specification Limits Tell You\n\n| Question | Answer |\n| ------------------------ | ------------------------------------------------------- |\n| Where do they come from? | **Customer requirements** (contracts, standards, needs) |\n| What do they represent? | The boundary between acceptable and unacceptable |\n| Who sets them? | The customer — based on their needs |\n| Can you change them? | Only by negotiating with the customer |\n\n---\n\n## The Voice of the Customer Says:\n\n> \"I don't care how your process works. I need the output to be between these limits. Anything outside is unacceptable to me.\"\n\n---\n\n## Specification Limits Are NOT:\n\n- ❌ Calculated from your data\n- ❌ Related to your process capability\n- ❌ Indicators of process stability\n- ❌ Something you can change unilaterally\n\n---\n\n## Specification Limits ARE:\n\n- ✅ Defined by customer requirements\n- ✅ The customer speaking for themselves\n- ✅ Accept/reject boundaries\n- ✅ External to your process\n- ✅ Fixed unless customer agrees to change\n\n---\n\n## The ITC Coffee Example\n\nIn coffee quality control, the two voices are especially clear:\n\n### Voice of the Customer (Buyer)\n\n| Attribute | Specification |\n| ----------- | ----------------------- |\n| Moisture | 10-12% |\n| Screen Size | Min 80% above Screen 15 |\n| Defects | Max 5 per 300g |\n| Cup Score | Min 80 points |\n\n> \"I will pay premium price only if coffee meets these specifications.\"\n\n### Voice of the Process (Wet Mill)\n\n| Attribute | What Process Produces |\n| ----------- | --------------------- |\n| Moisture | x̄ = 11.2%, σ = 0.8% |\n| Screen Size | x̄ = 76% above 15 |\n| Defects | x̄ = 8.3 per 300g |\n| Cup Score | x̄ = 78.5 points |\n\n> \"Given current fermentation, drying, and sorting — this is what I produce.\"\n\n### The Gap\n\n| Attribute | Customer Wants | Process Delivers | Gap |\n| ----------- | -------------- | ---------------- | -------------- |\n| Moisture | 10-12% | 11.2% ± 0.8% | ✅ Capable |\n| Screen Size | >80% | 76% | ❌ Not capable |\n| Defects | \u003C5 | 8.3 | ❌ Not capable |\n| Cup Score | >80 | 78.5 | ❌ Not capable |\n\n### The Action\n\nDon't just \"try harder\" on sorting. The **process** produces this output naturally. Change requires:\n\n- Better cherry selection (FLOW)\n- Improved fermentation timing (CHANGE)\n- Enhanced drying protocols (CHANGE)\n- Investment in sorting equipment (process change)\n\n---\n\n## See Also\n\n- [Two Voices Overview](index.md)\n- [Control Limits](control-limits.md) — Voice of the process\n- [Four Scenarios](scenarios.md) — When voices align (or don't)", + "src/content/docs/01-vision/two-voices/spec-limits.md", + "0e4719a58acaf8a9", + { "html": 6014, "metadata": 6015 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"voice-of-the-customer-specification-limits\">Voice of the Customer: Specification Limits\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#voice-of-the-customer-specification-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Voice of the Customer: Specification Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visualization\">Visualization\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visualization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visualization”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USL ━━━━━━━━━━━━━━━━━━━━━━━━━ Upper Specification Limit\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"Maximum acceptable\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">█████████████████████\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">███████████████████████ Distribution of\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">█████████████████████████ process output\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">███████████████████████████\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LSL ━━━━━━━━━━━━━━━━━━━━━━━━━ Lower Specification Limit\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"Minimum acceptable\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"USL ━━━━━━━━━━━━━━━━━━━━━━━━━ Upper Specification Limit "Maximum acceptable" █████████████████████ ███████████████████████ Distribution of █████████████████████████ process output ███████████████████████████LSL ━━━━━━━━━━━━━━━━━━━━━━━━━ Lower Specification Limit "Minimum acceptable"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-specification-limits-tell-you\">What Specification Limits Tell You\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-specification-limits-tell-you\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Specification Limits Tell You”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Question\u003C/th>\u003Cth>Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Where do they come from?\u003C/td>\u003Ctd>\u003Cstrong>Customer requirements\u003C/strong> (contracts, standards, needs)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>What do they represent?\u003C/td>\u003Ctd>The boundary between acceptable and unacceptable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Who sets them?\u003C/td>\u003Ctd>The customer — based on their needs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Can you change them?\u003C/td>\u003Ctd>Only by negotiating with the customer\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-voice-of-the-customer-says\">The Voice of the Customer Says:\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-voice-of-the-customer-says\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Voice of the Customer Says:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“I don’t care how your process works. I need the output to be between these limits. Anything outside is unacceptable to me.”\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"specification-limits-are-not\">Specification Limits Are NOT:\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#specification-limits-are-not\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Specification Limits Are NOT:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>❌ Calculated from your data\u003C/li>\n\u003Cli>❌ Related to your process capability\u003C/li>\n\u003Cli>❌ Indicators of process stability\u003C/li>\n\u003Cli>❌ Something you can change unilaterally\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"specification-limits-are\">Specification Limits ARE:\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#specification-limits-are\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Specification Limits ARE:”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>✅ Defined by customer requirements\u003C/li>\n\u003Cli>✅ The customer speaking for themselves\u003C/li>\n\u003Cli>✅ Accept/reject boundaries\u003C/li>\n\u003Cli>✅ External to your process\u003C/li>\n\u003Cli>✅ Fixed unless customer agrees to change\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-itc-coffee-example\">The ITC Coffee Example\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-itc-coffee-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The ITC Coffee Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>In coffee quality control, the two voices are especially clear:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"voice-of-the-customer-buyer\">Voice of the Customer (Buyer)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#voice-of-the-customer-buyer\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Voice of the Customer (Buyer)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Specification\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Moisture\u003C/td>\u003Ctd>10-12%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Screen Size\u003C/td>\u003Ctd>Min 80% above Screen 15\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Defects\u003C/td>\u003Ctd>Max 5 per 300g\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cup Score\u003C/td>\u003Ctd>Min 80 points\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>“I will pay premium price only if coffee meets these specifications.”\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"voice-of-the-process-wet-mill\">Voice of the Process (Wet Mill)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#voice-of-the-process-wet-mill\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Voice of the Process (Wet Mill)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>What Process Produces\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Moisture\u003C/td>\u003Ctd>x̄ = 11.2%, σ = 0.8%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Screen Size\u003C/td>\u003Ctd>x̄ = 76% above 15\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Defects\u003C/td>\u003Ctd>x̄ = 8.3 per 300g\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cup Score\u003C/td>\u003Ctd>x̄ = 78.5 points\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>“Given current fermentation, drying, and sorting — this is what I produce.”\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-gap\">The Gap\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-gap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Gap”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Customer Wants\u003C/th>\u003Cth>Process Delivers\u003C/th>\u003Cth>Gap\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Moisture\u003C/td>\u003Ctd>10-12%\u003C/td>\u003Ctd>11.2% ± 0.8%\u003C/td>\u003Ctd>✅ Capable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Screen Size\u003C/td>\u003Ctd>>80%\u003C/td>\u003Ctd>76%\u003C/td>\u003Ctd>❌ Not capable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Defects\u003C/td>\u003Ctd><5\u003C/td>\u003Ctd>8.3\u003C/td>\u003Ctd>❌ Not capable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cup Score\u003C/td>\u003Ctd>>80\u003C/td>\u003Ctd>78.5\u003C/td>\u003Ctd>❌ Not capable\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-action\">The Action\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-action\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Action”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Don’t just “try harder” on sorting. The \u003Cstrong>process\u003C/strong> produces this output naturally. Change requires:\u003C/p>\n\u003Cul>\n\u003Cli>Better cherry selection (FLOW)\u003C/li>\n\u003Cli>Improved fermentation timing (CHANGE)\u003C/li>\n\u003Cli>Enhanced drying protocols (CHANGE)\u003C/li>\n\u003Cli>Investment in sorting equipment (process change)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Two Voices Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"control-limits.md\">Control Limits\u003C/a> — Voice of the process\u003C/li>\n\u003Cli>\u003Ca href=\"scenarios.md\">Four Scenarios\u003C/a> — When voices align (or don’t)\u003C/li>\n\u003C/ul>", + { + "headings": 6016, + "localImagePaths": 6048, + "remoteImagePaths": 6049, + "frontmatter": 6050, + "imagePaths": 6051 + }, + [6017, 6019, 6020, 6023, 6026, 6029, 6032, 6035, 6038, 6041, 6044, 6047], + { "depth": 30, "slug": 6018, "text": 6006 }, + "voice-of-the-customer-specification-limits", + { "depth": 33, "slug": 5896, "text": 5897 }, + { "depth": 33, "slug": 6021, "text": 6022 }, + "what-specification-limits-tell-you", + "What Specification Limits Tell You", + { "depth": 33, "slug": 6024, "text": 6025 }, + "the-voice-of-the-customer-says", + "The Voice of the Customer Says:", + { "depth": 33, "slug": 6027, "text": 6028 }, + "specification-limits-are-not", + "Specification Limits Are NOT:", + { "depth": 33, "slug": 6030, "text": 6031 }, + "specification-limits-are", + "Specification Limits ARE:", + { "depth": 33, "slug": 6033, "text": 6034 }, + "the-itc-coffee-example", + "The ITC Coffee Example", + { "depth": 79, "slug": 6036, "text": 6037 }, + "voice-of-the-customer-buyer", + "Voice of the Customer (Buyer)", + { "depth": 79, "slug": 6039, "text": 6040 }, + "voice-of-the-process-wet-mill", + "Voice of the Process (Wet Mill)", + { "depth": 79, "slug": 6042, "text": 6043 }, + "the-gap", + "The Gap", + { "depth": 79, "slug": 6045, "text": 6046 }, + "the-action", + "The Action", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6006 }, + [], + "01-vision/two-voices/variation-types", + { "id": 6052, "data": 6054, "body": 6059, "filePath": 6060, "digest": 6061, "rendered": 6062 }, + { + "title": 6055, + "editUrl": 16, + "head": 6056, + "template": 18, + "sidebar": 6057, + "pagefind": 16, + "draft": 20 + }, + "Two Types of Variation, Two Types of Action", + [], + { "hidden": 20, "attrs": 6058 }, + {}, + "# Two Types of Variation, Two Types of Action\n\nThe I-Chart reveals patterns — but what you DO about them depends on what TYPE of variation you're seeing.\n\n---\n\n## Special Cause Variation\n\n```\nUCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\n ● ← Point outside limits\n ● ● ● ●\n ● ● ● ●\nx̄ ═══════════════════════════════════\n ● ● ●\n ● ● ● ●\nLCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\n```\n\n| Characteristic | Special Cause |\n| -------------- | ------------------------------------------------------ |\n| **What it is** | Assignable, identifiable event |\n| **Signal** | Point outside control limits, patterns, trends |\n| **Examples** | New operator, material batch change, equipment failure |\n| **Who acts** | Local level: Operator, Supervisor, Team |\n| **Action** | Find it, remove it, prevent recurrence |\n| **Goal** | Restore stability |\n\n---\n\n## Common Cause Variation\n\n```\nUSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nUCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ← Process is STABLE\n ● ● ● ● but control limits\n ● ● ● ● exceed specs!\nx̄ ═══════════════════════════════════\n ● ● ●\n ● ● ● ●\nLCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\n\nLSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n```\n\n| Characteristic | Common Cause |\n| -------------- | ----------------------------------------------------------------------- |\n| **What it is** | Inherent to the system as designed |\n| **Signal** | Stable process BUT control limits outside specs |\n| **Examples** | Equipment capability, process design, material specs |\n| **Who acts** | System level: Management, Corporate Quality, Business Improvement, OpEx |\n| **Action** | Fundamental process change, investment, redesign |\n| **Goal** | Reduce variation, improve capability |\n\n---\n\n## Beneficial Special Causes\n\nNot all special causes are problems. When the [characteristic type](../../03-features/analysis/characteristic-types.md) is directional (smaller-is-better or larger-is-better), a special cause that moves the process _toward_ the quality goal is a favorable signal:\n\n- A cycle time (smaller-is-better) dropping below LCL = unexpectedly fast — replicate it\n- A yield (larger-is-better) exceeding UCL = unexpectedly high — understand why\n\nTraditional SPC treats all special causes as \"investigate and remove.\" Direction awareness refines this: investigate favorable signals to _replicate_ them, and harmful signals to _fix_ them. This is the foundation for the green/red dot coloring on the I-Chart.\n\n---\n\n## The Critical Insight\n\n**Looking at stability is the traditional use of control charts — but it's only half the story.**\n\n| Situation | I-Chart Shows | Action Required |\n| -------------------------- | -------------------------------------------------- | --------------------------------------------- |\n| **Special cause present** | Points outside limits, patterns | Find and remove the cause (local action) |\n| **Stable but not capable** | All points within limits, BUT limits outside specs | Reduce common cause variation (system action) |\n\n:::caution[The Trap]\nWhen a process is stable but not capable, local actions won't help. \"Trying harder\" or adjusting individual points just adds variation. The **system itself** must change.\n:::\n\n---\n\n## Who Does What?\n\n| Role | Focus | Type of Variation | Typical Actions |\n| ------------------------------- | -------------------- | --------------------- | ------------------------------------- |\n| **Operator** | Run the process | Detect special causes | Flag abnormalities, follow procedures |\n| **Supervisor** | Daily management | Remove special causes | Investigate, correct, document |\n| **Quality Team** | Monitor & measure | Both | Track Cp/Cpk, report trends |\n| **OpEx / Business Improvement** | System improvement | Common cause | Projects, Kaizen, process redesign |\n| **Corporate Quality** | Strategy & standards | Common cause | Capability targets, investment cases |\n| **Management** | Resource allocation | Common cause | Approve changes, fund improvements |\n\n**Deming's insight:** Management is responsible for the system. If the system produces common cause variation that's too high, only management can authorize the changes needed to fix it.\n\n---\n\n## The Business Improvement Function's Role\n\nWhen VariScout reveals a \"stable but not capable\" situation, this is where **Corporate Quality / Business Improvement / OpEx** comes in:\n\n| They Ask | VariScout Provides |\n| ------------------------------------------------- | --------------------------------------------------- |\n| \"Which processes need fundamental improvement?\" | Capability analysis showing stable but not capable |\n| \"Where should we invest in process redesign?\" | Prioritized list by gap between UCL/LCL and USL/LSL |\n| \"What's the potential ROI of improvement?\" | Variation % that could be reduced |\n| \"Which factors drive the common cause variation?\" | Boxplot showing factor contribution |\n\n**The workflow:**\n\n```\nLOCAL LEVEL SYSTEM LEVEL\n───────────────── ─────────────────\nI-Chart reveals I-Chart reveals\nspecial cause stable but not capable\n ↓ ↓\nSupervisor Corporate Quality /\ninvestigates Business Improvement\n ↓ ↓\nFind & remove Fundamental process\nthe cause change project\n ↓ ↓\nRestore stability Reduce common cause\n variation\n ↓ ↓\nBACK TO NORMAL NEW CAPABILITY LEVEL\n```\n\n---\n\n## VariScout Connects Both Levels\n\n**For local teams:** I-Chart with control limits → \"Is something unusual happening?\"\n\n**For improvement functions:** I-Chart with BOTH limits → \"Is the system capable?\" + Boxplot → \"What drives the variation?\"\n\n> VariScout finds WHERE to focus — whether it's a special cause for local action or common cause variation for system improvement. Apply Lean thinking to find WHY — and what to do about it.\n\n---\n\n## See Also\n\n- [Two Voices Overview](index.md)\n- [Four Scenarios](scenarios.md) — Different combinations of stability and capability", + "src/content/docs/01-vision/two-voices/variation-types.md", + "037dc1c0693428db", + { "html": 6063, "metadata": 6064 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"two-types-of-variation-two-types-of-action\">Two Types of Variation, Two Types of Action\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#two-types-of-variation-two-types-of-action\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two Types of Variation, Two Types of Action”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The I-Chart reveals patterns — but what you DO about them depends on what TYPE of variation you’re seeing.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"special-cause-variation\">Special Cause Variation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#special-cause-variation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Special Cause Variation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ← Point outside limits\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">x̄ ═══════════════════════════════════\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ● ← Point outside limits ● ● ● ● ● ● ● ●x̄ ═══════════════════════════════════ ● ● ● ● ● ● ●LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Characteristic\u003C/th>\u003Cth>Special Cause\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>What it is\u003C/strong>\u003C/td>\u003Ctd>Assignable, identifiable event\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Signal\u003C/strong>\u003C/td>\u003Ctd>Point outside control limits, patterns, trends\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Examples\u003C/strong>\u003C/td>\u003Ctd>New operator, material batch change, equipment failure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Who acts\u003C/strong>\u003C/td>\u003Ctd>Local level: Operator, Supervisor, Team\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Action\u003C/strong>\u003C/td>\u003Ctd>Find it, remove it, prevent recurrence\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Restore stability\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"common-cause-variation\">Common Cause Variation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#common-cause-variation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Cause Variation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ← Process is STABLE\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ● but control limits\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ● exceed specs!\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">x̄ ═══════════════════════════════════\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● ● ● ●\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"USL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━UCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ← Process is STABLE ● ● ● ● but control limits ● ● ● ● exceed specs!x̄ ═══════════════════════════════════ ● ● ● ● ● ● ●LCL ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─LSL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Characteristic\u003C/th>\u003Cth>Common Cause\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>What it is\u003C/strong>\u003C/td>\u003Ctd>Inherent to the system as designed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Signal\u003C/strong>\u003C/td>\u003Ctd>Stable process BUT control limits outside specs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Examples\u003C/strong>\u003C/td>\u003Ctd>Equipment capability, process design, material specs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Who acts\u003C/strong>\u003C/td>\u003Ctd>System level: Management, Corporate Quality, Business Improvement, OpEx\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Action\u003C/strong>\u003C/td>\u003Ctd>Fundamental process change, investment, redesign\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Goal\u003C/strong>\u003C/td>\u003Ctd>Reduce variation, improve capability\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"beneficial-special-causes\">Beneficial Special Causes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#beneficial-special-causes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Beneficial Special Causes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Not all special causes are problems. When the \u003Ca href=\"../../03-features/analysis/characteristic-types.md\">characteristic type\u003C/a> is directional (smaller-is-better or larger-is-better), a special cause that moves the process \u003Cem>toward\u003C/em> the quality goal is a favorable signal:\u003C/p>\n\u003Cul>\n\u003Cli>A cycle time (smaller-is-better) dropping below LCL = unexpectedly fast — replicate it\u003C/li>\n\u003Cli>A yield (larger-is-better) exceeding UCL = unexpectedly high — understand why\u003C/li>\n\u003C/ul>\n\u003Cp>Traditional SPC treats all special causes as “investigate and remove.” Direction awareness refines this: investigate favorable signals to \u003Cem>replicate\u003C/em> them, and harmful signals to \u003Cem>fix\u003C/em> them. This is the foundation for the green/red dot coloring on the I-Chart.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-critical-insight\">The Critical Insight\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-critical-insight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Critical Insight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Looking at stability is the traditional use of control charts — but it’s only half the story.\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Situation\u003C/th>\u003Cth>I-Chart Shows\u003C/th>\u003Cth>Action Required\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Special cause present\u003C/strong>\u003C/td>\u003Ctd>Points outside limits, patterns\u003C/td>\u003Ctd>Find and remove the cause (local action)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Stable but not capable\u003C/strong>\u003C/td>\u003Ctd>All points within limits, BUT limits outside specs\u003C/td>\u003Ctd>Reduce common cause variation (system action)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Caside aria-label=\"The Trap\" class=\"starlight-aside starlight-aside--caution\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath d=\"M12 16C11.8022 16 11.6089 16.0587 11.4444 16.1686C11.28 16.2784 11.1518 16.4346 11.0761 16.6173C11.0004 16.8001 10.9806 17.0011 11.0192 17.1951C11.0578 17.3891 11.153 17.5673 11.2929 17.7071C11.4327 17.847 11.6109 17.9422 11.8049 17.9808C11.9989 18.0194 12.2 17.9996 12.3827 17.9239C12.5654 17.8482 12.7216 17.72 12.8315 17.5556C12.9413 17.3911 13 17.1978 13 17C13 16.7348 12.8946 16.4805 12.7071 16.2929C12.5196 16.1054 12.2652 16 12 16ZM22.67 17.47L14.62 3.47003C14.3598 3.00354 13.9798 2.61498 13.5192 2.3445C13.0586 2.07401 12.5341 1.9314 12 1.9314C11.4659 1.9314 10.9414 2.07401 10.4808 2.3445C10.0202 2.61498 9.64019 3.00354 9.38 3.47003L1.38 17.47C1.11079 17.924 0.966141 18.441 0.960643 18.9688C0.955144 19.4966 1.089 20.0166 1.34868 20.4761C1.60837 20.9356 1.9847 21.3185 2.43968 21.5861C2.89466 21.8536 3.41218 21.9964 3.94 22H20.06C20.5921 22.0053 21.1159 21.8689 21.5779 21.6049C22.0399 21.341 22.4234 20.9589 22.689 20.4978C22.9546 20.0368 23.0928 19.5134 23.0895 18.9814C23.0862 18.4493 22.9414 17.9277 22.67 17.47ZM20.94 19.47C20.8523 19.626 20.7245 19.7556 20.5697 19.8453C20.4149 19.935 20.2389 19.9815 20.06 19.98H3.94C3.76111 19.9815 3.5851 19.935 3.43032 19.8453C3.27553 19.7556 3.14765 19.626 3.06 19.47C2.97223 19.318 2.92602 19.1456 2.92602 18.97C2.92602 18.7945 2.97223 18.622 3.06 18.47L11.06 4.47003C11.1439 4.30623 11.2714 4.16876 11.4284 4.07277C11.5855 3.97678 11.766 3.92599 11.95 3.92599C12.134 3.92599 12.3145 3.97678 12.4716 4.07277C12.6286 4.16876 12.7561 4.30623 12.84 4.47003L20.89 18.47C20.9892 18.6199 21.0462 18.7937 21.055 18.9732C21.0638 19.1527 21.0241 19.3312 20.94 19.49V19.47ZM12 8.00003C11.7348 8.00003 11.4804 8.10538 11.2929 8.29292C11.1054 8.48046 11 8.73481 11 9.00003V13C11 13.2652 11.1054 13.5196 11.2929 13.7071C11.4804 13.8947 11.7348 14 12 14C12.2652 14 12.5196 13.8947 12.7071 13.7071C12.8946 13.5196 13 13.2652 13 13V9.00003C13 8.73481 12.8946 8.48046 12.7071 8.29292C12.5196 8.10538 12.2652 8.00003 12 8.00003Z\">\u003C/path>\u003C/svg>The Trap\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>When a process is stable but not capable, local actions won’t help. “Trying harder” or adjusting individual points just adds variation. The \u003Cstrong>system itself\u003C/strong> must change.\u003C/p>\u003C/div>\u003C/aside>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"who-does-what\">Who Does What?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#who-does-what\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Who Does What?”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Focus\u003C/th>\u003Cth>Type of Variation\u003C/th>\u003Cth>Typical Actions\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Operator\u003C/strong>\u003C/td>\u003Ctd>Run the process\u003C/td>\u003Ctd>Detect special causes\u003C/td>\u003Ctd>Flag abnormalities, follow procedures\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Supervisor\u003C/strong>\u003C/td>\u003Ctd>Daily management\u003C/td>\u003Ctd>Remove special causes\u003C/td>\u003Ctd>Investigate, correct, document\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Quality Team\u003C/strong>\u003C/td>\u003Ctd>Monitor & measure\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Track Cp/Cpk, report trends\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>OpEx / Business Improvement\u003C/strong>\u003C/td>\u003Ctd>System improvement\u003C/td>\u003Ctd>Common cause\u003C/td>\u003Ctd>Projects, Kaizen, process redesign\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Corporate Quality\u003C/strong>\u003C/td>\u003Ctd>Strategy & standards\u003C/td>\u003Ctd>Common cause\u003C/td>\u003Ctd>Capability targets, investment cases\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Management\u003C/strong>\u003C/td>\u003Ctd>Resource allocation\u003C/td>\u003Ctd>Common cause\u003C/td>\u003Ctd>Approve changes, fund improvements\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Deming’s insight:\u003C/strong> Management is responsible for the system. If the system produces common cause variation that’s too high, only management can authorize the changes needed to fix it.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-business-improvement-functions-role\">The Business Improvement Function’s Role\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-business-improvement-functions-role\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Business Improvement Function’s Role”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When VariScout reveals a “stable but not capable” situation, this is where \u003Cstrong>Corporate Quality / Business Improvement / OpEx\u003C/strong> comes in:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>They Ask\u003C/th>\u003Cth>VariScout Provides\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Which processes need fundamental improvement?”\u003C/td>\u003Ctd>Capability analysis showing stable but not capable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Where should we invest in process redesign?”\u003C/td>\u003Ctd>Prioritized list by gap between UCL/LCL and USL/LSL\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”What’s the potential ROI of improvement?”\u003C/td>\u003Ctd>Variation % that could be reduced\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Which factors drive the common cause variation?”\u003C/td>\u003Ctd>Boxplot showing factor contribution\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>The workflow:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LOCAL LEVEL SYSTEM LEVEL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">───────────────── ─────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">I-Chart reveals I-Chart reveals\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">special cause stable but not capable\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓ ↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Supervisor Corporate Quality /\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">investigates Business Improvement\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓ ↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Find & remove Fundamental process\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">the cause change project\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓ ↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Restore stability Reduce common cause\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">variation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓ ↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">BACK TO NORMAL NEW CAPABILITY LEVEL\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"LOCAL LEVEL SYSTEM LEVEL───────────────── ─────────────────I-Chart reveals I-Chart revealsspecial cause stable but not capable ↓ ↓Supervisor Corporate Quality /investigates Business Improvement ↓ ↓Find & remove Fundamental processthe cause change project ↓ ↓Restore stability Reduce common cause variation ↓ ↓BACK TO NORMAL NEW CAPABILITY LEVEL\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-connects-both-levels\">VariScout Connects Both Levels\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-connects-both-levels\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout Connects Both Levels”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>For local teams:\u003C/strong> I-Chart with control limits → “Is something unusual happening?”\u003C/p>\n\u003Cp>\u003Cstrong>For improvement functions:\u003C/strong> I-Chart with BOTH limits → “Is the system capable?” + Boxplot → “What drives the variation?”\u003C/p>\n\u003Cblockquote>\n\u003Cp>VariScout finds WHERE to focus — whether it’s a special cause for local action or common cause variation for system improvement. Apply Lean thinking to find WHY — and what to do about it.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Two Voices Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"scenarios.md\">Four Scenarios\u003C/a> — Different combinations of stability and capability\u003C/li>\n\u003C/ul>", + { + "headings": 6065, + "localImagePaths": 6090, + "remoteImagePaths": 6091, + "frontmatter": 6092, + "imagePaths": 6093 + }, + [6066, 6068, 6071, 6074, 6077, 6080, 6083, 6086, 6089], + { "depth": 30, "slug": 6067, "text": 6055 }, + "two-types-of-variation-two-types-of-action", + { "depth": 33, "slug": 6069, "text": 6070 }, + "special-cause-variation", + "Special Cause Variation", + { "depth": 33, "slug": 6072, "text": 6073 }, + "common-cause-variation", + "Common Cause Variation", + { "depth": 33, "slug": 6075, "text": 6076 }, + "beneficial-special-causes", + "Beneficial Special Causes", + { "depth": 33, "slug": 6078, "text": 6079 }, + "the-critical-insight", + "The Critical Insight", + { "depth": 33, "slug": 6081, "text": 6082 }, + "who-does-what", + "Who Does What?", + { "depth": 33, "slug": 6084, "text": 6085 }, + "the-business-improvement-functions-role", + "The Business Improvement Function’s Role", + { "depth": 33, "slug": 6087, "text": 6088 }, + "variscout-connects-both-levels", + "VariScout Connects Both Levels", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6055 }, + [], + "01-vision/four-lenses/change", + { "id": 6094, "data": 6096, "body": 6101, "filePath": 6102, "digest": 6103, "rendered": 6104 }, + { + "title": 6097, + "editUrl": 16, + "head": 6098, + "template": 18, + "sidebar": 6099, + "pagefind": 16, + "draft": 20 + }, + "CHANGE Lens: I-Chart", + [], + { "hidden": 20, "attrs": 6100 }, + {}, + "# CHANGE Lens: I-Chart\n\n> The Adaptive Lens — look at the same data through time\n\nThe CHANGE lens asks what happens when you arrange your data along a time axis. The same measurements that look fine as an average can reveal shifts, trends, and cycles when viewed through this lens.\n\n---\n\n## The Question\n\n_\"Is the process stable, or is something degrading/shifting over time?\"_\n\n---\n\n## What the I-Chart Reveals\n\n- Time-based stability or instability\n- Trends, shifts, cycles\n- Points outside control limits (UCL/LCL)\n- Dynamic behavior: wear, degradation, seasonal effects\n\n---\n\n## Key Insight from Sock Mystery\n\n> \"Processes aren't static snapshots; they are moving pictures.\"\n\nThe wash cycle discovery (NEW → WORN → USED) showed how characteristics change over time. The I-Chart is your \"time-lapse camera\" for the process.\n\n---\n\n## VariScout Implementation\n\n- Auto-calculated control limits (x̄ ± 2.66MR̄)\n- Specification lines overlay (USL/LSL)\n- Click any point to see its factor values\n- Linked filtering: click a time region → see which factors were active\n\n---\n\n## The Reality Check\n\n> \"What variables are degrading or shifting over time?\"\n\nQuestions to ask:\n\n- Static vs dynamic analysis\n- Cyclical factors (shift patterns, seasonal effects)\n- Degradation factors (tool wear, material aging)\n\n---\n\n## Chart-to-Lens Reference\n\n| Lens | Chart | Key Metric | Key Visual | User Action |\n| ------ | ------- | ----------------------------- | --------------------------- | ------------------------- |\n| CHANGE | I-Chart | Stability (in/out of control) | Points vs UCL/LCL over time | Click point → see factors |\n\n---\n\n## See Also\n\n- [Four Lenses Overview](index.md)\n- [Two Voices](../two-voices/index.md) — Control limits vs specification limits", + "src/content/docs/01-vision/four-lenses/change.md", + "d162700e4272c376", + { "html": 6105, "metadata": 6106 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"change-lens-i-chart\">CHANGE Lens: I-Chart\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#change-lens-i-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CHANGE Lens: I-Chart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>The Adaptive Lens — look at the same data through time\u003C/p>\n\u003C/blockquote>\n\u003Cp>The CHANGE lens asks what happens when you arrange your data along a time axis. The same measurements that look fine as an average can reveal shifts, trends, and cycles when viewed through this lens.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-question\">The Question\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-question\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Question”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Is the process stable, or is something degrading/shifting over time?”\u003C/em>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-the-i-chart-reveals\">What the I-Chart Reveals\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-the-i-chart-reveals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What the I-Chart Reveals”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Time-based stability or instability\u003C/li>\n\u003Cli>Trends, shifts, cycles\u003C/li>\n\u003Cli>Points outside control limits (UCL/LCL)\u003C/li>\n\u003Cli>Dynamic behavior: wear, degradation, seasonal effects\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-insight-from-sock-mystery\">Key Insight from Sock Mystery\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-insight-from-sock-mystery\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Insight from Sock Mystery”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“Processes aren’t static snapshots; they are moving pictures.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>The wash cycle discovery (NEW → WORN → USED) showed how characteristics change over time. The I-Chart is your “time-lapse camera” for the process.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-implementation\">VariScout Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Auto-calculated control limits (x̄ ± 2.66MR̄)\u003C/li>\n\u003Cli>Specification lines overlay (USL/LSL)\u003C/li>\n\u003Cli>Click any point to see its factor values\u003C/li>\n\u003Cli>Linked filtering: click a time region → see which factors were active\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-reality-check\">The Reality Check\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-reality-check\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Reality Check”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“What variables are degrading or shifting over time?”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Questions to ask:\u003C/p>\n\u003Cul>\n\u003Cli>Static vs dynamic analysis\u003C/li>\n\u003Cli>Cyclical factors (shift patterns, seasonal effects)\u003C/li>\n\u003Cli>Degradation factors (tool wear, material aging)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-to-lens-reference\">Chart-to-Lens Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-to-lens-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart-to-Lens Reference”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Lens\u003C/th>\u003Cth>Chart\u003C/th>\u003Cth>Key Metric\u003C/th>\u003Cth>Key Visual\u003C/th>\u003Cth>User Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>CHANGE\u003C/td>\u003Ctd>I-Chart\u003C/td>\u003Ctd>Stability (in/out of control)\u003C/td>\u003Ctd>Points vs UCL/LCL over time\u003C/td>\u003Ctd>Click point → see factors\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Four Lenses Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../two-voices/index.md\">Two Voices\u003C/a> — Control limits vs specification limits\u003C/li>\n\u003C/ul>", + { + "headings": 6107, + "localImagePaths": 6129, + "remoteImagePaths": 6130, + "frontmatter": 6131, + "imagePaths": 6132 + }, + [6108, 6110, 6113, 6116, 6119, 6122, 6125, 6128], + { "depth": 30, "slug": 6109, "text": 6097 }, + "change-lens-i-chart", + { "depth": 33, "slug": 6111, "text": 6112 }, + "the-question", + "The Question", + { "depth": 33, "slug": 6114, "text": 6115 }, + "what-the-i-chart-reveals", + "What the I-Chart Reveals", + { "depth": 33, "slug": 6117, "text": 6118 }, + "key-insight-from-sock-mystery", + "Key Insight from Sock Mystery", + { "depth": 33, "slug": 6120, "text": 6121 }, + "variscout-implementation", + "VariScout Implementation", + { "depth": 33, "slug": 6123, "text": 6124 }, + "the-reality-check", + "The Reality Check", + { "depth": 33, "slug": 6126, "text": 6127 }, + "chart-to-lens-reference", + "Chart-to-Lens Reference", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6097 }, + [], + "01-vision/four-lenses/drilldown", + { "id": 6133, "data": 6135, "body": 6140, "filePath": 6141, "digest": 6142, "rendered": 6143 }, + { + "title": 6136, + "editUrl": 16, + "head": 6137, + "template": 18, + "sidebar": 6138, + "pagefind": 16, + "draft": 20 + }, + "Drill-Down: Progressive Variation Analysis", + [], + { "hidden": 20, "attrs": 6139 }, + {}, + "# Drill-Down: Progressive Variation Analysis\n\nThe drill-down methodology is the heart of VariScout's approach to finding where variation hides.\n\n---\n\n## The Drill-Down Logic\n\n### Decision Thresholds\n\n| Variation % | Action |\n| ----------- | ---------------------------------------- |\n| **>50%** | Auto-drill — this is the primary driver |\n| **>80%** | Strong focus — highly concentrated issue |\n| **30-50%** | Recommend investigating, ask user |\n| **\u003C30%** | Multiple factors — check interactions |\n\n### Example Drill-Down Journey\n\n```\nLEVEL 1: ALL DATA\n━━━━━━━━━━━━━━━━━\nI-Chart: Shows instability\nBoxplot: Compare Shift/Machine/Operator\nFinding: SHIFT explains 67% of variation\nAction: Drill into SHIFT\n↓\nLEVEL 2: WITHIN SHIFT\n━━━━━━━━━━━━━━━━━━━━━\nI-Chart: Shows only Night Shift timeline\nBoxplot: Compare Machines within Night Shift\nFinding: Night Shift = 89% of shift variation\nAction: Drill into Night Shift\n↓\nLEVEL 3: WITHIN NIGHT SHIFT\n━━━━━━━━━━━━━━━━━━━━━━━━━━━\nI-Chart: Shows only Night Shift + Machine C\nBoxplot: Compare Operators on Machine C at Night\nFinding: Machine C = 78% of Night Shift variation\nAction: Primary driver identified — investigate Machine C conditions\n```\n\n### Filter Chips UI\n\n```\n┌─────────────────────────────────────────────────────────────────────────┐\n│ ACTIVE FILTERS │\n│ │\n│ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │\n│ │ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │ │\n│ └────────────────────┘ └────────────────────┘ └────────────────────┘ │\n│ │\n│ CUMULATIVE: 46% of total variation isolated │\n│ \"Fix this combination to address nearly half your quality problems\" │\n└─────────────────────────────────────────────────────────────────────────┘\n```\n\nEach chip shows contribution % to TOTAL variation (not local η²).\n\n---\n\n## Cumulative Variation Tracking\n\n:::note[The Power of Filter Chips]\nThis is the killer insight of the entire methodology. Filter chips aren't just navigation — they show **contribution to TOTAL variation** that tells you exactly how much of your total problem you've isolated.\n:::\n\n:::caution[Important Terminology]\nVariScout identifies **factors driving variation**, not \"root causes.\" EDA shows _which_ factors explain variation — the _why_ requires further investigation (5 Whys, experimentation, Gemba walks). This distinction matters: we quantify contribution, not causation.\n:::\n\n### The Math Behind Contribution %\n\nEach filter's contribution % shows what portion of TOTAL variation it captures:\n\n```\nFILTER CHIP CONTRIBUTION TO TOTAL MEANING\n────────────────────────────────────────────────────────────────────────\n[Shift: Night ▼ 67%] 67% of total Night shift alone\n[Machine: C ▼ 24%] 24% of total Machine C within context\n[Operator: Kim ▼ 9%] 9% of total Kim within context\n\nCUMULATIVE ISOLATION: ~46% of total variation in ONE condition\n```\n\n**The insight:** By applying three filters, you've isolated 46.5% of ALL your variation into ONE specific condition: Operator Kim on Machine C during Night Shift.\n\n---\n\n## Why This Changes Everything\n\n| Traditional Approach | VariScout Filter Chip Approach |\n| ----------------------------------- | ------------------------------------------------- |\n| \"Our Cp is 0.4, process is chaotic\" | \"46% of variation = Machine C on Nights\" |\n| \"We need to improve quality\" | \"Fix this ONE combination = half the problem\" |\n| Scatter resources across everything | Laser focus on highest-impact target |\n| Months of unfocused effort | Days to targeted solution |\n| \"Quality is everyone's job\" | \"Machine C Night Shift team: here's your mission\" |\n\n---\n\n## The Actionability Hierarchy\n\nAs you add more filters, actionability increases:\n\n```\nDEPTH FILTER CHIPS FINDING ACTIONABILITY\n──────────────────────────────────────────────────────────────────────────────────────\nLevel 0 (no filters) \"We have variation\" ❌ Not actionable\n \"Improve everything\"\n\nLevel 1 [Shift: Night ▼ 67%] \"It's shift-related\" ⚠️ Somewhat actionable\n \"Look at shift practices\"\n\nLevel 2 + [Machine: C ▼ 24%] \"Night + Machine C\" ✓ Actionable\n \"Investigate Machine C\"\n\nLevel 3 + [Operator: Kim ▼ 9%] \"Kim on C at Night\" ✓✓ Highly actionable\n \"Fix Machine C setup/maint\"\n```\n\n---\n\n## Reading Filter Chips\n\n**Contribution % (shown in chip):**\n\n> \"Of TOTAL variation from ALL data, how much does this specific selection capture?\"\n\nUnlike local η² which shows variation at the current filtered level, contribution % always references the original dataset.\n\n```\nExample Filter Chips:\n[Shift: Night ▼ 67%] [Machine: C ▼ 24%] [Operator: Kim ▼ 9%]\n ↑ ↑ ↑\n 67% of TOTAL 24% of TOTAL 9% of TOTAL\n variation variation variation\n```\n\n---\n\n## Multi-Select Capability\n\nFilter chips support selecting multiple values within a factor:\n\n```\n┌────────────────────────┐\n│ Machine: A, C ▼ 45% │ ← Two machines selected\n└────────────────────────┘\n\nClicking the dropdown reveals:\n┌─────────────────────────┐\n│ Machine │\n├─────────────────────────┤\n│ ☑ A 23% │\n│ ☐ B 10% │\n│ ☑ C 22% │\n│ ☐ D 12% │\n├─────────────────────────┤\n│ [Remove Filter] │\n└─────────────────────────┘\n```\n\nThis allows comparing specific combinations without losing context.\n\n---\n\n## The \"Half Your Problem\" Threshold\n\nA practical rule of thumb:\n\n| Cumulative % | Interpretation | Action |\n| ------------ | ------------------------------------- | --------------------------------- |\n| **>50%** | \"More than half your problem is HERE\" | Strong case for immediate action |\n| **30-50%** | \"Significant chunk isolated\" | Worth focused improvement project |\n| **\u003C30%** | \"One of several contributors\" | Address after bigger factors |\n\nIn our example, 46.5% means: **\"Fix Machine C on Night Shift and nearly half your quality problems disappear.\"**\n\n---\n\n## Visual: The Variation Funnel\n\n```\n ALL VARIATION (100%)\n ┌─────────────────────────┐\n │░░░░░░░░░░░░░░░░░░░░░░░░░│\n │░░░░░░░░░░░░░░░░░░░░░░░░░│\n └───────────┬─────────────┘\n │\n ┌──────────────────┴──────────────────┐\n │ │\n SHIFT (67%) Other (33%)\n ┌─────────────┐ ┌─────────┐\n │█████████████│ │░░░░░░░░░│\n │█████████████│ └─────────┘\n └──────┬──────┘ (park this)\n │\n ┌──────┴──────┐\n │ │\nNIGHT (89%) Day (11%)\n┌─────────┐ ┌───┐\n│█████████│ │░░░│\n│█████████│ └───┘\n└────┬────┘\n │\n┌────┴────┐\n│ │\nMACH C Others\n(78%) (22%)\n┌─────┐ ┌──┐\n│█████│ │░░│\n└─────┘ └──┘\n │\n ▼\n46.5% OF TOTAL\nVARIATION ISOLATED\nTO ONE CONDITION\n```\n\n---\n\n## Practical Example: Cost of Inaction vs Action\n\n**Scenario:** Production line with 10,000 units/month, 8% defect rate = 800 defects/month\n\n| Approach | Defects Addressed | Effort | ROI |\n| --------------------------------- | ----------------------- | -------------------------- | -------------- |\n| \"Improve everything\" | 800 (theoretically) | High, scattered | Low - no focus |\n| Fix Machine C Nights (46.5%) | ~372 defects eliminated | Focused, measurable | **High** |\n| Then fix remaining Shift (20.5%) | +164 more | Next project | Compounding |\n| **Total from 2 focused projects** | **536 defects (67%)** | **Sequential, manageable** | **Maximum** |\n\n---\n\n## Filter Chips as Communication Tool\n\n**Before (traditional):**\n\n> \"ANOVA shows statistically significant differences between shifts (p\u003C0.001) with eta-squared of 0.67, and within the night shift subset, machine effects show F(2,267)=45.3...\"\n\n**After (VariScout filter chips):**\n\n> Filter chips: `[Shift: Night ▼ 67%] [Machine: C ▼ 24%] [Operator: Kim ▼ 9%]`\n>\n> Translation: \"This combination explains 46% of all our quality variation. Fix this one combination and nearly half our problems disappear.\"\n\n**Which one does the plant manager act on?**\n\n---\n\n## Implementation in VariScout UI\n\nThe filter chips should always show:\n\n```\n┌─────────────────────────────────────────────────────────────────────────┐\n│ ACTIVE FILTERS │\n│ │\n│ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │\n│ │ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │ │\n│ └────────────────────┘ └────────────────────┘ └────────────────────┘ │\n│ │\n│ CUMULATIVE: 46% of total variation isolated │\n│ \"Fix this combination to address nearly half your quality problems\" │\n│ │\n│ [Clear All Filters] │\n└─────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## See Also\n\n- [Four Lenses Overview](index.md)\n- [FLOW](flow.md) — Boxplot for factor comparison", + "src/content/docs/01-vision/four-lenses/drilldown.md", + "2516187311bc9bbc", + { "html": 6144, "metadata": 6145 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"drill-down-progressive-variation-analysis\">Drill-Down: Progressive Variation Analysis\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#drill-down-progressive-variation-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill-Down: Progressive Variation Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The drill-down methodology is the heart of VariScout’s approach to finding where variation hides.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-drill-down-logic\">The Drill-Down Logic\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-drill-down-logic\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Drill-Down Logic”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"decision-thresholds\">Decision Thresholds\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#decision-thresholds\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision Thresholds”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variation %\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>>50%\u003C/strong>\u003C/td>\u003Ctd>Auto-drill — this is the primary driver\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>>80%\u003C/strong>\u003C/td>\u003Ctd>Strong focus — highly concentrated issue\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>30-50%\u003C/strong>\u003C/td>\u003Ctd>Recommend investigating, ask user\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong><30%\u003C/strong>\u003C/td>\u003Ctd>Multiple factors — check interactions\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-drill-down-journey\">Example Drill-Down Journey\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-drill-down-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example Drill-Down Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LEVEL 1: ALL DATA\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">I-Chart: Shows instability\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Boxplot: Compare Shift/Machine/Operator\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Finding: SHIFT explains 67% of variation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Action: Drill into SHIFT\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LEVEL 2: WITHIN SHIFT\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">I-Chart: Shows only Night Shift timeline\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Boxplot: Compare Machines within Night Shift\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Finding: Night Shift = 89% of shift variation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Action: Drill into Night Shift\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LEVEL 3: WITHIN NIGHT SHIFT\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">━━━━━━━━━━━━━━━━━━━━━━━━━━━\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">I-Chart: Shows only Night Shift + Machine C\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Boxplot: Compare Operators on Machine C at Night\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Finding: Machine C = 78% of Night Shift variation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Action: Primary driver identified — investigate Machine C conditions\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"LEVEL 1: ALL DATA━━━━━━━━━━━━━━━━━I-Chart: Shows instabilityBoxplot: Compare Shift/Machine/OperatorFinding: SHIFT explains 67% of variationAction: Drill into SHIFT↓LEVEL 2: WITHIN SHIFT━━━━━━━━━━━━━━━━━━━━━I-Chart: Shows only Night Shift timelineBoxplot: Compare Machines within Night ShiftFinding: Night Shift = 89% of shift variationAction: Drill into Night Shift↓LEVEL 3: WITHIN NIGHT SHIFT━━━━━━━━━━━━━━━━━━━━━━━━━━━I-Chart: Shows only Night Shift + Machine CBoxplot: Compare Operators on Machine C at NightFinding: Machine C = 78% of Night Shift variationAction: Primary driver identified — investigate Machine C conditions\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filter-chips-ui\">Filter Chips UI\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filter-chips-ui\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter Chips UI”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ACTIVE FILTERS │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └────────────────────┘ └────────────────────┘ └────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CUMULATIVE: 46% of total variation isolated │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Fix this combination to address nearly half your quality problems\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────────────┐│ ACTIVE FILTERS ││ ││ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ ││ │ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │ ││ └────────────────────┘ └────────────────────┘ └────────────────────┘ ││ ││ CUMULATIVE: 46% of total variation isolated ││ "Fix this combination to address nearly half your quality problems" │└─────────────────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Each chip shows contribution % to TOTAL variation (not local η²).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cumulative-variation-tracking\">Cumulative Variation Tracking\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cumulative-variation-tracking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cumulative Variation Tracking”\u003C/span>\u003C/a>\u003C/div>\n\u003Caside aria-label=\"The Power of Filter Chips\" class=\"starlight-aside starlight-aside--note\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath d=\"M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z\">\u003C/path>\u003C/svg>The Power of Filter Chips\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>This is the killer insight of the entire methodology. Filter chips aren’t just navigation — they show \u003Cstrong>contribution to TOTAL variation\u003C/strong> that tells you exactly how much of your total problem you’ve isolated.\u003C/p>\u003C/div>\u003C/aside>\n\u003Caside aria-label=\"Important Terminology\" class=\"starlight-aside starlight-aside--caution\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath d=\"M12 16C11.8022 16 11.6089 16.0587 11.4444 16.1686C11.28 16.2784 11.1518 16.4346 11.0761 16.6173C11.0004 16.8001 10.9806 17.0011 11.0192 17.1951C11.0578 17.3891 11.153 17.5673 11.2929 17.7071C11.4327 17.847 11.6109 17.9422 11.8049 17.9808C11.9989 18.0194 12.2 17.9996 12.3827 17.9239C12.5654 17.8482 12.7216 17.72 12.8315 17.5556C12.9413 17.3911 13 17.1978 13 17C13 16.7348 12.8946 16.4805 12.7071 16.2929C12.5196 16.1054 12.2652 16 12 16ZM22.67 17.47L14.62 3.47003C14.3598 3.00354 13.9798 2.61498 13.5192 2.3445C13.0586 2.07401 12.5341 1.9314 12 1.9314C11.4659 1.9314 10.9414 2.07401 10.4808 2.3445C10.0202 2.61498 9.64019 3.00354 9.38 3.47003L1.38 17.47C1.11079 17.924 0.966141 18.441 0.960643 18.9688C0.955144 19.4966 1.089 20.0166 1.34868 20.4761C1.60837 20.9356 1.9847 21.3185 2.43968 21.5861C2.89466 21.8536 3.41218 21.9964 3.94 22H20.06C20.5921 22.0053 21.1159 21.8689 21.5779 21.6049C22.0399 21.341 22.4234 20.9589 22.689 20.4978C22.9546 20.0368 23.0928 19.5134 23.0895 18.9814C23.0862 18.4493 22.9414 17.9277 22.67 17.47ZM20.94 19.47C20.8523 19.626 20.7245 19.7556 20.5697 19.8453C20.4149 19.935 20.2389 19.9815 20.06 19.98H3.94C3.76111 19.9815 3.5851 19.935 3.43032 19.8453C3.27553 19.7556 3.14765 19.626 3.06 19.47C2.97223 19.318 2.92602 19.1456 2.92602 18.97C2.92602 18.7945 2.97223 18.622 3.06 18.47L11.06 4.47003C11.1439 4.30623 11.2714 4.16876 11.4284 4.07277C11.5855 3.97678 11.766 3.92599 11.95 3.92599C12.134 3.92599 12.3145 3.97678 12.4716 4.07277C12.6286 4.16876 12.7561 4.30623 12.84 4.47003L20.89 18.47C20.9892 18.6199 21.0462 18.7937 21.055 18.9732C21.0638 19.1527 21.0241 19.3312 20.94 19.49V19.47ZM12 8.00003C11.7348 8.00003 11.4804 8.10538 11.2929 8.29292C11.1054 8.48046 11 8.73481 11 9.00003V13C11 13.2652 11.1054 13.5196 11.2929 13.7071C11.4804 13.8947 11.7348 14 12 14C12.2652 14 12.5196 13.8947 12.7071 13.7071C12.8946 13.5196 13 13.2652 13 13V9.00003C13 8.73481 12.8946 8.48046 12.7071 8.29292C12.5196 8.10538 12.2652 8.00003 12 8.00003Z\">\u003C/path>\u003C/svg>Important Terminology\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>VariScout identifies \u003Cstrong>factors driving variation\u003C/strong>, not “root causes.” EDA shows \u003Cem>which\u003C/em> factors explain variation — the \u003Cem>why\u003C/em> requires further investigation (5 Whys, experimentation, Gemba walks). This distinction matters: we quantify contribution, not causation.\u003C/p>\u003C/div>\u003C/aside>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-math-behind-contribution\">The Math Behind Contribution %\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-math-behind-contribution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Math Behind Contribution %”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each filter’s contribution % shows what portion of TOTAL variation it captures:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">FILTER CHIP CONTRIBUTION TO TOTAL MEANING\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">────────────────────────────────────────────────────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Shift: Night ▼ 67%] 67% of total Night shift alone\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Machine: C ▼ 24%] 24% of total Machine C within context\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Operator: Kim ▼ 9%] 9% of total Kim within context\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CUMULATIVE ISOLATION: ~46% of total variation in ONE condition\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"FILTER CHIP CONTRIBUTION TO TOTAL MEANING────────────────────────────────────────────────────────────────────────[Shift: Night ▼ 67%] 67% of total Night shift alone[Machine: C ▼ 24%] 24% of total Machine C within context[Operator: Kim ▼ 9%] 9% of total Kim within contextCUMULATIVE ISOLATION: ~46% of total variation in ONE condition\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>The insight:\u003C/strong> By applying three filters, you’ve isolated 46.5% of ALL your variation into ONE specific condition: Operator Kim on Machine C during Night Shift.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-this-changes-everything\">Why This Changes Everything\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-this-changes-everything\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why This Changes Everything”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Traditional Approach\u003C/th>\u003Cth>VariScout Filter Chip Approach\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Our Cp is 0.4, process is chaotic\"\u003C/td>\u003Ctd>\"46% of variation = Machine C on Nights\"\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\"We need to improve quality\"\u003C/td>\u003Ctd>\"Fix this ONE combination = half the problem”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Scatter resources across everything\u003C/td>\u003Ctd>Laser focus on highest-impact target\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Months of unfocused effort\u003C/td>\u003Ctd>Days to targeted solution\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Quality is everyone’s job\"\u003C/td>\u003Ctd>\"Machine C Night Shift team: here’s your mission”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-actionability-hierarchy\">The Actionability Hierarchy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-actionability-hierarchy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Actionability Hierarchy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>As you add more filters, actionability increases:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DEPTH FILTER CHIPS FINDING ACTIONABILITY\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">──────────────────────────────────────────────────────────────────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Level 0 (no filters) \"We have variation\" ❌ Not actionable\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"Improve everything\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Level 1 [Shift: Night ▼ 67%] \"It's shift-related\" ⚠️ Somewhat actionable\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"Look at shift practices\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Level 2 + [Machine: C ▼ 24%] \"Night + Machine C\" ✓ Actionable\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"Investigate Machine C\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Level 3 + [Operator: Kim ▼ 9%] \"Kim on C at Night\" ✓✓ Highly actionable\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"Fix Machine C setup/maint\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DEPTH FILTER CHIPS FINDING ACTIONABILITY──────────────────────────────────────────────────────────────────────────────────────Level 0 (no filters) "We have variation" ❌ Not actionable "Improve everything"Level 1 [Shift: Night ▼ 67%] "It's shift-related" ⚠️ Somewhat actionable "Look at shift practices"Level 2 + [Machine: C ▼ 24%] "Night + Machine C" ✓ Actionable "Investigate Machine C"Level 3 + [Operator: Kim ▼ 9%] "Kim on C at Night" ✓✓ Highly actionable "Fix Machine C setup/maint"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"reading-filter-chips\">Reading Filter Chips\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#reading-filter-chips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reading Filter Chips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Contribution % (shown in chip):\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Of TOTAL variation from ALL data, how much does this specific selection capture?”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Unlike local η² which shows variation at the current filtered level, contribution % always references the original dataset.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Example Filter Chips:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Shift: Night ▼ 67%] [Machine: C ▼ 24%] [Operator: Kim ▼ 9%]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↑ ↑ ↑\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">67% of TOTAL 24% of TOTAL 9% of TOTAL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">variation variation variation\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Example Filter Chips:[Shift: Night ▼ 67%] [Machine: C ▼ 24%] [Operator: Kim ▼ 9%] ↑ ↑ ↑ 67% of TOTAL 24% of TOTAL 9% of TOTAL variation variation variation\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"multi-select-capability\">Multi-Select Capability\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#multi-select-capability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Multi-Select Capability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Filter chips support selecting multiple values within a factor:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Machine: A, C ▼ 45% │ ← Two machines selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Clicking the dropdown reveals:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Machine │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☑ A 23% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☐ B 10% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☑ C 22% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☐ D 12% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Remove Filter] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌────────────────────────┐│ Machine: A, C ▼ 45% │ ← Two machines selected└────────────────────────┘Clicking the dropdown reveals:┌─────────────────────────┐│ Machine │├─────────────────────────┤│ ☑ A 23% ││ ☐ B 10% ││ ☑ C 22% ││ ☐ D 12% │├─────────────────────────┤│ [Remove Filter] │└─────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This allows comparing specific combinations without losing context.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-half-your-problem-threshold\">The “Half Your Problem” Threshold\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-half-your-problem-threshold\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The “Half Your Problem” Threshold”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A practical rule of thumb:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Cumulative %\u003C/th>\u003Cth>Interpretation\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>>50%\u003C/strong>\u003C/td>\u003Ctd>“More than half your problem is HERE”\u003C/td>\u003Ctd>Strong case for immediate action\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>30-50%\u003C/strong>\u003C/td>\u003Ctd>“Significant chunk isolated”\u003C/td>\u003Ctd>Worth focused improvement project\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong><30%\u003C/strong>\u003C/td>\u003Ctd>“One of several contributors”\u003C/td>\u003Ctd>Address after bigger factors\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>In our example, 46.5% means: \u003Cstrong>“Fix Machine C on Night Shift and nearly half your quality problems disappear.”\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visual-the-variation-funnel\">Visual: The Variation Funnel\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visual-the-variation-funnel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual: The Variation Funnel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">ALL VARIATION (100%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│░░░░░░░░░░░░░░░░░░░░░░░░░│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│░░░░░░░░░░░░░░░░░░░░░░░░░│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───────────┬─────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌──────────────────┴──────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SHIFT (67%) Other (33%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────┐ ┌─────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│█████████████│ │░░░░░░░░░│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│█████████████│ └─────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────┬──────┘ (park this)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌──────┴──────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">NIGHT (89%) Day (11%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────┐ ┌───┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│█████████│ │░░░│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│█████████│ └───┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────┬────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────┴────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">MACH C Others\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">(78%) (22%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────┐ ┌──┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│█████│ │░░│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────┘ └──┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">46.5% OF TOTAL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">VARIATION ISOLATED\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">TO ONE CONDITION\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" ALL VARIATION (100%) ┌─────────────────────────┐ │░░░░░░░░░░░░░░░░░░░░░░░░░│ │░░░░░░░░░░░░░░░░░░░░░░░░░│ └───────────┬─────────────┘ │ ┌──────────────────┴──────────────────┐ │ │ SHIFT (67%) Other (33%) ┌─────────────┐ ┌─────────┐ │█████████████│ │░░░░░░░░░│ │█████████████│ └─────────┘ └──────┬──────┘ (park this) │ ┌──────┴──────┐ │ │NIGHT (89%) Day (11%)┌─────────┐ ┌───┐│█████████│ │░░░││█████████│ └───┘└────┬────┘ │┌────┴────┐│ │MACH C Others(78%) (22%)┌─────┐ ┌──┐│█████│ │░░│└─────┘ └──┘ │ ▼46.5% OF TOTALVARIATION ISOLATEDTO ONE CONDITION\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"practical-example-cost-of-inaction-vs-action\">Practical Example: Cost of Inaction vs Action\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#practical-example-cost-of-inaction-vs-action\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Practical Example: Cost of Inaction vs Action”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Scenario:\u003C/strong> Production line with 10,000 units/month, 8% defect rate = 800 defects/month\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Approach\u003C/th>\u003Cth>Defects Addressed\u003C/th>\u003Cth>Effort\u003C/th>\u003Cth>ROI\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Improve everything”\u003C/td>\u003Ctd>800 (theoretically)\u003C/td>\u003Ctd>High, scattered\u003C/td>\u003Ctd>Low - no focus\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Fix Machine C Nights (46.5%)\u003C/td>\u003Ctd>~372 defects eliminated\u003C/td>\u003Ctd>Focused, measurable\u003C/td>\u003Ctd>\u003Cstrong>High\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Then fix remaining Shift (20.5%)\u003C/td>\u003Ctd>+164 more\u003C/td>\u003Ctd>Next project\u003C/td>\u003Ctd>Compounding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total from 2 focused projects\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>536 defects (67%)\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>Sequential, manageable\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>Maximum\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"filter-chips-as-communication-tool\">Filter Chips as Communication Tool\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#filter-chips-as-communication-tool\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter Chips as Communication Tool”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Before (traditional):\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“ANOVA shows statistically significant differences between shifts (p<0.001) with eta-squared of 0.67, and within the night shift subset, machine effects show F(2,267)=45.3…”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>After (VariScout filter chips):\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>Filter chips: \u003Ccode dir=\"auto\">[Shift: Night ▼ 67%] [Machine: C ▼ 24%] [Operator: Kim ▼ 9%]\u003C/code>\u003C/p>\n\u003Cp>Translation: “This combination explains 46% of all our quality variation. Fix this one combination and nearly half our problems disappear.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Which one does the plant manager act on?\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation-in-variscout-ui\">Implementation in VariScout UI\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-in-variscout-ui\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation in VariScout UI”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The filter chips should always show:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ACTIVE FILTERS │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └────────────────────┘ └────────────────────┘ └────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CUMULATIVE: 46% of total variation isolated │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Fix this combination to address nearly half your quality problems\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Clear All Filters] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────────────┐│ ACTIVE FILTERS ││ ││ ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐ ││ │ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │ ││ └────────────────────┘ └────────────────────┘ └────────────────────┘ ││ ││ CUMULATIVE: 46% of total variation isolated ││ "Fix this combination to address nearly half your quality problems" ││ ││ [Clear All Filters] │└─────────────────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Four Lenses Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"flow.md\">FLOW\u003C/a> — Boxplot for factor comparison\u003C/li>\n\u003C/ul>", + { + "headings": 6146, + "localImagePaths": 6195, + "remoteImagePaths": 6196, + "frontmatter": 6197, + "imagePaths": 6198 + }, + [ + 6147, 6149, 6152, 6155, 6158, 6161, 6164, 6167, 6170, 6173, 6176, 6179, 6182, 6185, 6188, 6191, + 6194 + ], + { "depth": 30, "slug": 6148, "text": 6136 }, + "drill-down-progressive-variation-analysis", + { "depth": 33, "slug": 6150, "text": 6151 }, + "the-drill-down-logic", + "The Drill-Down Logic", + { "depth": 79, "slug": 6153, "text": 6154 }, + "decision-thresholds", + "Decision Thresholds", + { "depth": 79, "slug": 6156, "text": 6157 }, + "example-drill-down-journey", + "Example Drill-Down Journey", + { "depth": 79, "slug": 6159, "text": 6160 }, + "filter-chips-ui", + "Filter Chips UI", + { "depth": 33, "slug": 6162, "text": 6163 }, + "cumulative-variation-tracking", + "Cumulative Variation Tracking", + { "depth": 79, "slug": 6165, "text": 6166 }, + "the-math-behind-contribution", + "The Math Behind Contribution %", + { "depth": 33, "slug": 6168, "text": 6169 }, + "why-this-changes-everything", + "Why This Changes Everything", + { "depth": 33, "slug": 6171, "text": 6172 }, + "the-actionability-hierarchy", + "The Actionability Hierarchy", + { "depth": 33, "slug": 6174, "text": 6175 }, + "reading-filter-chips", + "Reading Filter Chips", + { "depth": 33, "slug": 6177, "text": 6178 }, + "multi-select-capability", + "Multi-Select Capability", + { "depth": 33, "slug": 6180, "text": 6181 }, + "the-half-your-problem-threshold", + "The “Half Your Problem” Threshold", + { "depth": 33, "slug": 6183, "text": 6184 }, + "visual-the-variation-funnel", + "Visual: The Variation Funnel", + { "depth": 33, "slug": 6186, "text": 6187 }, + "practical-example-cost-of-inaction-vs-action", + "Practical Example: Cost of Inaction vs Action", + { "depth": 33, "slug": 6189, "text": 6190 }, + "filter-chips-as-communication-tool", + "Filter Chips as Communication Tool", + { "depth": 33, "slug": 6192, "text": 6193 }, + "implementation-in-variscout-ui", + "Implementation in VariScout UI", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6136 }, + [], + "01-vision/four-lenses/failure", + { "id": 6199, "data": 6201, "body": 6206, "filePath": 6207, "digest": 6208, "rendered": 6209 }, + { + "title": 6202, + "editUrl": 16, + "head": 6203, + "template": 18, + "sidebar": 6204, + "pagefind": 16, + "draft": 20 + }, + "FAILURE Lens: Pareto", + [], + { "hidden": 20, "attrs": 6205 }, + {}, + "# FAILURE Lens: Pareto\n\n> The Integrity Lens — look at where problems concentrate\n\nThe FAILURE lens asks what happens when you count and rank the things that go wrong. The same data that averages describe as \"95% good\" reveals that most problems cluster in a few specific categories when viewed through this lens.\n\n---\n\n## The Question\n\n_\"Where do problems concentrate? Is 'chaotic data' actually mixed streams?\"_\n\n---\n\n## What the Pareto Reveals\n\n- Which categories contain most defects/issues\n- The vital few vs trivial many (80/20 rule)\n- Hidden patterns in \"generic scrap buckets\"\n- Whether failure modes are being masked\n\n---\n\n## Key Insight from Sock Mystery\n\n> \"A 'bad process' is often just a 'badly grouped' process.\"\n\nChaotic control charts with Cp \u003C 1.0 weren't bad data — they were mixed subgroups. The Pareto finds the \"blood spatter\" pattern.\n\n---\n\n## VariScout Implementation\n\n- Frequency analysis of any categorical column\n- Cumulative percentage line\n- Click any bar → filters to that category\n- Reveals which factor level drives most problems\n\n---\n\n## The Reality Check\n\n> \"Is chaotic data masking a 'mixed subgroup' problem?\"\n\nQuestions to ask:\n\n- The \"Chaos\" signal (Cp \u003C 1.0)\n- Generic scrap buckets\n- Multi-modal distributions\n\n---\n\n## Chart-to-Lens Reference\n\n| Lens | Chart | Key Metric | Key Visual | User Action |\n| ------- | ------ | ------------------ | ---------------------------- | ------------------------------ |\n| FAILURE | Pareto | Category frequency | Bar height + cumulative line | Click bar → filter to category |\n\n---\n\n## See Also\n\n- [Four Lenses Overview](index.md)\n- [Drill-Down](drilldown.md) — Progressive analysis methodology", + "src/content/docs/01-vision/four-lenses/failure.md", + "ec5a4ed2e1ba0e71", + { "html": 6210, "metadata": 6211 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"failure-lens-pareto\">FAILURE Lens: Pareto\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#failure-lens-pareto\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “FAILURE Lens: Pareto”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>The Integrity Lens — look at where problems concentrate\u003C/p>\n\u003C/blockquote>\n\u003Cp>The FAILURE lens asks what happens when you count and rank the things that go wrong. The same data that averages describe as “95% good” reveals that most problems cluster in a few specific categories when viewed through this lens.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-question\">The Question\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-question\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Question”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Where do problems concentrate? Is ‘chaotic data’ actually mixed streams?”\u003C/em>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-the-pareto-reveals\">What the Pareto Reveals\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-the-pareto-reveals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What the Pareto Reveals”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Which categories contain most defects/issues\u003C/li>\n\u003Cli>The vital few vs trivial many (80/20 rule)\u003C/li>\n\u003Cli>Hidden patterns in “generic scrap buckets”\u003C/li>\n\u003Cli>Whether failure modes are being masked\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-insight-from-sock-mystery\">Key Insight from Sock Mystery\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-insight-from-sock-mystery\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Insight from Sock Mystery”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“A ‘bad process’ is often just a ‘badly grouped’ process.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Chaotic control charts with Cp < 1.0 weren’t bad data — they were mixed subgroups. The Pareto finds the “blood spatter” pattern.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-implementation\">VariScout Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Frequency analysis of any categorical column\u003C/li>\n\u003Cli>Cumulative percentage line\u003C/li>\n\u003Cli>Click any bar → filters to that category\u003C/li>\n\u003Cli>Reveals which factor level drives most problems\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-reality-check\">The Reality Check\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-reality-check\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Reality Check”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“Is chaotic data masking a ‘mixed subgroup’ problem?”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Questions to ask:\u003C/p>\n\u003Cul>\n\u003Cli>The “Chaos” signal (Cp < 1.0)\u003C/li>\n\u003Cli>Generic scrap buckets\u003C/li>\n\u003Cli>Multi-modal distributions\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-to-lens-reference\">Chart-to-Lens Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-to-lens-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart-to-Lens Reference”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Lens\u003C/th>\u003Cth>Chart\u003C/th>\u003Cth>Key Metric\u003C/th>\u003Cth>Key Visual\u003C/th>\u003Cth>User Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>FAILURE\u003C/td>\u003Ctd>Pareto\u003C/td>\u003Ctd>Category frequency\u003C/td>\u003Ctd>Bar height + cumulative line\u003C/td>\u003Ctd>Click bar → filter to category\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Four Lenses Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"drilldown.md\">Drill-Down\u003C/a> — Progressive analysis methodology\u003C/li>\n\u003C/ul>", + { + "headings": 6212, + "localImagePaths": 6224, + "remoteImagePaths": 6225, + "frontmatter": 6226, + "imagePaths": 6227 + }, + [6213, 6215, 6216, 6219, 6220, 6221, 6222, 6223], + { "depth": 30, "slug": 6214, "text": 6202 }, + "failure-lens-pareto", + { "depth": 33, "slug": 6111, "text": 6112 }, + { "depth": 33, "slug": 6217, "text": 6218 }, + "what-the-pareto-reveals", + "What the Pareto Reveals", + { "depth": 33, "slug": 6117, "text": 6118 }, + { "depth": 33, "slug": 6120, "text": 6121 }, + { "depth": 33, "slug": 6123, "text": 6124 }, + { "depth": 33, "slug": 6126, "text": 6127 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6202 }, + [], + "01-vision/four-lenses/flow", + { "id": 6228, "data": 6230, "body": 6235, "filePath": 6236, "digest": 6237, "rendered": 6238 }, + { + "title": 6231, + "editUrl": 16, + "head": 6232, + "template": 18, + "sidebar": 6233, + "pagefind": 16, + "draft": 20 + }, + "FLOW Lens: Boxplot", + [], + { "hidden": 20, "attrs": 6234 }, + {}, + "# FLOW Lens: Boxplot\n\n> The Structural Lens — look at the same data grouped by factor\n\nThe FLOW lens asks what happens when you split your data by a categorical factor (machine, shift, operator). The same measurements that look uniform as one distribution reveal very different spreads when viewed through this lens.\n\n---\n\n## The Question\n\n_\"Which upstream inputs explain the variation I see downstream?\"_\n\n---\n\n## What the Boxplot Reveals\n\n- Comparison across factors (Machine A vs B vs C)\n- Between-group vs within-group variation\n- Which subgroup contributes most variation\n- The \"soup ingredients\" that create the output\n\n---\n\n## Key Insight from Sock Mystery\n\n> \"Don't measure the 'soup' until you know the ingredients.\"\n\nParticipants initially measured output (sock length) without understanding inputs (size settings S/M/L). The boxplot traces footprints upstream.\n\n---\n\n## VariScout Implementation\n\n- Compare any factor column (Machine, Shift, Operator, etc.)\n- IQR-based outlier detection\n- Visual median/spread comparison\n- Violin mode: toggle density curves to reveal distribution shape (bimodality, skewness)\n- Click any box → filters all other charts to that subgroup\n\n---\n\n## The Reality Check\n\n> \"Have we identified upstream inputs before measuring downstream outputs?\"\n\nQuestions to ask:\n\n- Input visibility\n- Merge points\n- Traceability\n\n---\n\n## Chart-to-Lens Reference\n\n| Lens | Chart | Key Metric | Key Visual | User Action |\n| ---- | ------- | ------------------------- | ------------------------------ | ------------------------------ |\n| FLOW | Boxplot | Between-group variation % | Box position/spread comparison | Click box → filter to subgroup |\n\n---\n\n## See Also\n\n- [Four Lenses Overview](index.md)\n- [Drill-Down](drilldown.md) — How to drill into variation sources", + "src/content/docs/01-vision/four-lenses/flow.md", + "e9116b8ad580c6c7", + { "html": 6239, "metadata": 6240 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"flow-lens-boxplot\">FLOW Lens: Boxplot\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#flow-lens-boxplot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “FLOW Lens: Boxplot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>The Structural Lens — look at the same data grouped by factor\u003C/p>\n\u003C/blockquote>\n\u003Cp>The FLOW lens asks what happens when you split your data by a categorical factor (machine, shift, operator). The same measurements that look uniform as one distribution reveal very different spreads when viewed through this lens.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-question\">The Question\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-question\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Question”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Which upstream inputs explain the variation I see downstream?”\u003C/em>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-the-boxplot-reveals\">What the Boxplot Reveals\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-the-boxplot-reveals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What the Boxplot Reveals”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Comparison across factors (Machine A vs B vs C)\u003C/li>\n\u003Cli>Between-group vs within-group variation\u003C/li>\n\u003Cli>Which subgroup contributes most variation\u003C/li>\n\u003Cli>The “soup ingredients” that create the output\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-insight-from-sock-mystery\">Key Insight from Sock Mystery\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-insight-from-sock-mystery\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Insight from Sock Mystery”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“Don’t measure the ‘soup’ until you know the ingredients.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Participants initially measured output (sock length) without understanding inputs (size settings S/M/L). The boxplot traces footprints upstream.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-implementation\">VariScout Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Compare any factor column (Machine, Shift, Operator, etc.)\u003C/li>\n\u003Cli>IQR-based outlier detection\u003C/li>\n\u003Cli>Visual median/spread comparison\u003C/li>\n\u003Cli>Violin mode: toggle density curves to reveal distribution shape (bimodality, skewness)\u003C/li>\n\u003Cli>Click any box → filters all other charts to that subgroup\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-reality-check\">The Reality Check\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-reality-check\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Reality Check”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“Have we identified upstream inputs before measuring downstream outputs?”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Questions to ask:\u003C/p>\n\u003Cul>\n\u003Cli>Input visibility\u003C/li>\n\u003Cli>Merge points\u003C/li>\n\u003Cli>Traceability\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-to-lens-reference\">Chart-to-Lens Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-to-lens-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart-to-Lens Reference”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Lens\u003C/th>\u003Cth>Chart\u003C/th>\u003Cth>Key Metric\u003C/th>\u003Cth>Key Visual\u003C/th>\u003Cth>User Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>FLOW\u003C/td>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Between-group variation %\u003C/td>\u003Ctd>Box position/spread comparison\u003C/td>\u003Ctd>Click box → filter to subgroup\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Four Lenses Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"drilldown.md\">Drill-Down\u003C/a> — How to drill into variation sources\u003C/li>\n\u003C/ul>", + { + "headings": 6241, + "localImagePaths": 6253, + "remoteImagePaths": 6254, + "frontmatter": 6255, + "imagePaths": 6256 + }, + [6242, 6244, 6245, 6248, 6249, 6250, 6251, 6252], + { "depth": 30, "slug": 6243, "text": 6231 }, + "flow-lens-boxplot", + { "depth": 33, "slug": 6111, "text": 6112 }, + { "depth": 33, "slug": 6246, "text": 6247 }, + "what-the-boxplot-reveals", + "What the Boxplot Reveals", + { "depth": 33, "slug": 6117, "text": 6118 }, + { "depth": 33, "slug": 6120, "text": 6121 }, + { "depth": 33, "slug": 6123, "text": 6124 }, + { "depth": 33, "slug": 6126, "text": 6127 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6231 }, + [], + "01-vision/four-lenses", + { "id": 6257, "data": 6259, "body": 6264, "filePath": 6265, "digest": 6266, "rendered": 6267 }, + { + "title": 6260, + "editUrl": 16, + "head": 6261, + "template": 18, + "sidebar": 6262, + "pagefind": 16, + "draft": 20 + }, + "Watson's Four Lenses of Process Knowledge", + [], + { "hidden": 20, "attrs": 6263 }, + {}, + "# Watson's Four Lenses of Process Knowledge\n\n> \"VariScout doesn't just display charts — it gives you four lenses to see what averages hide.\"\n\n---\n\n## Why Lenses?\n\nThe Four Lenses are not sequential steps — they are **parallel lenses** on the same data. Each lens asks a fundamentally different question. Apply them in any order, combine them through drill-down, and the same dataset reveals different truths depending on which lens you look through.\n\nThink of a detective examining a crime scene: the same evidence looks different under UV light, through a magnifying glass, or in a timeline reconstruction. VariScout's four charts work the same way — four lenses, one dataset, four kinds of insight.\n\n---\n\n## The Core Insight\n\nVariScout's four core charts aren't random statistical outputs. Each chart directly maps to one of Watson's Four Lenses of Process Knowledge — each a distinct **lens** on your data:\n\n| Chart | Lens | Core Question |\n| ------------------------ | ----------- | --------------------------------- |\n| **I-Chart** | **CHANGE** | \"What's shifting over time?\" |\n| **Boxplot** | **FLOW** | \"Where does variation come from?\" |\n| **Pareto** | **FAILURE** | \"Where do problems cluster?\" |\n| **Capability Histogram** | **VALUE** | \"Does it meet customer specs?\" |\n\n### Add-on: Regression (Correlation Check)\n\n| Chart | Purpose | Core Question |\n| -------------- | ----------------- | ----------------------------------------------- |\n| **Regression** | Correlation Check | \"Is there even a relationship between X and Y?\" |\n\n:::note\nRegression in VariScout serves as a **first step** to visually check if correlation exists between two continuous variables. It answers \"is there a relationship?\" before investing in deeper predictive modeling. For most variation analysis, the Four Lenses are sufficient.\n:::\n\n---\n\n## The Four Lenses\n\n\u003Cdiv class=\"grid cards\" markdown>\n\n- :material-chart-line:{ .lg .middle } **CHANGE lens**\n\n ***\n\n I-Chart reveals time-based stability. \"Is something shifting over time?\"\n\n [:octicons-arrow-right-24: Learn more](change.md)\n\n- :material-chart-box:{ .lg .middle } **FLOW lens**\n\n ***\n\n Boxplot traces variation upstream. \"Which inputs explain the output?\"\n\n [:octicons-arrow-right-24: Learn more](flow.md)\n\n- :material-chart-bar:{ .lg .middle } **FAILURE lens**\n\n ***\n\n Pareto finds where problems concentrate. \"What matters most?\"\n\n [:octicons-arrow-right-24: Learn more](failure.md)\n\n- :material-chart-histogram:{ .lg .middle } **VALUE lens**\n\n ***\n\n Capability compares to customer specs. \"Are we meeting needs?\"\n A different type of question — VALUE brings in an external reference (customer specs) rather than analyzing internal process behavior.\n\n [:octicons-arrow-right-24: Learn more](value.md)\n\n\u003C/div>\n\n---\n\n## The System Dynamics\n\nThe four lenses don't work in isolation — they're meshed gears:\n\n```\n ┌─────────┐\n │ CHANGE │ ← Dynamic factor: wear, shifts, seasons\n │(I-Chart)│\n └────┬────┘\n │\n ▼\n┌─────────┐ ┌─────────┐\n│ FLOW │◄───►│ FAILURE │\n│(Boxplot)│ │(Pareto) │\n└────┬────┘ └────┬────┘\n │ │\n └───────┬───────┘\n │\n ▼\n ┌─────────┐\n │ VALUE │ ← Drive gear: if undefined, nothing turns correctly\n │(Capable)│\n └─────────┘\n```\n\n**VariScout's Linked Filtering = Gear Meshing**\n\nWhen you click on one chart, all others respond. This isn't just a UI feature — it's how the lenses interconnect:\n\n| Action | System Response |\n| ---------------------------- | ---------------------------------------------------------- |\n| Click \"Machine B\" in Boxplot | I-Chart shows only Machine B's timeline |\n| | Pareto shows only Machine B's failure modes |\n| | Capability recalculates for Machine B alone |\n| Click \"Above UCL\" in I-Chart | Boxplot highlights which factors had out-of-control points |\n| | Pareto shows defect types during unstable periods |\n\n---\n\n## Progressive Analysis: Drill-Down\n\nThe lenses support progressive analysis through drill-down:\n\n1. **Level 1:** All Data — identify top-level patterns\n2. **Level 2:** Filter to dominant factor — zoom in\n3. **Level 3:** Within filtered data, find next factor\n4. **Continue** until actionable condition is isolated\n\n[:octicons-arrow-right-24: Drill-Down Methodology](drilldown.md)\n\n---\n\n## Reference\n\nBased on Watson's Four Lenses framework, the Sock Mystery experiential exercise, and the VariScout product design.", + "src/content/docs/01-vision/four-lenses/index.md", + "c21f7a384a08be6a", + { "html": 6268, "metadata": 6269 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"watsons-four-lenses-of-process-knowledge\">Watson’s Four Lenses of Process Knowledge\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#watsons-four-lenses-of-process-knowledge\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Watson’s Four Lenses of Process Knowledge”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“VariScout doesn’t just display charts — it gives you four lenses to see what averages hide.”\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-lenses\">Why Lenses?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-lenses\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Lenses?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Four Lenses are not sequential steps — they are \u003Cstrong>parallel lenses\u003C/strong> on the same data. Each lens asks a fundamentally different question. Apply them in any order, combine them through drill-down, and the same dataset reveals different truths depending on which lens you look through.\u003C/p>\n\u003Cp>Think of a detective examining a crime scene: the same evidence looks different under UV light, through a magnifying glass, or in a timeline reconstruction. VariScout’s four charts work the same way — four lenses, one dataset, four kinds of insight.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-core-insight\">The Core Insight\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-core-insight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Core Insight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s four core charts aren’t random statistical outputs. Each chart directly maps to one of Watson’s Four Lenses of Process Knowledge — each a distinct \u003Cstrong>lens\u003C/strong> on your data:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Lens\u003C/th>\u003Cth>Core Question\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>I-Chart\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>CHANGE\u003C/strong>\u003C/td>\u003Ctd>”What’s shifting over time?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Boxplot\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>FLOW\u003C/strong>\u003C/td>\u003Ctd>”Where does variation come from?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pareto\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>FAILURE\u003C/strong>\u003C/td>\u003Ctd>”Where do problems cluster?”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Capability Histogram\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>VALUE\u003C/strong>\u003C/td>\u003Ctd>”Does it meet customer specs?”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"add-on-regression-correlation-check\">Add-on: Regression (Correlation Check)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#add-on-regression-correlation-check\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Add-on: Regression (Correlation Check)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Core Question\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Regression\u003C/strong>\u003C/td>\u003Ctd>Correlation Check\u003C/td>\u003Ctd>”Is there even a relationship between X and Y?”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Caside aria-label=\"Note\" class=\"starlight-aside starlight-aside--note\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath d=\"M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z\">\u003C/path>\u003C/svg>Note\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>Regression in VariScout serves as a \u003Cstrong>first step\u003C/strong> to visually check if correlation exists between two continuous variables. It answers “is there a relationship?” before investing in deeper predictive modeling. For most variation analysis, the Four Lenses are sufficient.\u003C/p>\u003C/div>\u003C/aside>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-four-lenses\">The Four Lenses\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-four-lenses\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Four Lenses”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"grid cards\" markdown=\"\">\n\u003Cul>\n\u003Cli>\n\u003Cp>:material-chart-line:{ .lg .middle } \u003Cstrong>CHANGE lens\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>I-Chart reveals time-based stability. “Is something shifting over time?”\u003C/p>\n\u003Cp>\u003Ca href=\"change.md\">:octicons-arrow-right-24: Learn more\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-chart-box:{ .lg .middle } \u003Cstrong>FLOW lens\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>Boxplot traces variation upstream. “Which inputs explain the output?”\u003C/p>\n\u003Cp>\u003Ca href=\"flow.md\">:octicons-arrow-right-24: Learn more\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-chart-bar:{ .lg .middle } \u003Cstrong>FAILURE lens\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>Pareto finds where problems concentrate. “What matters most?”\u003C/p>\n\u003Cp>\u003Ca href=\"failure.md\">:octicons-arrow-right-24: Learn more\u003C/a>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>:material-chart-histogram:{ .lg .middle } \u003Cstrong>VALUE lens\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cp>Capability compares to customer specs. “Are we meeting needs?”\nA different type of question — VALUE brings in an external reference (customer specs) rather than analyzing internal process behavior.\u003C/p>\n\u003Cp>\u003Ca href=\"value.md\">:octicons-arrow-right-24: Learn more\u003C/a>\u003C/p>\n\u003C/li>\n\u003C/ul>\n\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-system-dynamics\">The System Dynamics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-system-dynamics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The System Dynamics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The four lenses don’t work in isolation — they’re meshed gears:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CHANGE │ ← Dynamic factor: wear, shifts, seasons\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│(I-Chart)│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────┬────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────┐ ┌─────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ FLOW │◄───►│ FAILURE │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│(Boxplot)│ │(Pareto) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────┬────┘ └────┬────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───────┬───────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ VALUE │ ← Drive gear: if undefined, nothing turns correctly\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│(Capable)│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" ┌─────────┐ │ CHANGE │ ← Dynamic factor: wear, shifts, seasons │(I-Chart)│ └────┬────┘ │ ▼┌─────────┐ ┌─────────┐│ FLOW │◄───►│ FAILURE ││(Boxplot)│ │(Pareto) │└────┬────┘ └────┬────┘ │ │ └───────┬───────┘ │ ▼ ┌─────────┐ │ VALUE │ ← Drive gear: if undefined, nothing turns correctly │(Capable)│ └─────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>VariScout’s Linked Filtering = Gear Meshing\u003C/strong>\u003C/p>\n\u003Cp>When you click on one chart, all others respond. This isn’t just a UI feature — it’s how the lenses interconnect:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>System Response\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Click “Machine B” in Boxplot\u003C/td>\u003Ctd>I-Chart shows only Machine B’s timeline\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003C/td>\u003Ctd>Pareto shows only Machine B’s failure modes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003C/td>\u003Ctd>Capability recalculates for Machine B alone\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Click “Above UCL” in I-Chart\u003C/td>\u003Ctd>Boxplot highlights which factors had out-of-control points\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003C/td>\u003Ctd>Pareto shows defect types during unstable periods\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"progressive-analysis-drill-down\">Progressive Analysis: Drill-Down\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#progressive-analysis-drill-down\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Progressive Analysis: Drill-Down”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The lenses support progressive analysis through drill-down:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Level 1:\u003C/strong> All Data — identify top-level patterns\u003C/li>\n\u003Cli>\u003Cstrong>Level 2:\u003C/strong> Filter to dominant factor — zoom in\u003C/li>\n\u003Cli>\u003Cstrong>Level 3:\u003C/strong> Within filtered data, find next factor\u003C/li>\n\u003Cli>\u003Cstrong>Continue\u003C/strong> until actionable condition is isolated\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Ca href=\"drilldown.md\">:octicons-arrow-right-24: Drill-Down Methodology\u003C/a>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"reference\">Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Based on Watson’s Four Lenses framework, the Sock Mystery experiential exercise, and the VariScout product design.\u003C/p>", + { + "headings": 6270, + "localImagePaths": 6291, + "remoteImagePaths": 6292, + "frontmatter": 6293, + "imagePaths": 6294 + }, + [6271, 6274, 6277, 6280, 6283, 6286, 6287, 6290], + { "depth": 30, "slug": 6272, "text": 6273 }, + "watsons-four-lenses-of-process-knowledge", + "Watson’s Four Lenses of Process Knowledge", + { "depth": 33, "slug": 6275, "text": 6276 }, + "why-lenses", + "Why Lenses?", + { "depth": 33, "slug": 6278, "text": 6279 }, + "the-core-insight", + "The Core Insight", + { "depth": 79, "slug": 6281, "text": 6282 }, + "add-on-regression-correlation-check", + "Add-on: Regression (Correlation Check)", + { "depth": 33, "slug": 6284, "text": 6285 }, + "the-four-lenses", + "The Four Lenses", + { "depth": 33, "slug": 875, "text": 876 }, + { "depth": 33, "slug": 6288, "text": 6289 }, + "progressive-analysis-drill-down", + "Progressive Analysis: Drill-Down", + { "depth": 33, "slug": 5948, "text": 5949 }, + [], + [], + { "title": 6260 }, + [], + "01-vision/four-lenses/value", + { "id": 6295, "data": 6297, "body": 6302, "filePath": 6303, "digest": 6304, "rendered": 6305 }, + { + "title": 6298, + "editUrl": 16, + "head": 6299, + "template": 18, + "sidebar": 6300, + "pagefind": 16, + "draft": 20 + }, + "VALUE Lens: Capability Histogram", + [], + { "hidden": 20, "attrs": 6301 }, + {}, + "# VALUE Lens: Capability Histogram\n\n> The Alignment Lens — a different type of question\n\nThe VALUE lens is fundamentally different from the other three. While CHANGE, FLOW, and FAILURE analyze internal process behavior (what the process is doing), VALUE brings in an **external reference** — the customer's specification. It asks: \"does the variation we found actually matter to the customer?\"\n\nThis makes VALUE a different kind of question, and often a different kind of story. The detective lenses (CHANGE, FLOW, FAILURE) find the source of variation. The VALUE lens determines whether it's worth fixing.\n\n---\n\n## The Question\n\n_\"Are we measuring what the customer actually experiences? Do we meet their specs?\"_\n\n---\n\n## What the Capability Histogram Reveals\n\n- Distribution shape (normal, bimodal, skewed)\n- Position relative to specifications (USL/LSL/Target)\n- Cp/Cpk metrics (process capability)\n- Pass/fail percentage\n\n---\n\n## Key Insight from Sock Mystery\n\n> \"If you get Value wrong, the rest of the analysis is meaningless.\"\n\nThe demand for \"consistent length\" only made sense within a size category. Rational subgroups must align with how customers experience variation.\n\n---\n\n## VariScout Implementation\n\n- Specification limit inputs (USL/LSL/Target)\n- Cp/Cpk calculation with visual indicators\n- Distribution overlay on histogram\n- Multi-tier grading support (coffee A/B/C grades, etc.)\n\n---\n\n## The Reality Check\n\n> \"Are we measuring what the customer actually experiences?\"\n\nQuestions to ask:\n\n- Customer vs Machine CTQ\n- Relative vs Absolute specs\n- The \"So What?\" test\n\n---\n\n## Chart-to-Lens Reference\n\n| Lens | Chart | Key Metric | Key Visual | User Action |\n| ----- | ---------- | ---------- | ----------------------- | ------------------ |\n| VALUE | Capability | Cp/Cpk | Histogram vs spec lines | Set USL/LSL/Target |\n\n---\n\n## See Also\n\n- [Four Lenses Overview](index.md)\n- [Two Voices](../two-voices/index.md) — Control limits vs specification limits", + "src/content/docs/01-vision/four-lenses/value.md", + "f5c5d92cc3397512", + { "html": 6306, "metadata": 6307 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"value-lens-capability-histogram\">VALUE Lens: Capability Histogram\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#value-lens-capability-histogram\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VALUE Lens: Capability Histogram”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>The Alignment Lens — a different type of question\u003C/p>\n\u003C/blockquote>\n\u003Cp>The VALUE lens is fundamentally different from the other three. While CHANGE, FLOW, and FAILURE analyze internal process behavior (what the process is doing), VALUE brings in an \u003Cstrong>external reference\u003C/strong> — the customer’s specification. It asks: “does the variation we found actually matter to the customer?”\u003C/p>\n\u003Cp>This makes VALUE a different kind of question, and often a different kind of story. The detective lenses (CHANGE, FLOW, FAILURE) find the source of variation. The VALUE lens determines whether it’s worth fixing.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-question\">The Question\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-question\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Question”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Are we measuring what the customer actually experiences? Do we meet their specs?”\u003C/em>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-the-capability-histogram-reveals\">What the Capability Histogram Reveals\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-the-capability-histogram-reveals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What the Capability Histogram Reveals”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Distribution shape (normal, bimodal, skewed)\u003C/li>\n\u003Cli>Position relative to specifications (USL/LSL/Target)\u003C/li>\n\u003Cli>Cp/Cpk metrics (process capability)\u003C/li>\n\u003Cli>Pass/fail percentage\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-insight-from-sock-mystery\">Key Insight from Sock Mystery\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-insight-from-sock-mystery\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Insight from Sock Mystery”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“If you get Value wrong, the rest of the analysis is meaningless.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>The demand for “consistent length” only made sense within a size category. Rational subgroups must align with how customers experience variation.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-implementation\">VariScout Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Specification limit inputs (USL/LSL/Target)\u003C/li>\n\u003Cli>Cp/Cpk calculation with visual indicators\u003C/li>\n\u003Cli>Distribution overlay on histogram\u003C/li>\n\u003Cli>Multi-tier grading support (coffee A/B/C grades, etc.)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-reality-check\">The Reality Check\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-reality-check\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Reality Check”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“Are we measuring what the customer actually experiences?”\u003C/p>\n\u003C/blockquote>\n\u003Cp>Questions to ask:\u003C/p>\n\u003Cul>\n\u003Cli>Customer vs Machine CTQ\u003C/li>\n\u003Cli>Relative vs Absolute specs\u003C/li>\n\u003Cli>The “So What?” test\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-to-lens-reference\">Chart-to-Lens Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-to-lens-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart-to-Lens Reference”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Lens\u003C/th>\u003Cth>Chart\u003C/th>\u003Cth>Key Metric\u003C/th>\u003Cth>Key Visual\u003C/th>\u003Cth>User Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>VALUE\u003C/td>\u003Ctd>Capability\u003C/td>\u003Ctd>Cp/Cpk\u003C/td>\u003Ctd>Histogram vs spec lines\u003C/td>\u003Ctd>Set USL/LSL/Target\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Four Lenses Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../two-voices/index.md\">Two Voices\u003C/a> — Control limits vs specification limits\u003C/li>\n\u003C/ul>", + { + "headings": 6308, + "localImagePaths": 6320, + "remoteImagePaths": 6321, + "frontmatter": 6322, + "imagePaths": 6323 + }, + [6309, 6311, 6312, 6315, 6316, 6317, 6318, 6319], + { "depth": 30, "slug": 6310, "text": 6298 }, + "value-lens-capability-histogram", + { "depth": 33, "slug": 6111, "text": 6112 }, + { "depth": 33, "slug": 6313, "text": 6314 }, + "what-the-capability-histogram-reveals", + "What the Capability Histogram Reveals", + { "depth": 33, "slug": 6117, "text": 6118 }, + { "depth": 33, "slug": 6120, "text": 6121 }, + { "depth": 33, "slug": 6123, "text": 6124 }, + { "depth": 33, "slug": 6126, "text": 6127 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6298 }, + [], + "03-features/analysis/boxplot", + { "id": 6324, "data": 6326, "body": 6331, "filePath": 6332, "digest": 6333, "rendered": 6334 }, + { + "title": 6327, + "editUrl": 16, + "head": 6328, + "template": 18, + "sidebar": 6329, + "pagefind": 16, + "draft": 20 + }, + "Boxplot", + [], + { "hidden": 20, "attrs": 6330 }, + {}, + "\u003C!-- journey-phase: scout -->\n\n# Boxplot\n\nThe Boxplot is VariScout's tool for the **FLOW** lens - comparing variation across factors.\n\n---\n\n## Purpose\n\n_\"Which upstream inputs explain the variation I see downstream?\"_\n\nThe Boxplot reveals:\n\n- Comparison across factors (Machine A vs B vs C)\n- Between-group vs within-group variation\n- Which subgroup contributes most variation\n- The \"soup ingredients\" that create the output\n\n---\n\n## Key Elements\n\n| Element | Description |\n| ----------- | ----------------------------------------------- |\n| Box | Interquartile range (IQR, 25th-75th percentile) |\n| Median line | Middle value (50th percentile) |\n| Whiskers | Extend to 1.5×IQR from box |\n| Outliers | Points beyond whiskers |\n\n---\n\n## ANOVA Statistics\n\nWhen comparing factors, VariScout calculates:\n\n| Statistic | Description |\n| ---------------- | -------------------------------- |\n| F-statistic | Ratio of between/within variance |\n| p-value | Probability of chance difference |\n| η² (eta-squared) | Proportion of variance explained |\n\nSee [Variation Decomposition](variation-decomposition.md) for how η² relates to the category-level Total SS metrics shown in the Mindmap and contribution labels.\n\n---\n\n## Interpretation\n\n| Pattern | Meaning |\n| --------------------- | ------------------------------- |\n| Non-overlapping boxes | Significant difference |\n| High η² | Factor explains much variation |\n| Wide box | High variation within group |\n| Many outliers | Check data quality or subgroups |\n\n---\n\n## Violin Mode (Distribution Shape)\n\nToggle **Show distribution shape** in Settings to switch to violin-primary rendering (industry standard, matching Seaborn/Plotly/ggplot2). This uses Kernel Density Estimation (KDE) with a Gaussian kernel and Silverman's rule-of-thumb bandwidth.\n\n| Pattern | What the violin reveals |\n| ----------------- | ---------------------------------------------------- |\n| Single peak | Unimodal process, well-centered |\n| Two peaks | Bimodal distribution — likely two process conditions |\n| Skewed shape | Asymmetric process — investigate cause |\n| Wide/narrow shape | Variation magnitude at a glance |\n\nWhen enabled, the density curve becomes the dominant shape with a thin IQR box inside showing Q1-Q3 range, median line, and mean diamond. Whiskers and outliers are hidden since the density curve conveys the full distribution shape.\n\nAvailable in PWA and Azure App.\n\n---\n\n## Category Sorting\n\nSort boxplot categories by **Name** (alphabetical, default), **Mean**, or **Spread** (IQR). Toggle ascending/descending direction.\n\nAccess via the display options icon (SlidersHorizontal) in the Boxplot card header — the same popover that controls Violin Mode and Contribution Labels.\n\n| Sort Criterion | What it reveals |\n| -------------- | ---------------------------------------------------------- |\n| Name (default) | Alphabetical order — stable reference view |\n| Mean | Rank categories by center — find highest/lowest performers |\n| Spread | Rank by IQR — find most/least consistent categories |\n\nAvailable in both PWA and Azure App.\n\n---\n\n## Direction Coloring\n\nWhen specification limits are set, boxplot categories are colored by how well their mean aligns with the quality goal. The [characteristic type](characteristic-types.md) determines what \"best\" means:\n\n- **Smaller-is-better**: lowest mean = green (best), highest mean = red (worst)\n- **Larger-is-better**: highest mean = green, lowest mean = red\n- **Nominal**: closest to target = green, furthest = red\n\nCategories are ranked into thirds (green / amber / red). With 2 categories: best = green, worst = red. With 1 category: neutral gray.\n\nDirection coloring combines with the existing [variation contribution](variation-decomposition.md) bars: box fill shows quality direction (green/amber/red), contribution bar shows variation impact. Together they highlight categories that are both high-impact and poorly performing.\n\nManual annotation highlights (right-click) always override auto-colors. When specs are hidden or cleared, boxes revert to neutral gray.\n\n---\n\n## Linked Filtering\n\nClick any box to:\n\n- Filter all charts to that subgroup\n- See I-Chart for just that factor level\n- Continue drill-down analysis\n\n---\n\n---\n\n## Technical Reference\n\nVariScout's implementation:\n\n```typescript\n// From @variscout/core\nimport { calculateAnova, getEtaSquared } from '@variscout/core';\n\nconst anova = calculateAnova(data, 'Machine', 'Weight');\n// Returns: { fStatistic, pValue, etaSquared, groups }\n\nconst etaSq = getEtaSquared(data, 'Machine', 'Weight');\n// Returns: number (0-1)\n```\n\n**Test coverage:** See `packages/core/src/__tests__/stats.test.ts` for ANOVA tests.\n\n---\n\n## See Also\n\n- [FLOW Lens](../../01-vision/four-lenses/flow.md) - Upstream factor concepts\n- [Drill-Down](../navigation/drill-down.md) - Multi-level factor exploration\n- [I-Chart](i-chart.md) - Previous step: detect instability over time\n- [Pareto](pareto.md) - Next step: rank contribution of factors\n- [Regression](regression.md) - When to check for interactions\n- [Chart Design](../../06-design-system/charts/boxplot.md)\n- [Glossary: η² (Eta-squared)](../../glossary.md#2-eta-squared)\n- [Glossary: F-statistic](../../glossary.md#f-statistic)\n- [Case: Bottleneck](../../04-cases/bottleneck/index.md) - Factor comparison example", + "src/content/docs/03-features/analysis/boxplot.md", + "28665d19e37395fd", + { "html": 6335, "metadata": 6336 }, + "\u003C!-- journey-phase: scout -->\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"boxplot\">Boxplot\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#boxplot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Boxplot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Boxplot is VariScout’s tool for the \u003Cstrong>FLOW\u003C/strong> lens - comparing variation across factors.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Which upstream inputs explain the variation I see downstream?”\u003C/em>\u003C/p>\n\u003Cp>The Boxplot reveals:\u003C/p>\n\u003Cul>\n\u003Cli>Comparison across factors (Machine A vs B vs C)\u003C/li>\n\u003Cli>Between-group vs within-group variation\u003C/li>\n\u003Cli>Which subgroup contributes most variation\u003C/li>\n\u003Cli>The “soup ingredients” that create the output\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-elements\">Key Elements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Elements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Box\u003C/td>\u003Ctd>Interquartile range (IQR, 25th-75th percentile)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Median line\u003C/td>\u003Ctd>Middle value (50th percentile)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Whiskers\u003C/td>\u003Ctd>Extend to 1.5×IQR from box\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Outliers\u003C/td>\u003Ctd>Points beyond whiskers\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"anova-statistics\">ANOVA Statistics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#anova-statistics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ANOVA Statistics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When comparing factors, VariScout calculates:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Statistic\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>F-statistic\u003C/td>\u003Ctd>Ratio of between/within variance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>p-value\u003C/td>\u003Ctd>Probability of chance difference\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>η² (eta-squared)\u003C/td>\u003Ctd>Proportion of variance explained\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"variation-decomposition.md\">Variation Decomposition\u003C/a> for how η² relates to the category-level Total SS metrics shown in the Mindmap and contribution labels.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interpretation\">Interpretation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interpretation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpretation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Non-overlapping boxes\u003C/td>\u003Ctd>Significant difference\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>High η²\u003C/td>\u003Ctd>Factor explains much variation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Wide box\u003C/td>\u003Ctd>High variation within group\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Many outliers\u003C/td>\u003Ctd>Check data quality or subgroups\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"violin-mode-distribution-shape\">Violin Mode (Distribution Shape)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#violin-mode-distribution-shape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Violin Mode (Distribution Shape)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Toggle \u003Cstrong>Show distribution shape\u003C/strong> in Settings to switch to violin-primary rendering (industry standard, matching Seaborn/Plotly/ggplot2). This uses Kernel Density Estimation (KDE) with a Gaussian kernel and Silverman’s rule-of-thumb bandwidth.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>What the violin reveals\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Single peak\u003C/td>\u003Ctd>Unimodal process, well-centered\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Two peaks\u003C/td>\u003Ctd>Bimodal distribution — likely two process conditions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Skewed shape\u003C/td>\u003Ctd>Asymmetric process — investigate cause\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Wide/narrow shape\u003C/td>\u003Ctd>Variation magnitude at a glance\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>When enabled, the density curve becomes the dominant shape with a thin IQR box inside showing Q1-Q3 range, median line, and mean diamond. Whiskers and outliers are hidden since the density curve conveys the full distribution shape.\u003C/p>\n\u003Cp>Available in PWA and Azure App.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"category-sorting\">Category Sorting\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#category-sorting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Category Sorting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Sort boxplot categories by \u003Cstrong>Name\u003C/strong> (alphabetical, default), \u003Cstrong>Mean\u003C/strong>, or \u003Cstrong>Spread\u003C/strong> (IQR). Toggle ascending/descending direction.\u003C/p>\n\u003Cp>Access via the display options icon (SlidersHorizontal) in the Boxplot card header — the same popover that controls Violin Mode and Contribution Labels.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Sort Criterion\u003C/th>\u003Cth>What it reveals\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Name (default)\u003C/td>\u003Ctd>Alphabetical order — stable reference view\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mean\u003C/td>\u003Ctd>Rank categories by center — find highest/lowest performers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Spread\u003C/td>\u003Ctd>Rank by IQR — find most/least consistent categories\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Available in both PWA and Azure App.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"direction-coloring\">Direction Coloring\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#direction-coloring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Direction Coloring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When specification limits are set, boxplot categories are colored by how well their mean aligns with the quality goal. The \u003Ca href=\"characteristic-types.md\">characteristic type\u003C/a> determines what “best” means:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Smaller-is-better\u003C/strong>: lowest mean = green (best), highest mean = red (worst)\u003C/li>\n\u003Cli>\u003Cstrong>Larger-is-better\u003C/strong>: highest mean = green, lowest mean = red\u003C/li>\n\u003Cli>\u003Cstrong>Nominal\u003C/strong>: closest to target = green, furthest = red\u003C/li>\n\u003C/ul>\n\u003Cp>Categories are ranked into thirds (green / amber / red). With 2 categories: best = green, worst = red. With 1 category: neutral gray.\u003C/p>\n\u003Cp>Direction coloring combines with the existing \u003Ca href=\"variation-decomposition.md\">variation contribution\u003C/a> bars: box fill shows quality direction (green/amber/red), contribution bar shows variation impact. Together they highlight categories that are both high-impact and poorly performing.\u003C/p>\n\u003Cp>Manual annotation highlights (right-click) always override auto-colors. When specs are hidden or cleared, boxes revert to neutral gray.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"linked-filtering\">Linked Filtering\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#linked-filtering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Linked Filtering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click any box to:\u003C/p>\n\u003Cul>\n\u003Cli>Filter all charts to that subgroup\u003C/li>\n\u003Cli>See I-Chart for just that factor level\u003C/li>\n\u003Cli>Continue drill-down analysis\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-reference\">Technical Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s implementation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// From @variscout/core\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateAnova, getEtaSquared } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">anova\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateAnova\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Machine\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Weight\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns: { fStatistic, pValue, etaSquared, groups }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">etaSq\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getEtaSquared\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Machine\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Weight\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns: number (0-1)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// From @variscout/coreimport { calculateAnova, getEtaSquared } from '@variscout/core';const anova = calculateAnova(data, 'Machine', 'Weight');// Returns: { fStatistic, pValue, etaSquared, groups }const etaSq = getEtaSquared(data, 'Machine', 'Weight');// Returns: number (0-1)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Test coverage:\u003C/strong> See \u003Ccode dir=\"auto\">packages/core/src/__tests__/stats.test.ts\u003C/code> for ANOVA tests.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/flow.md\">FLOW Lens\u003C/a> - Upstream factor concepts\u003C/li>\n\u003Cli>\u003Ca href=\"../navigation/drill-down.md\">Drill-Down\u003C/a> - Multi-level factor exploration\u003C/li>\n\u003Cli>\u003Ca href=\"i-chart.md\">I-Chart\u003C/a> - Previous step: detect instability over time\u003C/li>\n\u003Cli>\u003Ca href=\"pareto.md\">Pareto\u003C/a> - Next step: rank contribution of factors\u003C/li>\n\u003Cli>\u003Ca href=\"regression.md\">Regression\u003C/a> - When to check for interactions\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/charts/boxplot.md\">Chart Design\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md#2-eta-squared\">Glossary: η² (Eta-squared)\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md#f-statistic\">Glossary: F-statistic\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../04-cases/bottleneck/index.md\">Case: Bottleneck\u003C/a> - Factor comparison example\u003C/li>\n\u003C/ul>", + { + "headings": 6337, + "localImagePaths": 6362, + "remoteImagePaths": 6363, + "frontmatter": 6364, + "imagePaths": 6365 + }, + [6338, 6340, 6341, 6344, 6345, 6348, 6351, 6354, 6357, 6360, 6361], + { "depth": 30, "slug": 6339, "text": 6327 }, + "boxplot", + { "depth": 33, "slug": 3911, "text": 3912 }, + { "depth": 33, "slug": 6342, "text": 6343 }, + "key-elements", + "Key Elements", + { "depth": 33, "slug": 531, "text": 532 }, + { "depth": 33, "slug": 6346, "text": 6347 }, + "interpretation", + "Interpretation", + { "depth": 33, "slug": 6349, "text": 6350 }, + "violin-mode-distribution-shape", + "Violin Mode (Distribution Shape)", + { "depth": 33, "slug": 6352, "text": 6353 }, + "category-sorting", + "Category Sorting", + { "depth": 33, "slug": 6355, "text": 6356 }, + "direction-coloring", + "Direction Coloring", + { "depth": 33, "slug": 6358, "text": 6359 }, + "linked-filtering", + "Linked Filtering", + { "depth": 33, "slug": 3956, "text": 3957 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6327 }, + [], + "03-features/analysis/capability", + { "id": 6366, "data": 6368, "body": 6372, "filePath": 6373, "digest": 6374, "rendered": 6375 }, + { + "title": 984, + "editUrl": 16, + "head": 6369, + "template": 18, + "sidebar": 6370, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 6371 }, + {}, + "\u003C!-- journey-phase: scout -->\n\n# Capability Analysis\n\nCapability Analysis is VariScout's tool for the **VALUE** lens - comparing process output to customer specifications.\n\n---\n\n## Purpose\n\n_\"Are we measuring what the customer actually experiences? Do we meet their specs?\"_\n\nCapability reveals:\n\n- Distribution shape (normal, bimodal, skewed)\n- Position relative to specifications (USL/LSL/Target)\n- Cp/Cpk metrics (process capability)\n- Pass/fail percentage\n\n---\n\n## Key Metrics\n\n| Metric | Formula | Interpretation |\n| --------- | ----------------------- | -------------------------------------- |\n| Cp | (USL - LSL) / 6σ_within | Potential capability (spread only) |\n| Cpk | min(CPU, CPL) | Actual capability (spread + centering) |\n| Pass Rate | % within specs | Conformance rate |\n\n### One-Sided Characteristics\n\nFor directional [characteristic types](characteristic-types.md), capability metrics adapt:\n\n- **Smaller-is-better** (USL only): Cp and Cpk use only the upper specification limit\n- **Larger-is-better** (LSL only): Cp and Cpk use only the lower specification limit\n- **Nominal** (USL + LSL): Standard two-sided Cp/Cpk calculation\n\nWhen only one spec limit is set, Cp equals Cpk (there is only one side to measure against). The capability histogram still shows the full distribution but marks only the relevant limit.\n\n---\n\n## Sigma Estimation (σ_within)\n\nVariScout uses **σ_within** (within-subgroup standard deviation) for Cp/Cpk and I-Chart control limits, not the overall standard deviation. This is the industry standard approach used by Minitab, JMP, and other SPC software.\n\n### How σ_within is estimated\n\nσ_within is estimated from the **moving range** of consecutive observations:\n\n```\nσ_within = MR̄ / d2\n```\n\nWhere:\n\n- **MR̄** = mean of absolute differences between consecutive points: mean(|x*i - x*{i-1}|)\n- **d2** = 1.128 (unbiasing constant for span of 2)\n\n### Why subgroup size = 1 (individuals)\n\nVariScout always uses subgroup size n=1 because data arrives as individual measurements (flat rows), not rational subgroups. This means:\n\n- Chart type is always **I-MR** (Individuals and Moving Range)\n- The moving range span is 2 (consecutive pairs), giving d2 = 1.128\n- No subgroup size selector is needed (unlike Minitab, which supports X̄-R charts with larger subgroups)\n\n**Reference — Minitab d2 constants by subgroup size:**\n\n| n | d2 | Chart type |\n| --------------- | ----- | ---------- |\n| 1 (individuals) | 1.128 | I-MR |\n| 2 | 1.128 | X̄-R |\n| 3 | 1.693 | X̄-R |\n| 4 | 2.059 | X̄-R |\n| 5 | 2.326 | X̄-R |\n\n### Data order matters\n\nThe moving range assumes data is in **time or production order**. If rows are shuffled or sorted by value, MR̄ will be inflated and σ_within will overestimate true short-term variation.\n\n### σ_within vs σ_overall\n\n| | σ_within (MR̄/d2) | σ_overall (sample std dev) |\n| -------------------- | --------------------------------- | -------------------------------- |\n| **Used for** | Cp, Cpk, control limits (UCL/LCL) | Pp, Ppk (not currently computed) |\n| **Captures** | Short-term, inherent variation | All variation including shifts |\n| **Sensitive to** | Consecutive-point differences | All data points equally |\n| **When they differ** | Process has shifts or trends | — |\n\nVariScout computes Cp/Cpk only (using σ_within). Pp/Ppk (using σ_overall) are not currently reported.\n\n---\n\n## Prerequisites\n\nCapability metrics require specification limits to be meaningful:\n\n| Metric | Requirements |\n| --------- | ------------------------------ |\n| Pass Rate | At least one spec (USL or LSL) |\n| Cp | Both USL and LSL |\n| Cpk | At least one spec (USL or LSL) |\n\nWhen no specifications are configured, the StatsPanel shows only basic statistics (Mean, Std Dev, Sample count).\n\n---\n\n## Capability Grades\n\n| Cpk | Grade | Interpretation |\n| --------- | --------- | -------------- |\n| ≥1.67 | Excellent | Very capable |\n| 1.33-1.67 | Good | Capable |\n| 1.00-1.33 | Marginal | Barely capable |\n| \u003C1.00 | Poor | Not capable |\n\n---\n\n## Histogram Elements\n\n| Element | Description |\n| ------------ | ---------------------- |\n| Bars | Frequency distribution |\n| USL line | Upper specification |\n| LSL line | Lower specification |\n| Target line | Ideal value |\n| Normal curve | Fitted distribution |\n\n---\n\n## Interpretation\n\n| Pattern | Meaning |\n| -------------------------- | --------------- |\n| Distribution within specs | Capable process |\n| Distribution exceeds specs | Not capable |\n| Centered on target | Well-centered |\n| Shifted toward one spec | Centering issue |\n| Bimodal | Mixed streams |\n\n---\n\n---\n\n## Technical Reference\n\nVariScout's implementation:\n\n```typescript\n// From @variscout/core\nimport { calculateStats } from '@variscout/core';\n\nconst stats = calculateStats(values, usl, lsl);\n// Returns: { mean, stdDev, sigmaWithin, mrBar, ucl, lcl, cp, cpk, outOfSpecPercentage, ... }\n\n// σ_within = MR̄ / d2 (d2 = 1.128 for individuals chart)\n// Cp = (USL - LSL) / (6 * sigmaWithin)\n// Cpk = min((USL - mean) / (3 * sigmaWithin), (mean - LSL) / (3 * sigmaWithin))\n// UCL = mean + 3 * sigmaWithin\n// LCL = mean - 3 * sigmaWithin\n```\n\n**Test coverage:** See `packages/core/src/__tests__/stats.test.ts` for capability tests.\n\n---\n\n## See Also\n\n- [VALUE Lens](../../01-vision/four-lenses/value.md) - Customer value concepts\n- [Two Voices](../../01-vision/two-voices/index.md) - Control limits vs specs\n- [Probability Plot](probability-plot.md) - Check normality assumption\n- [Performance Mode](performance-mode.md) - Multi-channel capability comparison\n- [Staged Analysis](staged-analysis.md) - Before/after capability comparison\n- [Glossary: Cp/Cpk](../../glossary.md#cp)\n- [Chart Design](../../06-design-system/charts/capability.md)\n- [Case: Packaging](../../04-cases/packaging/index.md) - Capability assessment example", + "src/content/docs/03-features/analysis/capability.md", + "d16ef50c19c4b0a7", + { "html": 6376, "metadata": 6377 }, + "\u003C!-- journey-phase: scout -->\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"capability-analysis\">Capability Analysis\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#capability-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Capability Analysis is VariScout’s tool for the \u003Cstrong>VALUE\u003C/strong> lens - comparing process output to customer specifications.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Are we measuring what the customer actually experiences? Do we meet their specs?”\u003C/em>\u003C/p>\n\u003Cp>Capability reveals:\u003C/p>\n\u003Cul>\n\u003Cli>Distribution shape (normal, bimodal, skewed)\u003C/li>\n\u003Cli>Position relative to specifications (USL/LSL/Target)\u003C/li>\n\u003Cli>Cp/Cpk metrics (process capability)\u003C/li>\n\u003Cli>Pass/fail percentage\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-metrics\">Key Metrics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Formula\u003C/th>\u003Cth>Interpretation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Cp\u003C/td>\u003Ctd>(USL - LSL) / 6σ_within\u003C/td>\u003Ctd>Potential capability (spread only)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cpk\u003C/td>\u003Ctd>min(CPU, CPL)\u003C/td>\u003Ctd>Actual capability (spread + centering)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pass Rate\u003C/td>\u003Ctd>% within specs\u003C/td>\u003Ctd>Conformance rate\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"one-sided-characteristics\">One-Sided Characteristics\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#one-sided-characteristics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “One-Sided Characteristics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For directional \u003Ca href=\"characteristic-types.md\">characteristic types\u003C/a>, capability metrics adapt:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Smaller-is-better\u003C/strong> (USL only): Cp and Cpk use only the upper specification limit\u003C/li>\n\u003Cli>\u003Cstrong>Larger-is-better\u003C/strong> (LSL only): Cp and Cpk use only the lower specification limit\u003C/li>\n\u003Cli>\u003Cstrong>Nominal\u003C/strong> (USL + LSL): Standard two-sided Cp/Cpk calculation\u003C/li>\n\u003C/ul>\n\u003Cp>When only one spec limit is set, Cp equals Cpk (there is only one side to measure against). The capability histogram still shows the full distribution but marks only the relevant limit.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sigma-estimation-σ_within\">Sigma Estimation (σ_within)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sigma-estimation-σ_within\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sigma Estimation (σ_within)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses \u003Cstrong>σ_within\u003C/strong> (within-subgroup standard deviation) for Cp/Cpk and I-Chart control limits, not the overall standard deviation. This is the industry standard approach used by Minitab, JMP, and other SPC software.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"how-σ_within-is-estimated\">How σ_within is estimated\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#how-σ_within-is-estimated\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How σ_within is estimated”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>σ_within is estimated from the \u003Cstrong>moving range\u003C/strong> of consecutive observations:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">σ_within = MR̄ / d2\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"σ_within = MR̄ / d2\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Where:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>MR̄\u003C/strong> = mean of absolute differences between consecutive points: mean(|x\u003Cem>i - x\u003C/em>{i-1}|)\u003C/li>\n\u003Cli>\u003Cstrong>d2\u003C/strong> = 1.128 (unbiasing constant for span of 2)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-subgroup-size--1-individuals\">Why subgroup size = 1 (individuals)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-subgroup-size--1-individuals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why subgroup size = 1 (individuals)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout always uses subgroup size n=1 because data arrives as individual measurements (flat rows), not rational subgroups. This means:\u003C/p>\n\u003Cul>\n\u003Cli>Chart type is always \u003Cstrong>I-MR\u003C/strong> (Individuals and Moving Range)\u003C/li>\n\u003Cli>The moving range span is 2 (consecutive pairs), giving d2 = 1.128\u003C/li>\n\u003Cli>No subgroup size selector is needed (unlike Minitab, which supports X̄-R charts with larger subgroups)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Reference — Minitab d2 constants by subgroup size:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>n\u003C/th>\u003Cth>d2\u003C/th>\u003Cth>Chart type\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1 (individuals)\u003C/td>\u003Ctd>1.128\u003C/td>\u003Ctd>I-MR\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>1.128\u003C/td>\u003Ctd>X̄-R\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>1.693\u003C/td>\u003Ctd>X̄-R\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>2.059\u003C/td>\u003Ctd>X̄-R\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>2.326\u003C/td>\u003Ctd>X̄-R\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-order-matters\">Data order matters\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-order-matters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data order matters”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The moving range assumes data is in \u003Cstrong>time or production order\u003C/strong>. If rows are shuffled or sorted by value, MR̄ will be inflated and σ_within will overestimate true short-term variation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"σ_within-vs-σ_overall\">σ_within vs σ_overall\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#σ_within-vs-σ_overall\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “σ_within vs σ_overall”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>\u003C/th>\u003Cth>σ_within (MR̄/d2)\u003C/th>\u003Cth>σ_overall (sample std dev)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Used for\u003C/strong>\u003C/td>\u003Ctd>Cp, Cpk, control limits (UCL/LCL)\u003C/td>\u003Ctd>Pp, Ppk (not currently computed)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Captures\u003C/strong>\u003C/td>\u003Ctd>Short-term, inherent variation\u003C/td>\u003Ctd>All variation including shifts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Sensitive to\u003C/strong>\u003C/td>\u003Ctd>Consecutive-point differences\u003C/td>\u003Ctd>All data points equally\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>When they differ\u003C/strong>\u003C/td>\u003Ctd>Process has shifts or trends\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>VariScout computes Cp/Cpk only (using σ_within). Pp/Ppk (using σ_overall) are not currently reported.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"prerequisites\">Prerequisites\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#prerequisites\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Prerequisites”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Capability metrics require specification limits to be meaningful:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Requirements\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Pass Rate\u003C/td>\u003Ctd>At least one spec (USL or LSL)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cp\u003C/td>\u003Ctd>Both USL and LSL\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cpk\u003C/td>\u003Ctd>At least one spec (USL or LSL)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>When no specifications are configured, the StatsPanel shows only basic statistics (Mean, Std Dev, Sample count).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"capability-grades\">Capability Grades\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#capability-grades\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability Grades”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Cpk\u003C/th>\u003Cth>Grade\u003C/th>\u003Cth>Interpretation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>≥1.67\u003C/td>\u003Ctd>Excellent\u003C/td>\u003Ctd>Very capable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.33-1.67\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Capable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.00-1.33\u003C/td>\u003Ctd>Marginal\u003C/td>\u003Ctd>Barely capable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd><1.00\u003C/td>\u003Ctd>Poor\u003C/td>\u003Ctd>Not capable\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"histogram-elements\">Histogram Elements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#histogram-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Histogram Elements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Bars\u003C/td>\u003Ctd>Frequency distribution\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>USL line\u003C/td>\u003Ctd>Upper specification\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LSL line\u003C/td>\u003Ctd>Lower specification\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Target line\u003C/td>\u003Ctd>Ideal value\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Normal curve\u003C/td>\u003Ctd>Fitted distribution\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interpretation\">Interpretation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interpretation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpretation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Distribution within specs\u003C/td>\u003Ctd>Capable process\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Distribution exceeds specs\u003C/td>\u003Ctd>Not capable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Centered on target\u003C/td>\u003Ctd>Well-centered\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shifted toward one spec\u003C/td>\u003Ctd>Centering issue\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Bimodal\u003C/td>\u003Ctd>Mixed streams\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-reference\">Technical Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s implementation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// From @variscout/core\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateStats } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateStats\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(values\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">usl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">lsl);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns: { mean, stdDev, sigmaWithin, mrBar, ucl, lcl, cp, cpk, outOfSpecPercentage, ... }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// σ_within = MR̄ / d2 (d2 = 1.128 for individuals chart)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Cp = (USL - LSL) / (6 * sigmaWithin)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Cpk = min((USL - mean) / (3 * sigmaWithin), (mean - LSL) / (3 * sigmaWithin))\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// UCL = mean + 3 * sigmaWithin\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// LCL = mean - 3 * sigmaWithin\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// From @variscout/coreimport { calculateStats } from '@variscout/core';const stats = calculateStats(values, usl, lsl);// Returns: { mean, stdDev, sigmaWithin, mrBar, ucl, lcl, cp, cpk, outOfSpecPercentage, ... }// σ_within = MR̄ / d2 (d2 = 1.128 for individuals chart)// Cp = (USL - LSL) / (6 * sigmaWithin)// Cpk = min((USL - mean) / (3 * sigmaWithin), (mean - LSL) / (3 * sigmaWithin))// UCL = mean + 3 * sigmaWithin// LCL = mean - 3 * sigmaWithin\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Test coverage:\u003C/strong> See \u003Ccode dir=\"auto\">packages/core/src/__tests__/stats.test.ts\u003C/code> for capability tests.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/value.md\">VALUE Lens\u003C/a> - Customer value concepts\u003C/li>\n\u003Cli>\u003Ca href=\"../../01-vision/two-voices/index.md\">Two Voices\u003C/a> - Control limits vs specs\u003C/li>\n\u003Cli>\u003Ca href=\"probability-plot.md\">Probability Plot\u003C/a> - Check normality assumption\u003C/li>\n\u003Cli>\u003Ca href=\"performance-mode.md\">Performance Mode\u003C/a> - Multi-channel capability comparison\u003C/li>\n\u003Cli>\u003Ca href=\"staged-analysis.md\">Staged Analysis\u003C/a> - Before/after capability comparison\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md#cp\">Glossary: Cp/Cpk\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/charts/capability.md\">Chart Design\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../04-cases/packaging/index.md\">Case: Packaging\u003C/a> - Capability assessment example\u003C/li>\n\u003C/ul>", + { + "headings": 6378, + "localImagePaths": 6412, + "remoteImagePaths": 6413, + "frontmatter": 6414, + "imagePaths": 6415 + }, + [6379, 6380, 6381, 6382, 6385, 6388, 6391, 6394, 6397, 6400, 6403, 6406, 6409, 6410, 6411], + { "depth": 30, "slug": 983, "text": 984 }, + { "depth": 33, "slug": 3911, "text": 3912 }, + { "depth": 33, "slug": 3914, "text": 3915 }, + { "depth": 79, "slug": 6383, "text": 6384 }, + "one-sided-characteristics", + "One-Sided Characteristics", + { "depth": 33, "slug": 6386, "text": 6387 }, + "sigma-estimation-σ_within", + "Sigma Estimation (σ_within)", + { "depth": 79, "slug": 6389, "text": 6390 }, + "how-σ_within-is-estimated", + "How σ_within is estimated", + { "depth": 79, "slug": 6392, "text": 6393 }, + "why-subgroup-size--1-individuals", + "Why subgroup size = 1 (individuals)", + { "depth": 79, "slug": 6395, "text": 6396 }, + "data-order-matters", + "Data order matters", + { "depth": 79, "slug": 6398, "text": 6399 }, + "σ_within-vs-σ_overall", + "σ_within vs σ_overall", + { "depth": 33, "slug": 6401, "text": 6402 }, + "prerequisites", + "Prerequisites", + { "depth": 33, "slug": 6404, "text": 6405 }, + "capability-grades", + "Capability Grades", + { "depth": 33, "slug": 6407, "text": 6408 }, + "histogram-elements", + "Histogram Elements", + { "depth": 33, "slug": 6346, "text": 6347 }, + { "depth": 33, "slug": 3956, "text": 3957 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 984 }, + [], + "03-features/analysis/characteristic-types", + { "id": 6416, "data": 6418, "body": 6423, "filePath": 6424, "digest": 6425, "rendered": 6426 }, + { + "title": 6419, + "editUrl": 16, + "head": 6420, + "template": 18, + "sidebar": 6421, + "pagefind": 16, + "draft": 20 + }, + "Characteristic Type Awareness", + [], + { "hidden": 20, "attrs": 6422 }, + {}, + "# Characteristic Type Awareness\n\nQuality characteristics come in three types. VariScout detects the type from specification limits and uses it to provide direction-aware analysis throughout the tool.\n\n---\n\n## The Three Types\n\n| Type | Goal | Example | Spec Pattern |\n| --------------------- | ------------------------ | ----------------------------------- | ------------ |\n| **Nominal-is-best** | Hit the target | Fill weight, dimensions, pH | USL + LSL |\n| **Smaller-is-better** | Lower values are better | Defect count, cycle time, shrinkage | USL only |\n| **Larger-is-better** | Higher values are better | Yield, strength, uptime | LSL only |\n\nFor nominal characteristics, both over and under are bad. For directional characteristics (smaller/larger), deviation in one direction is harmful while deviation in the other is favorable or at least not a defect.\n\n---\n\n## How the Type is Determined\n\n### Auto-inference from Specification Limits\n\nWhen no explicit type is set, VariScout infers it from the limits provided:\n\n| Limits Set | Inferred Type | Rationale |\n| ---------- | ------------- | ----------------------------------- |\n| USL + LSL | Nominal | Both limits = target-centered |\n| USL only | Smaller | Upper limit only = lower is better |\n| LSL only | Larger | Lower limit only = higher is better |\n\nThis covers the majority of real-world cases. A fill weight with both an upper and lower limit is nominal. A cycle time with only an upper limit is smaller-is-better.\n\n### Manual Override\n\nThree icon buttons appear below the Target field in both the SpecEditor popover and the ColumnMapping setup screen:\n\n| Icon | Type | Meaning |\n| ---------------- | ----------------- | ---------------- |\n| ↕ (MoveVertical) | Nominal | Target-centered |\n| ↓ (ArrowDown) | Smaller is better | Lower is better |\n| ↑ (ArrowUp) | Larger is better | Higher is better |\n\n**Button states:**\n\n- **No icon selected** (default) = auto-inference from limits. The inferred icon gets a dotted blue outline. A \"detected: nominal\" hint appears below when limits are set.\n- **Icon selected** (clicked) = explicit override. Solid blue fill. Click the active icon again to reset back to auto.\n\nManual override is necessary when auto-inference is wrong. For example, a yield metric with both USL and LSL would auto-infer as nominal, but if the LSL is a minimum acceptance threshold and higher yield is always better, the analyst should override to \"Larger.\"\n\nThe override is persisted with the spec limits and saved in .vrs project files. When reset to auto (no icon selected), the type re-infers if the analyst later changes the limits.\n\n---\n\n## I-Chart Interpretation\n\nThe I-Chart uses characteristic type to distinguish between harmful and favorable special causes.\n\n### Violation Color Map\n\n| Violation | Nominal | Smaller-is-better | Larger-is-better |\n| ------------------- | --------------- | ----------------- | ----------------- |\n| Above USL (spec) | Orange (defect) | Orange (defect) | -- |\n| Below LSL (spec) | Orange (defect) | -- | Orange (defect) |\n| Above UCL (control) | Red (harmful) | Red (harmful) | Green (favorable) |\n| Below LCL (control) | Red (harmful) | Green (favorable) | Red (harmful) |\n| Nelson Rule 2 | Red (pattern) | Red (pattern) | Red (pattern) |\n\n**Spec violations** are always orange regardless of direction -- any out-of-spec point is a defect.\n\n**Control violations** gain directional awareness:\n\n- **Green dots** = favorable signal -- investigate to _replicate_ (what went right?)\n- **Red dots** = harmful signal -- investigate to _fix_ (what went wrong?)\n\nTooltips show a \"-- favorable signal\" suffix for beneficial special causes, guiding the analyst toward the correct investigation action.\n\n### Why This Matters\n\nWithout direction awareness, an analyst seeing a point below LCL on a cycle time chart (smaller-is-better) would investigate it as a problem. In reality, that point represents unexpectedly fast performance -- something to understand and replicate, not fix. This is one of the most common mistakes in SPC practice.\n\n---\n\n## Boxplot Direction Coloring\n\nWhen specs are set, boxplot categories are colored by how well their mean aligns with the quality goal:\n\n| Characteristic Type | Best (Green) | Worst (Red) |\n| ------------------- | ----------------- | -------------------- |\n| Smaller | Lowest mean | Highest mean |\n| Larger | Highest mean | Lowest mean |\n| Nominal | Closest to target | Furthest from target |\n\nCategories are ranked into thirds:\n\n- **Top third** = green (best performers)\n- **Middle third** = amber (average)\n- **Bottom third** = red (worst performers)\n\nWith 2 categories: best = green, worst = red. With 1 category: neutral gray (no comparison possible).\n\n### Combined with Variation Contribution\n\nDirection coloring complements the existing variation contribution system:\n\n- **Box fill color** -- direction quality (green/amber/red)\n- **Contribution bar** -- variation impact (proportional width)\n- Together: \"Machine A causes 45% of variation AND is performing badly (red)\"\n\nThis dual encoding lets the analyst quickly identify categories that are both high-impact and poorly performing -- the highest-priority improvement targets.\n\n### Override Behavior\n\n- Manual annotation highlights (right-click) always override auto-colors\n- When specs are hidden (display option) or cleared, boxes revert to neutral gray\n- Direction coloring requires at least one spec limit to be set\n\n---\n\n## What-If Smart Presets\n\nThe What-If Simulator auto-computes up to 6 presets based on current stats and characteristic type. These are one-click shortcuts that set slider values; users can still adjust manually afterward.\n\n| # | Preset | Requires | Logic |\n| --- | --------------- | -------------------------- | ------------------------------------ |\n| 1 | Shift to target | Specs with target/midpoint | Mean shift to target |\n| 2 | Shift to median | Skewed distribution | Mean shift to median (corrects skew) |\n| 3 | Match best | Active factor | Direction-aware best category mean |\n| 4 | Tighten spread | Active factor | Match tightest category's std dev |\n| 5 | Reach 95% yield | Specs, yield \u003C 95% | Reverse-calc shift/reduction for 95% |\n| 6 | Best of both | Active factor | Combine #3 + #4 |\n\n### Direction Awareness in Presets\n\nPreset 3 (\"Match best\") uses the characteristic type to determine which category is \"best\":\n\n- **Smaller-is-better**: category with the lowest mean\n- **Larger-is-better**: category with the highest mean\n- **Nominal**: category with mean closest to target\n\nThis ensures the preset shifts toward the correct direction. Without type awareness, the preset would default to the category closest to target (nominal behavior), which is wrong for directional characteristics.\n\n---\n\n## Relationship to Two Voices\n\nThis feature extends the [Two Voices](../../01-vision/two-voices/index.md) model (Voice of the Customer vs Voice of the Process):\n\n- **Spec violations** (Voice of the Customer, orange) remain direction-neutral -- any out-of-spec point is a defect regardless of which side it falls on\n- **Control violations** (Voice of the Process, red/green) gain directional awareness -- a special cause that moves the process toward the quality goal is favorable, not a problem\n\nThe Two Voices distinction is preserved: specs define customer requirements, control limits define process behavior. Characteristic type adds a third dimension -- _which direction is good_ -- that refines how control violations are interpreted.\n\n---\n\n## Technical Reference\n\n### Types and Functions\n\n```typescript\n// Type definition\ntype CharacteristicType = 'nominal' | 'smaller' | 'larger';\n\n// Auto-inference from spec limits\nimport { inferCharacteristicType } from '@variscout/core';\nconst type = inferCharacteristicType(specs);\n// { usl: 10, lsl: 5 } → 'nominal'\n// { usl: 10 } → 'smaller'\n// { lsl: 5 } → 'larger'\n\n// Direction-aware category coloring for boxplot\nimport { computeCategoryDirectionColors } from '@variscout/core';\nconst colors = computeCategoryDirectionColors(data, specs);\n// Returns per-category color assignment: 'green' | 'amber' | 'red' | 'neutral'\n```\n\n### Persistence\n\n- `SpecLimits.characteristicType` -- optional field (`CharacteristicType | undefined`)\n- When `undefined`, auto-inference is used (backward compatible with existing .vrs files)\n- When set to a specific type, the override is persisted and restored on load\n\n---\n\n## See Also\n\n- [Capability Analysis](capability.md) - Cp/Cpk metrics that depend on spec limits\n- [I-Chart](i-chart.md) - Where violation colors are displayed\n- [Two Voices](../../01-vision/two-voices/index.md) - Control limits vs specification limits\n- [What-If Simulator](../../06-design-system/components/what-if-simulator.md) - Smart presets and simulation\n- [Variation Decomposition](variation-decomposition.md) - Category contribution system\n- [Nelson Rules](nelson-rules.md) - Pattern detection on I-Chart\n- [Boxplot](boxplot.md) - Category comparison with direction coloring", + "src/content/docs/03-features/analysis/characteristic-types.md", + "938814ef1b7e49e6", + { "html": 6427, "metadata": 6428 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"characteristic-type-awareness\">Characteristic Type Awareness\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#characteristic-type-awareness\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Characteristic Type Awareness”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Quality characteristics come in three types. VariScout detects the type from specification limits and uses it to provide direction-aware analysis throughout the tool.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-three-types\">The Three Types\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-three-types\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Three Types”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Goal\u003C/th>\u003Cth>Example\u003C/th>\u003Cth>Spec Pattern\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Nominal-is-best\u003C/strong>\u003C/td>\u003Ctd>Hit the target\u003C/td>\u003Ctd>Fill weight, dimensions, pH\u003C/td>\u003Ctd>USL + LSL\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Smaller-is-better\u003C/strong>\u003C/td>\u003Ctd>Lower values are better\u003C/td>\u003Ctd>Defect count, cycle time, shrinkage\u003C/td>\u003Ctd>USL only\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Larger-is-better\u003C/strong>\u003C/td>\u003Ctd>Higher values are better\u003C/td>\u003Ctd>Yield, strength, uptime\u003C/td>\u003Ctd>LSL only\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>For nominal characteristics, both over and under are bad. For directional characteristics (smaller/larger), deviation in one direction is harmful while deviation in the other is favorable or at least not a defect.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-the-type-is-determined\">How the Type is Determined\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-the-type-is-determined\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How the Type is Determined”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"auto-inference-from-specification-limits\">Auto-inference from Specification Limits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#auto-inference-from-specification-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Auto-inference from Specification Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When no explicit type is set, VariScout infers it from the limits provided:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Limits Set\u003C/th>\u003Cth>Inferred Type\u003C/th>\u003Cth>Rationale\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>USL + LSL\u003C/td>\u003Ctd>Nominal\u003C/td>\u003Ctd>Both limits = target-centered\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>USL only\u003C/td>\u003Ctd>Smaller\u003C/td>\u003Ctd>Upper limit only = lower is better\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LSL only\u003C/td>\u003Ctd>Larger\u003C/td>\u003Ctd>Lower limit only = higher is better\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>This covers the majority of real-world cases. A fill weight with both an upper and lower limit is nominal. A cycle time with only an upper limit is smaller-is-better.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"manual-override\">Manual Override\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#manual-override\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Manual Override”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Three icon buttons appear below the Target field in both the SpecEditor popover and the ColumnMapping setup screen:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Icon\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>↕ (MoveVertical)\u003C/td>\u003Ctd>Nominal\u003C/td>\u003Ctd>Target-centered\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>↓ (ArrowDown)\u003C/td>\u003Ctd>Smaller is better\u003C/td>\u003Ctd>Lower is better\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>↑ (ArrowUp)\u003C/td>\u003Ctd>Larger is better\u003C/td>\u003Ctd>Higher is better\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Button states:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>No icon selected\u003C/strong> (default) = auto-inference from limits. The inferred icon gets a dotted blue outline. A “detected: nominal” hint appears below when limits are set.\u003C/li>\n\u003Cli>\u003Cstrong>Icon selected\u003C/strong> (clicked) = explicit override. Solid blue fill. Click the active icon again to reset back to auto.\u003C/li>\n\u003C/ul>\n\u003Cp>Manual override is necessary when auto-inference is wrong. For example, a yield metric with both USL and LSL would auto-infer as nominal, but if the LSL is a minimum acceptance threshold and higher yield is always better, the analyst should override to “Larger.”\u003C/p>\n\u003Cp>The override is persisted with the spec limits and saved in .vrs project files. When reset to auto (no icon selected), the type re-infers if the analyst later changes the limits.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"i-chart-interpretation\">I-Chart Interpretation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#i-chart-interpretation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “I-Chart Interpretation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The I-Chart uses characteristic type to distinguish between harmful and favorable special causes.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"violation-color-map\">Violation Color Map\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#violation-color-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Violation Color Map”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Violation\u003C/th>\u003Cth>Nominal\u003C/th>\u003Cth>Smaller-is-better\u003C/th>\u003Cth>Larger-is-better\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Above USL (spec)\u003C/td>\u003Ctd>Orange (defect)\u003C/td>\u003Ctd>Orange (defect)\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Below LSL (spec)\u003C/td>\u003Ctd>Orange (defect)\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Orange (defect)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Above UCL (control)\u003C/td>\u003Ctd>Red (harmful)\u003C/td>\u003Ctd>Red (harmful)\u003C/td>\u003Ctd>Green (favorable)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Below LCL (control)\u003C/td>\u003Ctd>Red (harmful)\u003C/td>\u003Ctd>Green (favorable)\u003C/td>\u003Ctd>Red (harmful)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Nelson Rule 2\u003C/td>\u003Ctd>Red (pattern)\u003C/td>\u003Ctd>Red (pattern)\u003C/td>\u003Ctd>Red (pattern)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Spec violations\u003C/strong> are always orange regardless of direction — any out-of-spec point is a defect.\u003C/p>\n\u003Cp>\u003Cstrong>Control violations\u003C/strong> gain directional awareness:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Green dots\u003C/strong> = favorable signal — investigate to \u003Cem>replicate\u003C/em> (what went right?)\u003C/li>\n\u003Cli>\u003Cstrong>Red dots\u003C/strong> = harmful signal — investigate to \u003Cem>fix\u003C/em> (what went wrong?)\u003C/li>\n\u003C/ul>\n\u003Cp>Tooltips show a ”— favorable signal” suffix for beneficial special causes, guiding the analyst toward the correct investigation action.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-this-matters\">Why This Matters\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-this-matters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why This Matters”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Without direction awareness, an analyst seeing a point below LCL on a cycle time chart (smaller-is-better) would investigate it as a problem. In reality, that point represents unexpectedly fast performance — something to understand and replicate, not fix. This is one of the most common mistakes in SPC practice.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"boxplot-direction-coloring\">Boxplot Direction Coloring\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#boxplot-direction-coloring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Boxplot Direction Coloring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When specs are set, boxplot categories are colored by how well their mean aligns with the quality goal:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Characteristic Type\u003C/th>\u003Cth>Best (Green)\u003C/th>\u003Cth>Worst (Red)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Smaller\u003C/td>\u003Ctd>Lowest mean\u003C/td>\u003Ctd>Highest mean\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Larger\u003C/td>\u003Ctd>Highest mean\u003C/td>\u003Ctd>Lowest mean\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Nominal\u003C/td>\u003Ctd>Closest to target\u003C/td>\u003Ctd>Furthest from target\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Categories are ranked into thirds:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Top third\u003C/strong> = green (best performers)\u003C/li>\n\u003Cli>\u003Cstrong>Middle third\u003C/strong> = amber (average)\u003C/li>\n\u003Cli>\u003Cstrong>Bottom third\u003C/strong> = red (worst performers)\u003C/li>\n\u003C/ul>\n\u003Cp>With 2 categories: best = green, worst = red. With 1 category: neutral gray (no comparison possible).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"combined-with-variation-contribution\">Combined with Variation Contribution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#combined-with-variation-contribution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Combined with Variation Contribution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Direction coloring complements the existing variation contribution system:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Box fill color\u003C/strong> — direction quality (green/amber/red)\u003C/li>\n\u003Cli>\u003Cstrong>Contribution bar\u003C/strong> — variation impact (proportional width)\u003C/li>\n\u003Cli>Together: “Machine A causes 45% of variation AND is performing badly (red)”\u003C/li>\n\u003C/ul>\n\u003Cp>This dual encoding lets the analyst quickly identify categories that are both high-impact and poorly performing — the highest-priority improvement targets.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"override-behavior\">Override Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#override-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Override Behavior”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Manual annotation highlights (right-click) always override auto-colors\u003C/li>\n\u003Cli>When specs are hidden (display option) or cleared, boxes revert to neutral gray\u003C/li>\n\u003Cli>Direction coloring requires at least one spec limit to be set\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-if-smart-presets\">What-If Smart Presets\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-if-smart-presets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What-If Smart Presets”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The What-If Simulator auto-computes up to 6 presets based on current stats and characteristic type. These are one-click shortcuts that set slider values; users can still adjust manually afterward.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Preset\u003C/th>\u003Cth>Requires\u003C/th>\u003Cth>Logic\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Shift to target\u003C/td>\u003Ctd>Specs with target/midpoint\u003C/td>\u003Ctd>Mean shift to target\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Shift to median\u003C/td>\u003Ctd>Skewed distribution\u003C/td>\u003Ctd>Mean shift to median (corrects skew)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Match best\u003C/td>\u003Ctd>Active factor\u003C/td>\u003Ctd>Direction-aware best category mean\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Tighten spread\u003C/td>\u003Ctd>Active factor\u003C/td>\u003Ctd>Match tightest category’s std dev\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Reach 95% yield\u003C/td>\u003Ctd>Specs, yield < 95%\u003C/td>\u003Ctd>Reverse-calc shift/reduction for 95%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Best of both\u003C/td>\u003Ctd>Active factor\u003C/td>\u003Ctd>Combine #3 + #4\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"direction-awareness-in-presets\">Direction Awareness in Presets\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#direction-awareness-in-presets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Direction Awareness in Presets”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Preset 3 (“Match best”) uses the characteristic type to determine which category is “best”:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Smaller-is-better\u003C/strong>: category with the lowest mean\u003C/li>\n\u003Cli>\u003Cstrong>Larger-is-better\u003C/strong>: category with the highest mean\u003C/li>\n\u003Cli>\u003Cstrong>Nominal\u003C/strong>: category with mean closest to target\u003C/li>\n\u003C/ul>\n\u003Cp>This ensures the preset shifts toward the correct direction. Without type awareness, the preset would default to the category closest to target (nominal behavior), which is wrong for directional characteristics.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"relationship-to-two-voices\">Relationship to Two Voices\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#relationship-to-two-voices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Relationship to Two Voices”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This feature extends the \u003Ca href=\"../../01-vision/two-voices/index.md\">Two Voices\u003C/a> model (Voice of the Customer vs Voice of the Process):\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Spec violations\u003C/strong> (Voice of the Customer, orange) remain direction-neutral — any out-of-spec point is a defect regardless of which side it falls on\u003C/li>\n\u003Cli>\u003Cstrong>Control violations\u003C/strong> (Voice of the Process, red/green) gain directional awareness — a special cause that moves the process toward the quality goal is favorable, not a problem\u003C/li>\n\u003C/ul>\n\u003Cp>The Two Voices distinction is preserved: specs define customer requirements, control limits define process behavior. Characteristic type adds a third dimension — \u003Cem>which direction is good\u003C/em> — that refines how control violations are interpreted.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-reference\">Technical Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"types-and-functions\">Types and Functions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#types-and-functions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Types and Functions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Type definition\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> CharacteristicType \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">nominal\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">smaller\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">larger\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Auto-inference from spec limits\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { inferCharacteristicType } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">inferCharacteristicType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(specs);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// { usl: 10, lsl: 5 } → 'nominal'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// { usl: 10 } → 'smaller'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// { lsl: 5 } → 'larger'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Direction-aware category coloring for boxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { computeCategoryDirectionColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">colors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">computeCategoryDirectionColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns per-category color assignment: 'green' | 'amber' | 'red' | 'neutral'\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Type definitiontype CharacteristicType = 'nominal' | 'smaller' | 'larger';// Auto-inference from spec limitsimport { inferCharacteristicType } from '@variscout/core';const type = inferCharacteristicType(specs);// { usl: 10, lsl: 5 } → 'nominal'// { usl: 10 } → 'smaller'// { lsl: 5 } → 'larger'// Direction-aware category coloring for boxplotimport { computeCategoryDirectionColors } from '@variscout/core';const colors = computeCategoryDirectionColors(data, specs);// Returns per-category color assignment: 'green' | 'amber' | 'red' | 'neutral'\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"persistence\">Persistence\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#persistence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persistence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">SpecLimits.characteristicType\u003C/code> — optional field (\u003Ccode dir=\"auto\">CharacteristicType | undefined\u003C/code>)\u003C/li>\n\u003Cli>When \u003Ccode dir=\"auto\">undefined\u003C/code>, auto-inference is used (backward compatible with existing .vrs files)\u003C/li>\n\u003Cli>When set to a specific type, the override is persisted and restored on load\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"capability.md\">Capability Analysis\u003C/a> - Cp/Cpk metrics that depend on spec limits\u003C/li>\n\u003Cli>\u003Ca href=\"i-chart.md\">I-Chart\u003C/a> - Where violation colors are displayed\u003C/li>\n\u003Cli>\u003Ca href=\"../../01-vision/two-voices/index.md\">Two Voices\u003C/a> - Control limits vs specification limits\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/components/what-if-simulator.md\">What-If Simulator\u003C/a> - Smart presets and simulation\u003C/li>\n\u003Cli>\u003Ca href=\"variation-decomposition.md\">Variation Decomposition\u003C/a> - Category contribution system\u003C/li>\n\u003Cli>\u003Ca href=\"nelson-rules.md\">Nelson Rules\u003C/a> - Pattern detection on I-Chart\u003C/li>\n\u003Cli>\u003Ca href=\"boxplot.md\">Boxplot\u003C/a> - Category comparison with direction coloring\u003C/li>\n\u003C/ul>", + { + "headings": 6429, + "localImagePaths": 6475, + "remoteImagePaths": 6476, + "frontmatter": 6477, + "imagePaths": 6478 + }, + [ + 6430, 6432, 6435, 6438, 6441, 6444, 6447, 6450, 6451, 6454, 6457, 6460, 6463, 6466, 6469, 6470, + 6473, 6474 + ], + { "depth": 30, "slug": 6431, "text": 6419 }, + "characteristic-type-awareness", + { "depth": 33, "slug": 6433, "text": 6434 }, + "the-three-types", + "The Three Types", + { "depth": 33, "slug": 6436, "text": 6437 }, + "how-the-type-is-determined", + "How the Type is Determined", + { "depth": 79, "slug": 6439, "text": 6440 }, + "auto-inference-from-specification-limits", + "Auto-inference from Specification Limits", + { "depth": 79, "slug": 6442, "text": 6443 }, + "manual-override", + "Manual Override", + { "depth": 33, "slug": 6445, "text": 6446 }, + "i-chart-interpretation", + "I-Chart Interpretation", + { "depth": 79, "slug": 6448, "text": 6449 }, + "violation-color-map", + "Violation Color Map", + { "depth": 79, "slug": 3782, "text": 3783 }, + { "depth": 33, "slug": 6452, "text": 6453 }, + "boxplot-direction-coloring", + "Boxplot Direction Coloring", + { "depth": 79, "slug": 6455, "text": 6456 }, + "combined-with-variation-contribution", + "Combined with Variation Contribution", + { "depth": 79, "slug": 6458, "text": 6459 }, + "override-behavior", + "Override Behavior", + { "depth": 33, "slug": 6461, "text": 6462 }, + "what-if-smart-presets", + "What-If Smart Presets", + { "depth": 79, "slug": 6464, "text": 6465 }, + "direction-awareness-in-presets", + "Direction Awareness in Presets", + { "depth": 33, "slug": 6467, "text": 6468 }, + "relationship-to-two-voices", + "Relationship to Two Voices", + { "depth": 33, "slug": 3956, "text": 3957 }, + { "depth": 79, "slug": 6471, "text": 6472 }, + "types-and-functions", + "Types and Functions", + { "depth": 79, "slug": 989, "text": 990 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6419 }, + [], + "03-features/analysis/i-chart", + { "id": 6479, "data": 6481, "body": 6486, "filePath": 6487, "digest": 6488, "rendered": 6489 }, + { + "title": 6482, + "editUrl": 16, + "head": 6483, + "template": 18, + "sidebar": 6484, + "pagefind": 16, + "draft": 20 + }, + "I-Chart (Individuals Chart)", + [], + { "hidden": 20, "attrs": 6485 }, + {}, + "\u003C!-- journey-phase: scout -->\n\n# I-Chart (Individuals Chart)\n\nThe I-Chart is VariScout's tool for the **CHANGE** lens - analyzing time-based stability.\n\n---\n\n## Purpose\n\n_\"Is the process stable, or is something degrading/shifting over time?\"_\n\nThe I-Chart reveals:\n\n- Time-based stability or instability\n- Trends, shifts, cycles\n- Points outside control limits (UCL/LCL)\n- Dynamic behavior: wear, degradation, seasonal effects\n\n---\n\n## Key Elements\n\n| Element | Description |\n| ------------- | ----------------------------------------- |\n| Data points | Individual measurements plotted over time |\n| Mean line (x̄) | Process average |\n| UCL | Upper Control Limit (x̄ + 2.66MR̄) |\n| LCL | Lower Control Limit (x̄ - 2.66MR̄) |\n| Spec lines | Optional USL/LSL overlay |\n\n---\n\n## Interpretation\n\n| Pattern | Meaning | Action |\n| ---------------------------- | -------------------- | ----------- |\n| Points within limits, random | Stable process | Maintain |\n| Point above UCL | Special cause (high) | Investigate |\n| Point below LCL | Special cause (low) | Investigate |\n| 7+ points one side | Shift in mean | Investigate |\n| Trending up/down | Drift | Investigate |\n\n---\n\n## Linked Filtering\n\nClick any point to:\n\n- See its factor values (Machine, Shift, Operator)\n- Filter other charts to that subset\n- Build drill-down path\n\n---\n\n## Point Selection & Create Factor\n\nWhen instability patterns don't align with any existing factor, you can create an ad-hoc grouping variable directly from the time series.\n\n### Selecting Points\n\n- **Drag-select (brush)**: Click and drag on the chart to draw a blue selection rectangle. All points inside the rectangle are selected.\n- **Ctrl+click**: Toggle individual points in/out of the selection.\n- **Shift+click**: Add individual points to the current selection.\n- **Esc**: Clear the selection.\n\n### What Happens Next\n\n1. A **Selection Panel** appears showing the count and details of selected points.\n2. Click **\"Create Factor\"** to open the naming modal.\n3. Enter a name for the group (e.g., \"Monday anomalies\", \"Startup batch\").\n4. VariScout creates a new factor column with two levels: your named group and \"Other\".\n5. The new factor is auto-applied as a filter, showing only the selected points.\n\n### When to Use\n\n- Special causes on the I-Chart that no existing factor explains\n- A cluster of points that \"look different\" but don't map to Shift, Operator, or Machine\n- Bridging from the **CHANGE** lens (time-series instability) to the **FLOW** lens (factor-based stratification): select the anomalous points, create a factor, then drill down with Boxplot to quantify the difference\n\n---\n\n## Technical Reference\n\nVariScout's implementation:\n\n```typescript\n// From @variscout/core\nimport { calculateStats, getNelsonRule2ViolationPoints } from '@variscout/core';\n\nconst stats = calculateStats(values, usl, lsl);\n// Returns: { mean, stdDev, ucl, lcl, cp, cpk, outOfSpecPercentage }\n\nconst violations = getNelsonRule2ViolationPoints(values, stats.mean);\n// Returns: Set of indices in violation runs\n```\n\n**Test coverage:** See `packages/core/src/__tests__/stats.test.ts` and `packages/core/src/__tests__/nelson.test.ts`.\n\n---\n\n## Beneficial Signals\n\nWhen a [characteristic type](characteristic-types.md) is set (or auto-inferred from spec limits), control violations gain directional awareness:\n\n- **Favorable special causes** (green dots) — the process moved in the desired direction. Investigate to _replicate_.\n- **Harmful special causes** (red dots) — the process moved away from the goal. Investigate to _fix_.\n\nFor example, a point below LCL on a smaller-is-better chart (e.g. cycle time) is a favorable signal — unexpectedly fast performance worth understanding. Without direction awareness, this would be misidentified as a problem.\n\nSee [Characteristic Type Awareness](characteristic-types.md) for the full violation color map.\n\n---\n\n## See Also\n\n- [CHANGE Lens](../../01-vision/four-lenses/change.md) - Time-based stability concepts\n- [Two Voices](../../01-vision/two-voices/index.md) - Control limits vs specs\n- [Nelson Rules](nelson-rules.md) - Pattern detection (9-point runs)\n- [Staged Analysis](staged-analysis.md) - Per-stage control limits\n- [Boxplot](boxplot.md) - Next step: find which factor explains variation\n- [Chart Design](../../06-design-system/charts/ichart.md)\n- [Glossary: UCL/LCL](../../glossary.md#ucl-upper-control-limit)\n- [Case: Bottleneck](../../04-cases/bottleneck/index.md) - I-Chart in action", + "src/content/docs/03-features/analysis/i-chart.md", + "676514473cd44276", + { "html": 6490, "metadata": 6491 }, + "\u003C!-- journey-phase: scout -->\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"i-chart-individuals-chart\">I-Chart (Individuals Chart)\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#i-chart-individuals-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “I-Chart (Individuals Chart)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The I-Chart is VariScout’s tool for the \u003Cstrong>CHANGE\u003C/strong> lens - analyzing time-based stability.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Is the process stable, or is something degrading/shifting over time?”\u003C/em>\u003C/p>\n\u003Cp>The I-Chart reveals:\u003C/p>\n\u003Cul>\n\u003Cli>Time-based stability or instability\u003C/li>\n\u003Cli>Trends, shifts, cycles\u003C/li>\n\u003Cli>Points outside control limits (UCL/LCL)\u003C/li>\n\u003Cli>Dynamic behavior: wear, degradation, seasonal effects\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-elements\">Key Elements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Elements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Data points\u003C/td>\u003Ctd>Individual measurements plotted over time\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mean line (x̄)\u003C/td>\u003Ctd>Process average\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UCL\u003C/td>\u003Ctd>Upper Control Limit (x̄ + 2.66MR̄)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LCL\u003C/td>\u003Ctd>Lower Control Limit (x̄ - 2.66MR̄)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Spec lines\u003C/td>\u003Ctd>Optional USL/LSL overlay\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interpretation\">Interpretation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interpretation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpretation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>Meaning\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Points within limits, random\u003C/td>\u003Ctd>Stable process\u003C/td>\u003Ctd>Maintain\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Point above UCL\u003C/td>\u003Ctd>Special cause (high)\u003C/td>\u003Ctd>Investigate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Point below LCL\u003C/td>\u003Ctd>Special cause (low)\u003C/td>\u003Ctd>Investigate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7+ points one side\u003C/td>\u003Ctd>Shift in mean\u003C/td>\u003Ctd>Investigate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trending up/down\u003C/td>\u003Ctd>Drift\u003C/td>\u003Ctd>Investigate\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"linked-filtering\">Linked Filtering\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#linked-filtering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Linked Filtering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click any point to:\u003C/p>\n\u003Cul>\n\u003Cli>See its factor values (Machine, Shift, Operator)\u003C/li>\n\u003Cli>Filter other charts to that subset\u003C/li>\n\u003Cli>Build drill-down path\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"point-selection--create-factor\">Point Selection & Create Factor\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#point-selection--create-factor\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Point Selection & Create Factor”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When instability patterns don’t align with any existing factor, you can create an ad-hoc grouping variable directly from the time series.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"selecting-points\">Selecting Points\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#selecting-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Selecting Points”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Drag-select (brush)\u003C/strong>: Click and drag on the chart to draw a blue selection rectangle. All points inside the rectangle are selected.\u003C/li>\n\u003Cli>\u003Cstrong>Ctrl+click\u003C/strong>: Toggle individual points in/out of the selection.\u003C/li>\n\u003Cli>\u003Cstrong>Shift+click\u003C/strong>: Add individual points to the current selection.\u003C/li>\n\u003Cli>\u003Cstrong>Esc\u003C/strong>: Clear the selection.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-happens-next\">What Happens Next\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-happens-next\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Happens Next”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>A \u003Cstrong>Selection Panel\u003C/strong> appears showing the count and details of selected points.\u003C/li>\n\u003Cli>Click \u003Cstrong>“Create Factor”\u003C/strong> to open the naming modal.\u003C/li>\n\u003Cli>Enter a name for the group (e.g., “Monday anomalies”, “Startup batch”).\u003C/li>\n\u003Cli>VariScout creates a new factor column with two levels: your named group and “Other”.\u003C/li>\n\u003Cli>The new factor is auto-applied as a filter, showing only the selected points.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"when-to-use\">When to Use\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-use\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Use”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Special causes on the I-Chart that no existing factor explains\u003C/li>\n\u003Cli>A cluster of points that “look different” but don’t map to Shift, Operator, or Machine\u003C/li>\n\u003Cli>Bridging from the \u003Cstrong>CHANGE\u003C/strong> lens (time-series instability) to the \u003Cstrong>FLOW\u003C/strong> lens (factor-based stratification): select the anomalous points, create a factor, then drill down with Boxplot to quantify the difference\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-reference\">Technical Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s implementation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// From @variscout/core\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateStats, getNelsonRule2ViolationPoints } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateStats\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(values\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">usl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">lsl);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns: { mean, stdDev, ucl, lcl, cp, cpk, outOfSpecPercentage }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">violations\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getNelsonRule2ViolationPoints\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(values\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns: Set of indices in violation runs\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// From @variscout/coreimport { calculateStats, getNelsonRule2ViolationPoints } from '@variscout/core';const stats = calculateStats(values, usl, lsl);// Returns: { mean, stdDev, ucl, lcl, cp, cpk, outOfSpecPercentage }const violations = getNelsonRule2ViolationPoints(values, stats.mean);// Returns: Set of indices in violation runs\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Test coverage:\u003C/strong> See \u003Ccode dir=\"auto\">packages/core/src/__tests__/stats.test.ts\u003C/code> and \u003Ccode dir=\"auto\">packages/core/src/__tests__/nelson.test.ts\u003C/code>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"beneficial-signals\">Beneficial Signals\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#beneficial-signals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Beneficial Signals”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When a \u003Ca href=\"characteristic-types.md\">characteristic type\u003C/a> is set (or auto-inferred from spec limits), control violations gain directional awareness:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Favorable special causes\u003C/strong> (green dots) — the process moved in the desired direction. Investigate to \u003Cem>replicate\u003C/em>.\u003C/li>\n\u003Cli>\u003Cstrong>Harmful special causes\u003C/strong> (red dots) — the process moved away from the goal. Investigate to \u003Cem>fix\u003C/em>.\u003C/li>\n\u003C/ul>\n\u003Cp>For example, a point below LCL on a smaller-is-better chart (e.g. cycle time) is a favorable signal — unexpectedly fast performance worth understanding. Without direction awareness, this would be misidentified as a problem.\u003C/p>\n\u003Cp>See \u003Ca href=\"characteristic-types.md\">Characteristic Type Awareness\u003C/a> for the full violation color map.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/change.md\">CHANGE Lens\u003C/a> - Time-based stability concepts\u003C/li>\n\u003Cli>\u003Ca href=\"../../01-vision/two-voices/index.md\">Two Voices\u003C/a> - Control limits vs specs\u003C/li>\n\u003Cli>\u003Ca href=\"nelson-rules.md\">Nelson Rules\u003C/a> - Pattern detection (9-point runs)\u003C/li>\n\u003Cli>\u003Ca href=\"staged-analysis.md\">Staged Analysis\u003C/a> - Per-stage control limits\u003C/li>\n\u003Cli>\u003Ca href=\"boxplot.md\">Boxplot\u003C/a> - Next step: find which factor explains variation\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/charts/ichart.md\">Chart Design\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md#ucl-upper-control-limit\">Glossary: UCL/LCL\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../04-cases/bottleneck/index.md\">Case: Bottleneck\u003C/a> - I-Chart in action\u003C/li>\n\u003C/ul>", + { + "headings": 6492, + "localImagePaths": 6516, + "remoteImagePaths": 6517, + "frontmatter": 6518, + "imagePaths": 6519 + }, + [6493, 6495, 6496, 6497, 6498, 6499, 6502, 6505, 6508, 6511, 6512, 6515], + { "depth": 30, "slug": 6494, "text": 6482 }, + "i-chart-individuals-chart", + { "depth": 33, "slug": 3911, "text": 3912 }, + { "depth": 33, "slug": 6342, "text": 6343 }, + { "depth": 33, "slug": 6346, "text": 6347 }, + { "depth": 33, "slug": 6358, "text": 6359 }, + { "depth": 33, "slug": 6500, "text": 6501 }, + "point-selection--create-factor", + "Point Selection & Create Factor", + { "depth": 79, "slug": 6503, "text": 6504 }, + "selecting-points", + "Selecting Points", + { "depth": 79, "slug": 6506, "text": 6507 }, + "what-happens-next", + "What Happens Next", + { "depth": 79, "slug": 6509, "text": 6510 }, + "when-to-use", + "When to Use", + { "depth": 33, "slug": 3956, "text": 3957 }, + { "depth": 33, "slug": 6513, "text": 6514 }, + "beneficial-signals", + "Beneficial Signals", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6482 }, + [], + "03-features/analysis/nelson-rules", + { "id": 6520, "data": 6522, "body": 6526, "filePath": 6527, "digest": 6528, "rendered": 6529 }, + { + "title": 572, + "editUrl": 16, + "head": 6523, + "template": 18, + "sidebar": 6524, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 6525 }, + {}, + "# Nelson Rules\n\nNelson Rules detect special cause variation patterns in control charts. VariScout implements Nelson Rule 2 to identify sustained process shifts.\n\n---\n\n## Nelson Rule 2: Nine-Point Run\n\n> \"Nine or more consecutive points on the same side of the mean.\"\n\nThis pattern indicates a **sustained shift** in the process - not random fluctuation.\n\n---\n\n## What It Detects\n\n| Pattern | Meaning |\n| -------------------- | ----------------------------------- |\n| 9+ points above mean | Process shifted UP |\n| 9+ points below mean | Process shifted DOWN |\n| Exactly on mean | Point doesn't count for either side |\n\n---\n\n## Why It Matters\n\nA single point outside control limits is obvious. But a sustained run on one side of the mean is equally significant - it means something systematic changed:\n\n- New material batch\n- Adjusted machine settings\n- Different operator technique\n- Environmental change (temperature, humidity)\n- Measurement system drift\n\n---\n\n## Probability\n\nFor a stable process:\n\n- Probability of 9 consecutive points above mean: (0.5)⁹ = 0.2%\n- This rare probability makes it a reliable signal\n\n---\n\n## How to Interpret\n\n```mermaid\nflowchart TD\n A[See 9+ point run] --> B{All above or all below mean?}\n B -->|Above| C[Process shifted UP]\n B -->|Below| D[Process shifted DOWN]\n C --> E[Investigate timeline]\n D --> E\n E --> F{Can identify change?}\n F -->|Yes| G[Document cause]\n F -->|No| H[Continue monitoring]\n G --> I[Decide: Revert or Accept?]\n I -->|Revert| J[Return to original state]\n I -->|Accept| K[Consider staged analysis]\n```\n\n---\n\n## Investigation Questions\n\nWhen you see a run:\n\n1. **When did it start?** - First point in the run\n2. **What changed then?** - Review logs, batches, personnel\n3. **Is the shift good or bad?** - Moving toward target = good\n4. **Is it permanent?** - One-time or ongoing change?\n\n---\n\n## Actions Based on Finding\n\n| Situation | Action |\n| --------------------------- | ------------------------------------------------- |\n| Shift improved process | Document as improvement, consider staged analysis |\n| Shift degraded process | Investigate root cause, correct |\n| Cause unknown, stable shift | Monitor, document, maintain |\n| Cause unknown, variable | Investigate urgently |\n\n---\n\n## In VariScout\n\nVariScout highlights Nelson Rule 2 violations directly on the I-Chart:\n\n- Points in a run are **marked distinctly**\n- Run length is displayed\n- Sequences are tracked in Performance Mode\n\n---\n\n## Staged Analysis Connection\n\nWhen a run indicates a genuine process shift (e.g., after an improvement project):\n\n1. The combined data shows a run violation\n2. But the **new process state** may be stable\n3. Use [Staged Analysis](staged-analysis.md) to calculate separate limits for before/after periods\n\n---\n\n## Technical Reference\n\nVariScout's implementation:\n\n```typescript\n// From @variscout/core\nimport { getNelsonRule2ViolationPoints, getNelsonRule2Sequences } from '@variscout/core';\n\n// Get indices of all points in violations\nconst violations = getNelsonRule2ViolationPoints(values, mean);\n\n// Get sequence details (start, end, side, length)\nconst sequences = getNelsonRule2Sequences(values, mean);\n```\n\n**Test coverage:** 30+ test cases in `packages/core/src/__tests__/nelson.test.ts`\n\n---\n\n## See Also\n\n- [I-Chart](i-chart.md) - Where Nelson rules are displayed\n- [Staged Analysis](staged-analysis.md) - Handling legitimate process shifts\n- [Glossary: Nelson Rules](../../glossary.md#nelson-rules)\n- [Glossary: Special Cause](../../glossary.md#special-cause)\n- [CHANGE Lens](../../01-vision/four-lenses/change.md) - Time-based stability", + "src/content/docs/03-features/analysis/nelson-rules.md", + "9f3979ed73261c9d", + { "html": 6530, "metadata": 6531 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"nelson-rules\">Nelson Rules\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#nelson-rules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Nelson Rules”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Nelson Rules detect special cause variation patterns in control charts. VariScout implements Nelson Rule 2 to identify sustained process shifts.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"nelson-rule-2-nine-point-run\">Nelson Rule 2: Nine-Point Run\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#nelson-rule-2-nine-point-run\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Nelson Rule 2: Nine-Point Run”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“Nine or more consecutive points on the same side of the mean.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>This pattern indicates a \u003Cstrong>sustained shift\u003C/strong> in the process - not random fluctuation.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-it-detects\">What It Detects\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-it-detects\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What It Detects”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>9+ points above mean\u003C/td>\u003Ctd>Process shifted UP\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9+ points below mean\u003C/td>\u003Ctd>Process shifted DOWN\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Exactly on mean\u003C/td>\u003Ctd>Point doesn’t count for either side\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-it-matters\">Why It Matters\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-it-matters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why It Matters”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A single point outside control limits is obvious. But a sustained run on one side of the mean is equally significant - it means something systematic changed:\u003C/p>\n\u003Cul>\n\u003Cli>New material batch\u003C/li>\n\u003Cli>Adjusted machine settings\u003C/li>\n\u003Cli>Different operator technique\u003C/li>\n\u003Cli>Environmental change (temperature, humidity)\u003C/li>\n\u003Cli>Measurement system drift\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"probability\">Probability\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#probability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Probability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For a stable process:\u003C/p>\n\u003Cul>\n\u003Cli>Probability of 9 consecutive points above mean: (0.5)⁹ = 0.2%\u003C/li>\n\u003Cli>This rare probability makes it a reliable signal\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-to-interpret\">How to Interpret\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-to-interpret\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How to Interpret”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[See 9+ point run] --> B{All above or all below mean?}\n B -->|Above| C[Process shifted UP]\n B -->|Below| D[Process shifted DOWN]\n C --> E[Investigate timeline]\n D --> E\n E --> F{Can identify change?}\n F -->|Yes| G[Document cause]\n F -->|No| H[Continue monitoring]\n G --> I[Decide: Revert or Accept?]\n I -->|Revert| J[Return to original state]\n I -->|Accept| K[Consider staged analysis]\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"investigation-questions\">Investigation Questions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-questions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation Questions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When you see a run:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>When did it start?\u003C/strong> - First point in the run\u003C/li>\n\u003Cli>\u003Cstrong>What changed then?\u003C/strong> - Review logs, batches, personnel\u003C/li>\n\u003Cli>\u003Cstrong>Is the shift good or bad?\u003C/strong> - Moving toward target = good\u003C/li>\n\u003Cli>\u003Cstrong>Is it permanent?\u003C/strong> - One-time or ongoing change?\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"actions-based-on-finding\">Actions Based on Finding\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#actions-based-on-finding\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Actions Based on Finding”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Situation\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Shift improved process\u003C/td>\u003Ctd>Document as improvement, consider staged analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shift degraded process\u003C/td>\u003Ctd>Investigate root cause, correct\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cause unknown, stable shift\u003C/td>\u003Ctd>Monitor, document, maintain\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cause unknown, variable\u003C/td>\u003Ctd>Investigate urgently\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"in-variscout\">In VariScout\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#in-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “In VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout highlights Nelson Rule 2 violations directly on the I-Chart:\u003C/p>\n\u003Cul>\n\u003Cli>Points in a run are \u003Cstrong>marked distinctly\u003C/strong>\u003C/li>\n\u003Cli>Run length is displayed\u003C/li>\n\u003Cli>Sequences are tracked in Performance Mode\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"staged-analysis-connection\">Staged Analysis Connection\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#staged-analysis-connection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Staged Analysis Connection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When a run indicates a genuine process shift (e.g., after an improvement project):\u003C/p>\n\u003Col>\n\u003Cli>The combined data shows a run violation\u003C/li>\n\u003Cli>But the \u003Cstrong>new process state\u003C/strong> may be stable\u003C/li>\n\u003Cli>Use \u003Ca href=\"staged-analysis.md\">Staged Analysis\u003C/a> to calculate separate limits for before/after periods\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-reference\">Technical Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s implementation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// From @variscout/core\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { getNelsonRule2ViolationPoints, getNelsonRule2Sequences } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Get indices of all points in violations\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">violations\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getNelsonRule2ViolationPoints\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(values\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Get sequence details (start, end, side, length)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sequences\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getNelsonRule2Sequences\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(values\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// From @variscout/coreimport { getNelsonRule2ViolationPoints, getNelsonRule2Sequences } from '@variscout/core';// Get indices of all points in violationsconst violations = getNelsonRule2ViolationPoints(values, mean);// Get sequence details (start, end, side, length)const sequences = getNelsonRule2Sequences(values, mean);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Test coverage:\u003C/strong> 30+ test cases in \u003Ccode dir=\"auto\">packages/core/src/__tests__/nelson.test.ts\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"i-chart.md\">I-Chart\u003C/a> - Where Nelson rules are displayed\u003C/li>\n\u003Cli>\u003Ca href=\"staged-analysis.md\">Staged Analysis\u003C/a> - Handling legitimate process shifts\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md#nelson-rules\">Glossary: Nelson Rules\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md#special-cause\">Glossary: Special Cause\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/change.md\">CHANGE Lens\u003C/a> - Time-based stability\u003C/li>\n\u003C/ul>", + { + "headings": 6532, + "localImagePaths": 6563, + "remoteImagePaths": 6564, + "frontmatter": 6565, + "imagePaths": 6566 + }, + [6533, 6534, 6537, 6540, 6543, 6546, 6549, 6552, 6555, 6558, 6561, 6562], + { "depth": 30, "slug": 571, "text": 572 }, + { "depth": 33, "slug": 6535, "text": 6536 }, + "nelson-rule-2-nine-point-run", + "Nelson Rule 2: Nine-Point Run", + { "depth": 33, "slug": 6538, "text": 6539 }, + "what-it-detects", + "What It Detects", + { "depth": 33, "slug": 6541, "text": 6542 }, + "why-it-matters", + "Why It Matters", + { "depth": 33, "slug": 6544, "text": 6545 }, + "probability", + "Probability", + { "depth": 33, "slug": 6547, "text": 6548 }, + "how-to-interpret", + "How to Interpret", + { "depth": 33, "slug": 6550, "text": 6551 }, + "investigation-questions", + "Investigation Questions", + { "depth": 33, "slug": 6553, "text": 6554 }, + "actions-based-on-finding", + "Actions Based on Finding", + { "depth": 33, "slug": 6556, "text": 6557 }, + "in-variscout", + "In VariScout", + { "depth": 33, "slug": 6559, "text": 6560 }, + "staged-analysis-connection", + "Staged Analysis Connection", + { "depth": 33, "slug": 3956, "text": 3957 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 572 }, + [], + "03-features/analysis/performance-mode", + { "id": 6567, "data": 6569, "body": 6574, "filePath": 6575, "digest": 6576, "rendered": 6577 }, + { + "title": 6570, + "editUrl": 16, + "head": 6571, + "template": 18, + "sidebar": 6572, + "pagefind": 16, + "draft": 20 + }, + "Performance Mode", + [], + { "hidden": 20, "attrs": 6573 }, + {}, + "# Performance Mode\n\nPerformance Mode enables multi-channel analysis for comparing multiple measurement points simultaneously.\n\n---\n\n## Purpose\n\nAnalyze multiple measurement channels (fill heads, cavities, nozzles) in a single view:\n\n- Compare Cpk across all channels\n- Identify the worst performers\n- Prioritize improvement efforts\n\n---\n\n## Use Cases\n\n| Industry | Channels |\n| ----------------------- | ------------------- |\n| Filling | Multiple fill heads |\n| Injection molding | Multiple cavities |\n| Multi-spindle machining | Multiple spindles |\n| Packaging | Multiple lanes |\n\n---\n\n## Performance Charts\n\n| Chart | Purpose |\n| ---------------------- | --------------------------------- |\n| Performance I-Chart | Cpk scatter plot by channel |\n| Performance Boxplot | Distribution comparison (max 5) |\n| Performance Pareto | Cpk ranking, worst first (max 20) |\n| Performance Capability | Single channel deep-dive |\n\n---\n\n## Workflow\n\n1. **Detect** - Auto-detect wide-format data with multiple measure columns\n2. **Configure** - Select which columns are measurement channels\n3. **Overview** - See all channels in Performance Pareto\n4. **Drill** - Click worst performer to see details\n5. **Analyze** - Use standard tools on filtered data\n\n---\n\n## Data Format\n\nPerformance Mode works with wide-format data:\n\n```csv\nTimestamp,Head1,Head2,Head3,Head4,Shift\n2024-01-01,99.5,100.2,98.8,99.1,Day\n2024-01-01,100.1,99.8,99.2,99.5,Day\n...\n```\n\n---\n\n## Props Pattern\n\nAll Performance charts accept:\n\n```typescript\ninterface PerformanceChartProps {\n channels: ChannelResult[];\n selectedMeasure?: string;\n onChannelClick?: (channel: string) => void;\n}\n```\n\n---\n\n---\n\n## Technical Reference\n\nVariScout's implementation:\n\n```typescript\n// From @variscout/core\nimport { calculateChannelResults, classifyChannelHealth } from '@variscout/core';\n\nconst channels = calculateChannelResults(data, measureColumns, specs);\n// Returns: ChannelResult[] with cpk, health classification per channel\n\n// Health classification based on Cpk:\n// - 'excellent': Cpk >= 1.67\n// - 'good': Cpk >= 1.33\n// - 'marginal': Cpk >= 1.0\n// - 'poor': Cpk \u003C 1.0\n```\n\n**Test coverage:** See `packages/core/src/__tests__/performance.test.ts`.\n\n---\n\n## See Also\n\n- [Chart Design: Performance Mode](../../06-design-system/charts/performance-mode.md)\n- [Capability Analysis](capability.md) - Single-channel capability concepts\n- [Pareto](pareto.md) - Ranking pattern (Performance Pareto similar)\n- [I-Chart](i-chart.md) - Time-series view (Performance I-Chart similar)\n- [Feature Parity](../../08-products/feature-parity.md) - Platform availability\n- [Glossary: Cpk](../../glossary.md#cpk)", + "src/content/docs/03-features/analysis/performance-mode.md", + "d05a4754cd7a7770", + { "html": 6578, "metadata": 6579 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"performance-mode\">Performance Mode\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#performance-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Performance Mode enables multi-channel analysis for comparing multiple measurement points simultaneously.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Analyze multiple measurement channels (fill heads, cavities, nozzles) in a single view:\u003C/p>\n\u003Cul>\n\u003Cli>Compare Cpk across all channels\u003C/li>\n\u003Cli>Identify the worst performers\u003C/li>\n\u003Cli>Prioritize improvement efforts\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"use-cases\">Use Cases\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#use-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Cases”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Industry\u003C/th>\u003Cth>Channels\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Filling\u003C/td>\u003Ctd>Multiple fill heads\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Injection molding\u003C/td>\u003Ctd>Multiple cavities\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multi-spindle machining\u003C/td>\u003Ctd>Multiple spindles\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Packaging\u003C/td>\u003Ctd>Multiple lanes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performance-charts\">Performance Charts\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performance-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Charts”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Performance I-Chart\u003C/td>\u003Ctd>Cpk scatter plot by channel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Boxplot\u003C/td>\u003Ctd>Distribution comparison (max 5)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Pareto\u003C/td>\u003Ctd>Cpk ranking, worst first (max 20)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Capability\u003C/td>\u003Ctd>Single channel deep-dive\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"workflow\">Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Detect\u003C/strong> - Auto-detect wide-format data with multiple measure columns\u003C/li>\n\u003Cli>\u003Cstrong>Configure\u003C/strong> - Select which columns are measurement channels\u003C/li>\n\u003Cli>\u003Cstrong>Overview\u003C/strong> - See all channels in Performance Pareto\u003C/li>\n\u003Cli>\u003Cstrong>Drill\u003C/strong> - Click worst performer to see details\u003C/li>\n\u003Cli>\u003Cstrong>Analyze\u003C/strong> - Use standard tools on filtered data\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-format\">Data Format\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-format\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Format”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Performance Mode works with wide-format data:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"csv\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Timestamp,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Head1,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Head2,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Head3,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Head4,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">Shift\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">2024-01-01,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">99.5,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">100.2,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">98.8,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">99.1,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">Day\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">2024-01-01,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">100.1,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">99.8,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">99.2,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">99.5,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">Day\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Timestamp,Head1,Head2,Head3,Head4,Shift2024-01-01,99.5,100.2,98.8,99.1,Day2024-01-01,100.1,99.8,99.2,99.5,Day...\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"props-pattern\">Props Pattern\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#props-pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Pattern”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All Performance charts accept:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceChartProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChannelResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">channel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface PerformanceChartProps { channels: ChannelResult[]; selectedMeasure?: string; onChannelClick?: (channel: string) => void;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-reference\">Technical Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s implementation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// From @variscout/core\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateChannelResults, classifyChannelHealth } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateChannelResults\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measureColumns\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns: ChannelResult[] with cpk, health classification per channel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Health classification based on Cpk:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - 'excellent': Cpk >= 1.67\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - 'good': Cpk >= 1.33\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - 'marginal': Cpk >= 1.0\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - 'poor': Cpk < 1.0\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// From @variscout/coreimport { calculateChannelResults, classifyChannelHealth } from '@variscout/core';const channels = calculateChannelResults(data, measureColumns, specs);// Returns: ChannelResult[] with cpk, health classification per channel// Health classification based on Cpk:// - 'excellent': Cpk >= 1.67// - 'good': Cpk >= 1.33// - 'marginal': Cpk >= 1.0// - 'poor': Cpk \u003C 1.0\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Test coverage:\u003C/strong> See \u003Ccode dir=\"auto\">packages/core/src/__tests__/performance.test.ts\u003C/code>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../06-design-system/charts/performance-mode.md\">Chart Design: Performance Mode\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"capability.md\">Capability Analysis\u003C/a> - Single-channel capability concepts\u003C/li>\n\u003Cli>\u003Ca href=\"pareto.md\">Pareto\u003C/a> - Ranking pattern (Performance Pareto similar)\u003C/li>\n\u003Cli>\u003Ca href=\"i-chart.md\">I-Chart\u003C/a> - Time-series view (Performance I-Chart similar)\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/feature-parity.md\">Feature Parity\u003C/a> - Platform availability\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md#cpk\">Glossary: Cpk\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 6580, + "localImagePaths": 6599, + "remoteImagePaths": 6600, + "frontmatter": 6601, + "imagePaths": 6602 + }, + [6581, 6583, 6584, 6585, 6588, 6591, 6594, 6597, 6598], + { "depth": 30, "slug": 6582, "text": 6570 }, + "performance-mode", + { "depth": 33, "slug": 3911, "text": 3912 }, + { "depth": 33, "slug": 907, "text": 908 }, + { "depth": 33, "slug": 6586, "text": 6587 }, + "performance-charts", + "Performance Charts", + { "depth": 33, "slug": 6589, "text": 6590 }, + "workflow", + "Workflow", + { "depth": 33, "slug": 6592, "text": 6593 }, + "data-format", + "Data Format", + { "depth": 33, "slug": 6595, "text": 6596 }, + "props-pattern", + "Props Pattern", + { "depth": 33, "slug": 3956, "text": 3957 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6570 }, + [], + "03-features/analysis/pareto", + { "id": 6603, "data": 6605, "body": 6610, "filePath": 6611, "digest": 6612, "rendered": 6613 }, + { + "title": 6606, + "editUrl": 16, + "head": 6607, + "template": 18, + "sidebar": 6608, + "pagefind": 16, + "draft": 20 + }, + "Pareto Chart", + [], + { "hidden": 20, "attrs": 6609 }, + {}, + "\u003C!-- journey-phase: scout -->\n\n# Pareto Chart\n\nThe Pareto Chart is VariScout's tool for the **FAILURE** lens - finding where problems concentrate.\n\n---\n\n## Purpose\n\n_\"Where do problems concentrate? Is 'chaotic data' actually mixed streams?\"_\n\nThe Pareto reveals:\n\n- Which categories contain most defects/issues\n- The vital few vs trivial many (80/20 rule)\n- Hidden patterns in \"generic scrap buckets\"\n- Whether failure modes are being masked\n\n---\n\n## Key Elements\n\n| Element | Description |\n| --------------- | ---------------------------------- |\n| Bars | Category counts, sorted descending |\n| Cumulative line | Running total percentage |\n| 80% marker | Visual guide for vital few |\n\n---\n\n## Interpretation\n\n| Pattern | Meaning |\n| ---------------------- | ------------------------ |\n| Steep cumulative curve | Few categories dominate |\n| Flat curve | Many small contributors |\n| First bar >50% | Single dominant category |\n| Top 3 bars >80% | Classic 80/20 pattern |\n\n---\n\n## Linked Filtering\n\nClick any bar to:\n\n- Filter all charts to that category\n- See which factors affect that defect type\n- Understand root causes\n\n---\n\n## Use Cases\n\n| Scenario | What to Analyze |\n| --------------- | --------------------------- |\n| Defect analysis | Count by defect type |\n| Downtime | Count by stoppage reason |\n| Complaints | Count by complaint category |\n| Scrap | Count by rejection reason |\n\n---\n\n## Data Shapes\n\nUsers typically bring Pareto data in one of two shapes:\n\n| Shape | Example | Recommended Mode |\n| --------------------- | ----------------------------------------------------------------------- | -------------------- |\n| **One row per event** | Each row is a defect occurrence with a category column | Count mode (default) |\n| **Pre-aggregated** | One row per category with a count/value column (e.g. `Defect \\| Count`) | Value mode (Σ) |\n\nWhen VariScout detects pre-aggregated data (every category has exactly one row), an amber hint appears on the Pareto chart suggesting the user switch to value mode. Clicking the hint activates value mode automatically.\n\n---\n\n## Technical Reference\n\nPareto charts in VariScout use sorted category counts with cumulative percentages. The calculation is straightforward:\n\n```typescript\n// Sort categories by count descending\n// Calculate cumulative percentage\n// Mark 80% threshold for \"vital few\"\n```\n\n---\n\n## See Also\n\n- [FAILURE Lens](../../01-vision/four-lenses/failure.md) - Problem concentration concepts\n- [Boxplot](boxplot.md) - Previous step: compare variation by factor\n- [Capability](capability.md) - Next step: assess capability of focused subset\n- [Drill-Down](../navigation/drill-down.md) - Navigate into top categories\n- [Chart Design](../../06-design-system/charts/pareto.md)\n- [Case: Packaging](../../04-cases/packaging/index.md) - Pareto in action\n- [Performance Mode](performance-mode.md) - Multi-channel Cpk ranking", + "src/content/docs/03-features/analysis/pareto.md", + "0ea8bc2286588c23", + { "html": 6614, "metadata": 6615 }, + "\u003C!-- journey-phase: scout -->\n\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"pareto-chart\">Pareto Chart\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#pareto-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pareto Chart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Pareto Chart is VariScout’s tool for the \u003Cstrong>FAILURE\u003C/strong> lens - finding where problems concentrate.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Where do problems concentrate? Is ‘chaotic data’ actually mixed streams?”\u003C/em>\u003C/p>\n\u003Cp>The Pareto reveals:\u003C/p>\n\u003Cul>\n\u003Cli>Which categories contain most defects/issues\u003C/li>\n\u003Cli>The vital few vs trivial many (80/20 rule)\u003C/li>\n\u003Cli>Hidden patterns in “generic scrap buckets”\u003C/li>\n\u003Cli>Whether failure modes are being masked\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-elements\">Key Elements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Elements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Bars\u003C/td>\u003Ctd>Category counts, sorted descending\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cumulative line\u003C/td>\u003Ctd>Running total percentage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>80% marker\u003C/td>\u003Ctd>Visual guide for vital few\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interpretation\">Interpretation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interpretation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpretation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Steep cumulative curve\u003C/td>\u003Ctd>Few categories dominate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Flat curve\u003C/td>\u003Ctd>Many small contributors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>First bar >50%\u003C/td>\u003Ctd>Single dominant category\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Top 3 bars >80%\u003C/td>\u003Ctd>Classic 80/20 pattern\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"linked-filtering\">Linked Filtering\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#linked-filtering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Linked Filtering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click any bar to:\u003C/p>\n\u003Cul>\n\u003Cli>Filter all charts to that category\u003C/li>\n\u003Cli>See which factors affect that defect type\u003C/li>\n\u003Cli>Understand root causes\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"use-cases\">Use Cases\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#use-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Cases”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Scenario\u003C/th>\u003Cth>What to Analyze\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Defect analysis\u003C/td>\u003Ctd>Count by defect type\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Downtime\u003C/td>\u003Ctd>Count by stoppage reason\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Complaints\u003C/td>\u003Ctd>Count by complaint category\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Scrap\u003C/td>\u003Ctd>Count by rejection reason\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-shapes\">Data Shapes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-shapes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Shapes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Users typically bring Pareto data in one of two shapes:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Shape\u003C/th>\u003Cth>Example\u003C/th>\u003Cth>Recommended Mode\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>One row per event\u003C/strong>\u003C/td>\u003Ctd>Each row is a defect occurrence with a category column\u003C/td>\u003Ctd>Count mode (default)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pre-aggregated\u003C/strong>\u003C/td>\u003Ctd>One row per category with a count/value column (e.g. \u003Ccode dir=\"auto\">Defect | Count\u003C/code>)\u003C/td>\u003Ctd>Value mode (Σ)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>When VariScout detects pre-aggregated data (every category has exactly one row), an amber hint appears on the Pareto chart suggesting the user switch to value mode. Clicking the hint activates value mode automatically.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-reference\">Technical Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pareto charts in VariScout use sorted category counts with cumulative percentages. The calculation is straightforward:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Sort categories by count descending\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Calculate cumulative percentage\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mark 80% threshold for \"vital few\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Sort categories by count descending// Calculate cumulative percentage// Mark 80% threshold for "vital few"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/failure.md\">FAILURE Lens\u003C/a> - Problem concentration concepts\u003C/li>\n\u003Cli>\u003Ca href=\"boxplot.md\">Boxplot\u003C/a> - Previous step: compare variation by factor\u003C/li>\n\u003Cli>\u003Ca href=\"capability.md\">Capability\u003C/a> - Next step: assess capability of focused subset\u003C/li>\n\u003Cli>\u003Ca href=\"../navigation/drill-down.md\">Drill-Down\u003C/a> - Navigate into top categories\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/charts/pareto.md\">Chart Design\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../04-cases/packaging/index.md\">Case: Packaging\u003C/a> - Pareto in action\u003C/li>\n\u003Cli>\u003Ca href=\"performance-mode.md\">Performance Mode\u003C/a> - Multi-channel Cpk ranking\u003C/li>\n\u003C/ul>", + { + "headings": 6616, + "localImagePaths": 6627, + "remoteImagePaths": 6628, + "frontmatter": 6629, + "imagePaths": 6630 + }, + [6617, 6619, 6620, 6621, 6622, 6623, 6624, 6625, 6626], + { "depth": 30, "slug": 6618, "text": 6606 }, + "pareto-chart", + { "depth": 33, "slug": 3911, "text": 3912 }, + { "depth": 33, "slug": 6342, "text": 6343 }, + { "depth": 33, "slug": 6346, "text": 6347 }, + { "depth": 33, "slug": 6358, "text": 6359 }, + { "depth": 33, "slug": 907, "text": 908 }, + { "depth": 33, "slug": 371, "text": 372 }, + { "depth": 33, "slug": 3956, "text": 3957 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6606 }, + [], + "03-features/analysis/probability-plot", + { "id": 6631, "data": 6633, "body": 6637, "filePath": 6638, "digest": 6639, "rendered": 6640 }, + { + "title": 581, + "editUrl": 16, + "head": 6634, + "template": 18, + "sidebar": 6635, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 6636 }, + {}, + "# Probability Plot\n\nThe probability plot assesses whether data follows a normal distribution, which underpins capability analysis and control chart assumptions.\n\n---\n\n## Purpose\n\n_\"Is my data normally distributed?\"_\n\nMany statistical methods assume normality:\n\n- **Cp/Cpk calculations** rely on normal distribution\n- **Control limits** (±3σ) assume symmetric, bell-shaped data\n- **Expected performance** predictions depend on distribution shape\n\nThe probability plot provides a visual answer.\n\n---\n\n## How to Read It\n\n### Linear = Normal\n\nIf your data is normally distributed, points fall along a **straight diagonal line**.\n\n```\nNormal Data: Non-Normal Data:\n • •\n • 95% •\n • •\n • line •\n • •\n• •\n```\n\n### Deviations from the Line\n\n| Pattern | Meaning |\n| ------------------ | ------------------------------- |\n| Points follow line | Normal distribution |\n| S-curve | Heavy tails (outliers) |\n| J-curve | Skewed right |\n| Inverted J | Skewed left |\n| Multiple clusters | Multi-modal (mixed populations) |\n\n---\n\n## Confidence Bands\n\nVariScout shows **95% confidence bands** around the expected line:\n\n- Points **within bands** = consistent with normality\n- Points **outside bands** = significant deviation\n\nA few points outside bands (especially at extremes) is normal. Systematic patterns outside bands indicate non-normality.\n\n---\n\n## Interpretation Workflow\n\n```mermaid\nflowchart TD\n A[View probability plot] --> B{Points follow line?}\n B -->|Yes| C[Data is approximately normal]\n B -->|No| D{What pattern?}\n D -->|S-curve| E[Check for outliers]\n D -->|J-curve| F[Right-skewed data]\n D -->|Multiple clusters| G[Mixed populations]\n C --> H[Capability analysis valid]\n E --> I[Investigate extreme values]\n F --> J[Consider transformation]\n G --> K[Stratify by factor]\n```\n\n---\n\n## Technical Details\n\n### Median Rank (Benard's Formula)\n\nVariScout uses **Benard's approximation** for expected percentiles:\n\n```\np = (i - 0.3) / (n + 0.4)\n```\n\nWhere:\n\n- `i` = rank position (1, 2, 3, ...)\n- `n` = sample size\n- `p` = expected cumulative probability\n\nThis formula is the **industry standard** (used by Minitab, JMP, and other statistical software).\n\n### Normal Quantile\n\nThe Y-axis shows the **normal quantile** (z-score) calculated using the **Acklam algorithm** for the inverse cumulative distribution function.\n\n---\n\n## When Normality Fails\n\n### Consequences\n\n| Impact Area | Effect of Non-Normality |\n| --------------------- | -------------------------------------- |\n| Cpk | May overstate or understate capability |\n| Control limits | May be too wide or too narrow |\n| Pass rate predictions | Will be inaccurate |\n\n### Solutions\n\n| Approach | When to Use |\n| -------------------------- | -------------------------------------- |\n| Transform data | Known skewness (e.g., log transform) |\n| Use non-parametric methods | When transformation not appropriate |\n| Stratify by factor | Multi-modal suggests mixed populations |\n| Increase sample size | Small samples often appear non-normal |\n| Accept approximation | Mild non-normality, large samples |\n\n---\n\n## Example Interpretations\n\n### Example 1: Normal Data\n\nPoints follow the line closely, all within confidence bands.\n\n**Conclusion:** Capability metrics are reliable.\n\n### Example 2: Heavy Tails\n\nS-shaped curve with points outside bands at both ends.\n\n**Conclusion:** More extreme values than normal predicts. Investigate for outliers or investigate the process for occasional disruptions.\n\n### Example 3: Right Skew\n\nJ-shaped curve, data clustered at low end.\n\n**Conclusion:** Process has a floor (can't go below zero?) but occasional high values. Consider log transformation or non-parametric analysis.\n\n---\n\n## Probability Plot vs. Histogram\n\n| Aspect | Probability Plot | Histogram |\n| -------------------- | ---------------- | ----------------- |\n| Normality assessment | Excellent | Good |\n| Tail behavior | Clear | Hard to see |\n| Small samples | Works well | Can be misleading |\n| Outlier detection | Good | Depends on bins |\n| Distribution shape | Precise | Approximate |\n\nUse **both** for comprehensive assessment.\n\n---\n\n## Technical Reference\n\nVariScout's implementation:\n\n```typescript\n// From @variscout/core\nimport { calculateProbabilityPlotData } from '@variscout/core';\n\nconst plotData = calculateProbabilityPlotData(values);\n\n// Returns array of:\n// {\n// value: number, // Sorted data value\n// percentile: number, // Benard's median rank\n// normalQuantile: number, // Z-score (Acklam)\n// ciLower: number, // 95% CI lower bound\n// ciUpper: number // 95% CI upper bound\n// }\n```\n\n**Test coverage:** See `packages/core/src/__tests__/stats.test.ts` for probability plot tests.\n\n---\n\n## See Also\n\n- [Capability](capability.md) - Where normality matters most\n- [Chart Design: Probability Plot](../../06-design-system/charts/probability-plot.md)\n- [Glossary: Probability Plot](../../glossary.md#probability-plot)\n- [Histogram (Capability Chart)](capability.md) - Alternative view", + "src/content/docs/03-features/analysis/probability-plot.md", + "0219f0066686b6f1", + { "html": 6641, "metadata": 6642 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"probability-plot\">Probability Plot\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#probability-plot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Probability Plot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The probability plot assesses whether data follows a normal distribution, which underpins capability analysis and control chart assumptions.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Is my data normally distributed?”\u003C/em>\u003C/p>\n\u003Cp>Many statistical methods assume normality:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Cp/Cpk calculations\u003C/strong> rely on normal distribution\u003C/li>\n\u003Cli>\u003Cstrong>Control limits\u003C/strong> (±3σ) assume symmetric, bell-shaped data\u003C/li>\n\u003Cli>\u003Cstrong>Expected performance\u003C/strong> predictions depend on distribution shape\u003C/li>\n\u003C/ul>\n\u003Cp>The probability plot provides a visual answer.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-to-read-it\">How to Read It\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-to-read-it\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How to Read It”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"linear--normal\">Linear = Normal\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#linear--normal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Linear = Normal”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>If your data is normally distributed, points fall along a \u003Cstrong>straight diagonal line\u003C/strong>.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Normal Data: Non-Normal Data:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">• •\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">• 95% •\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">• •\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">• line •\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">• •\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">• •\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Normal Data: Non-Normal Data: • • • 95% • • • • line • • •• •\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deviations-from-the-line\">Deviations from the Line\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deviations-from-the-line\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deviations from the Line”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Points follow line\u003C/td>\u003Ctd>Normal distribution\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>S-curve\u003C/td>\u003Ctd>Heavy tails (outliers)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>J-curve\u003C/td>\u003Ctd>Skewed right\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Inverted J\u003C/td>\u003Ctd>Skewed left\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multiple clusters\u003C/td>\u003Ctd>Multi-modal (mixed populations)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"confidence-bands\">Confidence Bands\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#confidence-bands\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Confidence Bands”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout shows \u003Cstrong>95% confidence bands\u003C/strong> around the expected line:\u003C/p>\n\u003Cul>\n\u003Cli>Points \u003Cstrong>within bands\u003C/strong> = consistent with normality\u003C/li>\n\u003Cli>Points \u003Cstrong>outside bands\u003C/strong> = significant deviation\u003C/li>\n\u003C/ul>\n\u003Cp>A few points outside bands (especially at extremes) is normal. Systematic patterns outside bands indicate non-normality.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interpretation-workflow\">Interpretation Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interpretation-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpretation Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[View probability plot] --> B{Points follow line?}\n B -->|Yes| C[Data is approximately normal]\n B -->|No| D{What pattern?}\n D -->|S-curve| E[Check for outliers]\n D -->|J-curve| F[Right-skewed data]\n D -->|Multiple clusters| G[Mixed populations]\n C --> H[Capability analysis valid]\n E --> I[Investigate extreme values]\n F --> J[Consider transformation]\n G --> K[Stratify by factor]\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-details\">Technical Details\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-details\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Details”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"median-rank-benards-formula\">Median Rank (Benard’s Formula)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#median-rank-benards-formula\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Median Rank (Benard’s Formula)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses \u003Cstrong>Benard’s approximation\u003C/strong> for expected percentiles:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">p = (i - 0.3) / (n + 0.4)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"p = (i - 0.3) / (n + 0.4)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Where:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">i\u003C/code> = rank position (1, 2, 3, …)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">n\u003C/code> = sample size\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">p\u003C/code> = expected cumulative probability\u003C/li>\n\u003C/ul>\n\u003Cp>This formula is the \u003Cstrong>industry standard\u003C/strong> (used by Minitab, JMP, and other statistical software).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"normal-quantile\">Normal Quantile\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#normal-quantile\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Normal Quantile”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Y-axis shows the \u003Cstrong>normal quantile\u003C/strong> (z-score) calculated using the \u003Cstrong>Acklam algorithm\u003C/strong> for the inverse cumulative distribution function.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"when-normality-fails\">When Normality Fails\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#when-normality-fails\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When Normality Fails”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"consequences\">Consequences\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#consequences\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consequences”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Impact Area\u003C/th>\u003Cth>Effect of Non-Normality\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Cpk\u003C/td>\u003Ctd>May overstate or understate capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Control limits\u003C/td>\u003Ctd>May be too wide or too narrow\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pass rate predictions\u003C/td>\u003Ctd>Will be inaccurate\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"solutions\">Solutions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#solutions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Solutions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Approach\u003C/th>\u003Cth>When to Use\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Transform data\u003C/td>\u003Ctd>Known skewness (e.g., log transform)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Use non-parametric methods\u003C/td>\u003Ctd>When transformation not appropriate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Stratify by factor\u003C/td>\u003Ctd>Multi-modal suggests mixed populations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Increase sample size\u003C/td>\u003Ctd>Small samples often appear non-normal\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Accept approximation\u003C/td>\u003Ctd>Mild non-normality, large samples\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"example-interpretations\">Example Interpretations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#example-interpretations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example Interpretations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-1-normal-data\">Example 1: Normal Data\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-1-normal-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example 1: Normal Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Points follow the line closely, all within confidence bands.\u003C/p>\n\u003Cp>\u003Cstrong>Conclusion:\u003C/strong> Capability metrics are reliable.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-2-heavy-tails\">Example 2: Heavy Tails\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-2-heavy-tails\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example 2: Heavy Tails”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>S-shaped curve with points outside bands at both ends.\u003C/p>\n\u003Cp>\u003Cstrong>Conclusion:\u003C/strong> More extreme values than normal predicts. Investigate for outliers or investigate the process for occasional disruptions.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-3-right-skew\">Example 3: Right Skew\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-3-right-skew\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example 3: Right Skew”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>J-shaped curve, data clustered at low end.\u003C/p>\n\u003Cp>\u003Cstrong>Conclusion:\u003C/strong> Process has a floor (can’t go below zero?) but occasional high values. Consider log transformation or non-parametric analysis.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"probability-plot-vs-histogram\">Probability Plot vs. Histogram\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#probability-plot-vs-histogram\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Probability Plot vs. Histogram”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Probability Plot\u003C/th>\u003Cth>Histogram\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Normality assessment\u003C/td>\u003Ctd>Excellent\u003C/td>\u003Ctd>Good\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tail behavior\u003C/td>\u003Ctd>Clear\u003C/td>\u003Ctd>Hard to see\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Small samples\u003C/td>\u003Ctd>Works well\u003C/td>\u003Ctd>Can be misleading\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Outlier detection\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Depends on bins\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Distribution shape\u003C/td>\u003Ctd>Precise\u003C/td>\u003Ctd>Approximate\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Use \u003Cstrong>both\u003C/strong> for comprehensive assessment.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-reference\">Technical Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s implementation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// From @variscout/core\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateProbabilityPlotData } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">plotData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateProbabilityPlotData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(values);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns array of:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// value: number, // Sorted data value\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// percentile: number, // Benard's median rank\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// normalQuantile: number, // Z-score (Acklam)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ciLower: number, // 95% CI lower bound\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ciUpper: number // 95% CI upper bound\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// }\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// From @variscout/coreimport { calculateProbabilityPlotData } from '@variscout/core';const plotData = calculateProbabilityPlotData(values);// Returns array of:// {// value: number, // Sorted data value// percentile: number, // Benard's median rank// normalQuantile: number, // Z-score (Acklam)// ciLower: number, // 95% CI lower bound// ciUpper: number // 95% CI upper bound// }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Test coverage:\u003C/strong> See \u003Ccode dir=\"auto\">packages/core/src/__tests__/stats.test.ts\u003C/code> for probability plot tests.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"capability.md\">Capability\u003C/a> - Where normality matters most\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/charts/probability-plot.md\">Chart Design: Probability Plot\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md#probability-plot\">Glossary: Probability Plot\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"capability.md\">Histogram (Capability Chart)\u003C/a> - Alternative view\u003C/li>\n\u003C/ul>", + { + "headings": 6643, + "localImagePaths": 6692, + "remoteImagePaths": 6693, + "frontmatter": 6694, + "imagePaths": 6695 + }, + [ + 6644, 6645, 6646, 6649, 6652, 6655, 6658, 6661, 6662, 6665, 6668, 6671, 6672, 6675, 6678, 6681, + 6684, 6687, 6690, 6691 + ], + { "depth": 30, "slug": 580, "text": 581 }, + { "depth": 33, "slug": 3911, "text": 3912 }, + { "depth": 33, "slug": 6647, "text": 6648 }, + "how-to-read-it", + "How to Read It", + { "depth": 79, "slug": 6650, "text": 6651 }, + "linear--normal", + "Linear = Normal", + { "depth": 79, "slug": 6653, "text": 6654 }, + "deviations-from-the-line", + "Deviations from the Line", + { "depth": 33, "slug": 6656, "text": 6657 }, + "confidence-bands", + "Confidence Bands", + { "depth": 33, "slug": 6659, "text": 6660 }, + "interpretation-workflow", + "Interpretation Workflow", + { "depth": 33, "slug": 3815, "text": 3816 }, + { "depth": 79, "slug": 6663, "text": 6664 }, + "median-rank-benards-formula", + "Median Rank (Benard’s Formula)", + { "depth": 79, "slug": 6666, "text": 6667 }, + "normal-quantile", + "Normal Quantile", + { "depth": 33, "slug": 6669, "text": 6670 }, + "when-normality-fails", + "When Normality Fails", + { "depth": 79, "slug": 2153, "text": 2154 }, + { "depth": 79, "slug": 6673, "text": 6674 }, + "solutions", + "Solutions", + { "depth": 33, "slug": 6676, "text": 6677 }, + "example-interpretations", + "Example Interpretations", + { "depth": 79, "slug": 6679, "text": 6680 }, + "example-1-normal-data", + "Example 1: Normal Data", + { "depth": 79, "slug": 6682, "text": 6683 }, + "example-2-heavy-tails", + "Example 2: Heavy Tails", + { "depth": 79, "slug": 6685, "text": 6686 }, + "example-3-right-skew", + "Example 3: Right Skew", + { "depth": 33, "slug": 6688, "text": 6689 }, + "probability-plot-vs-histogram", + "Probability Plot vs. Histogram", + { "depth": 33, "slug": 3956, "text": 3957 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 581 }, + [], + "03-features/analysis/staged-analysis", + { "id": 6696, "data": 6698, "body": 6702, "filePath": 6703, "digest": 6704, "rendered": 6705 }, + { + "title": 567, + "editUrl": 16, + "head": 6699, + "template": 18, + "sidebar": 6700, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 6701 }, + {}, + "# Staged Analysis\n\n\u003C!-- journey-phase: improve -->\n\nStaged analysis calculates independent control limits for different time periods, revealing improvements that combined analysis would hide.\n\n---\n\n## Purpose\n\n_\"Has the process actually improved, or are we averaging good with bad?\"_\n\nWhen a process changes (improvement project, new equipment, different supplier), combining all data can:\n\n- **Mask improvements** - Better recent performance drowns in historical noise\n- **Create false violations** - Good new data appears \"out of control\" against old limits\n- **Mislead decisions** - Average hides the real current state\n\n---\n\n## When to Use Staged Analysis\n\n| Situation | Use Staged? | Why |\n| -------------------------------- | ----------- | ------------------------- |\n| Improvement project before/after | ✓ | See actual impact |\n| Multiple material batches | ✓ | Compare batch performance |\n| Equipment replacement | ✓ | Validate new equipment |\n| Process change mid-dataset | ✓ | Separate old vs new |\n| Continuous stable process | ✗ | Combined is appropriate |\n| Investigating instability | Depends | May reveal hidden shifts |\n\n---\n\n## How It Works\n\n### Combined Analysis\n\n```\nAll Data → Single Mean → Single UCL/LCL\n```\n\nEvery point is judged against the same limits calculated from all data.\n\n### Staged Analysis\n\n```\nStage 1 Data → Stage 1 Mean → Stage 1 UCL/LCL\nStage 2 Data → Stage 2 Mean → Stage 2 UCL/LCL\n...\n```\n\nEach stage gets its own baseline, calculated only from that stage's data.\n\n---\n\n## Visual Example\n\n```mermaid\nflowchart LR\n subgraph Combined[\"Combined Analysis\"]\n A1[All data] --> A2[Single mean line]\n A2 --> A3[Single control limits]\n end\n\n subgraph Staged[\"Staged Analysis\"]\n B1[Stage 1] --> B2[Mean₁, UCL₁, LCL₁]\n B3[Stage 2] --> B4[Mean₂, UCL₂, LCL₂]\n end\n```\n\n---\n\n## Interpretation Guide\n\n### Comparing Stages\n\n| What Changed | Interpretation |\n| ------------------------------ | --------------------------------------------------------- |\n| Mean shifted down | Process center improved (if lower is better) |\n| Mean shifted up | Process center degraded (or improved if higher is better) |\n| Control limits narrowed | Variation reduced - more consistent |\n| Control limits widened | Variation increased - less consistent |\n| Both improved | Successful improvement project |\n| Mean improved, variation worse | Partial success - investigate |\n\n### Cpk Comparison\n\n| Stage | Cpk | Meaning |\n| ---------- | ---- | --------------------------- |\n| Before | 0.8 | Marginal capability |\n| After | 1.4 | Good capability |\n| **Change** | +0.6 | **Significant improvement** |\n\n---\n\n## Workflow\n\n```mermaid\nflowchart TD\n A[Upload data with time order] --> B{Single process period?}\n B -->|Yes| C[Use combined analysis]\n B -->|No| D[Identify stage boundaries]\n D --> E[Define stage column or dates]\n E --> F[View staged I-Chart]\n F --> G[Compare stage metrics]\n G --> H{Real improvement?}\n H -->|Yes| I[Document, set new baseline]\n H -->|No| J[Investigate why not]\n```\n\n---\n\n## Stage Definition Options\n\n### Option 1: Stage Column\n\nAdd a column to your data indicating the stage:\n\n| Row | Value | Stage |\n| --- | ----- | ------ |\n| 1 | 10.2 | Before |\n| 2 | 10.5 | Before |\n| ... | ... | ... |\n| 50 | 9.8 | After |\n| 51 | 9.7 | After |\n\n### Option 2: Date-Based\n\nUse a date column with a known cutoff:\n\n- Before: All rows before improvement date\n- After: All rows on or after improvement date\n\n### Option 3: Row Position\n\nDefine stage by row ranges:\n\n- Stage 1: Rows 1-100\n- Stage 2: Rows 101-200\n\n---\n\n## Example: Improvement Project\n\n**Scenario:** Fill weight optimization project\n\n| Metric | Before (n=50) | After (n=50) |\n| ------- | ------------- | ------------ |\n| Mean | 502.3g | 500.1g |\n| Std Dev | 2.8g | 1.9g |\n| UCL | 510.7g | 505.8g |\n| LCL | 493.9g | 494.4g |\n| Cpk | 0.89 | 1.32 |\n\n**Conclusion:** Project succeeded - closer to target (500g) with less variation.\n\n---\n\n## Avoiding the \"Aggregation Trap\"\n\nCombined analysis can mislead:\n\n```\nBefore: Mean = 502, StdDev = 2.8\nAfter: Mean = 500, StdDev = 1.9\nCombined: Mean = 501, StdDev = 2.5 ← Hides both the shift and the improvement!\n```\n\nStaged analysis reveals the truth that aggregated data conceals.\n\n---\n\n## Technical Reference\n\nVariScout's implementation:\n\n```typescript\n// From @variscout/core\nimport { calculateStagedStats, getStageBoundaries } from '@variscout/core';\n\n// Calculate per-stage statistics\nconst stagedStats = calculateStagedStats(\n data, // DataRow[]\n measureColumn, // e.g., 'FillWeight'\n stageColumn, // e.g., 'Period'\n stageOrder // 'data' | 'alphabetical' | 'chronological'\n);\n\n// Get boundaries for chart rendering\nconst boundaries = getStageBoundaries(sortedData, stagedStats);\n```\n\n**Test coverage:** See `packages/core/src/__tests__/stats.test.ts` for stage boundary tests.\n\n---\n\n## See Also\n\n- [I-Chart](i-chart.md) - Where staged analysis is displayed\n- [Nelson Rules](nelson-rules.md) - Detecting runs that signal shifts\n- [Capability](capability.md) - Comparing Cpk between stages\n- [Glossary: Staged Analysis](../../glossary.md#staged-analysis)\n- [Case: Hospital Ward](../../04-cases/hospital-ward/index.md) - Aggregation trap example", + "src/content/docs/03-features/analysis/staged-analysis.md", + "16d15ba830fabb24", + { "html": 6706, "metadata": 6707 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"staged-analysis\">Staged Analysis\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#staged-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Staged Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003C!-- journey-phase: improve -->\n\u003Cp>Staged analysis calculates independent control limits for different time periods, revealing improvements that combined analysis would hide.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Has the process actually improved, or are we averaging good with bad?”\u003C/em>\u003C/p>\n\u003Cp>When a process changes (improvement project, new equipment, different supplier), combining all data can:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Mask improvements\u003C/strong> - Better recent performance drowns in historical noise\u003C/li>\n\u003Cli>\u003Cstrong>Create false violations\u003C/strong> - Good new data appears “out of control” against old limits\u003C/li>\n\u003Cli>\u003Cstrong>Mislead decisions\u003C/strong> - Average hides the real current state\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"when-to-use-staged-analysis\">When to Use Staged Analysis\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-use-staged-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Use Staged Analysis”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Situation\u003C/th>\u003Cth>Use Staged?\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Improvement project before/after\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>See actual impact\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multiple material batches\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>Compare batch performance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Equipment replacement\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>Validate new equipment\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Process change mid-dataset\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>Separate old vs new\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Continuous stable process\u003C/td>\u003Ctd>✗\u003C/td>\u003Ctd>Combined is appropriate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Investigating instability\u003C/td>\u003Ctd>Depends\u003C/td>\u003Ctd>May reveal hidden shifts\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-it-works\">How It Works\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-it-works\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How It Works”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"combined-analysis\">Combined Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#combined-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Combined Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">All Data → Single Mean → Single UCL/LCL\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"All Data → Single Mean → Single UCL/LCL\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Every point is judged against the same limits calculated from all data.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"staged-analysis-1\">Staged Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#staged-analysis-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Staged Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Stage 1 Data → Stage 1 Mean → Stage 1 UCL/LCL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Stage 2 Data → Stage 2 Mean → Stage 2 UCL/LCL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">...\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Stage 1 Data → Stage 1 Mean → Stage 1 UCL/LCLStage 2 Data → Stage 2 Mean → Stage 2 UCL/LCL...\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Each stage gets its own baseline, calculated only from that stage’s data.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visual-example\">Visual Example\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visual-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n subgraph Combined[\"Combined Analysis\"]\n A1[All data] --> A2[Single mean line]\n A2 --> A3[Single control limits]\n end\n\n subgraph Staged[\"Staged Analysis\"]\n B1[Stage 1] --> B2[Mean₁, UCL₁, LCL₁]\n B3[Stage 2] --> B4[Mean₂, UCL₂, LCL₂]\n end\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interpretation-guide\">Interpretation Guide\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interpretation-guide\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpretation Guide”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"comparing-stages\">Comparing Stages\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#comparing-stages\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Comparing Stages”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>What Changed\u003C/th>\u003Cth>Interpretation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Mean shifted down\u003C/td>\u003Ctd>Process center improved (if lower is better)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mean shifted up\u003C/td>\u003Ctd>Process center degraded (or improved if higher is better)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Control limits narrowed\u003C/td>\u003Ctd>Variation reduced - more consistent\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Control limits widened\u003C/td>\u003Ctd>Variation increased - less consistent\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Both improved\u003C/td>\u003Ctd>Successful improvement project\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mean improved, variation worse\u003C/td>\u003Ctd>Partial success - investigate\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cpk-comparison\">Cpk Comparison\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cpk-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cpk Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stage\u003C/th>\u003Cth>Cpk\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Before\u003C/td>\u003Ctd>0.8\u003C/td>\u003Ctd>Marginal capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>After\u003C/td>\u003Ctd>1.4\u003C/td>\u003Ctd>Good capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Change\u003C/strong>\u003C/td>\u003Ctd>+0.6\u003C/td>\u003Ctd>\u003Cstrong>Significant improvement\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"workflow\">Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Upload data with time order] --> B{Single process period?}\n B -->|Yes| C[Use combined analysis]\n B -->|No| D[Identify stage boundaries]\n D --> E[Define stage column or dates]\n E --> F[View staged I-Chart]\n F --> G[Compare stage metrics]\n G --> H{Real improvement?}\n H -->|Yes| I[Document, set new baseline]\n H -->|No| J[Investigate why not]\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"stage-definition-options\">Stage Definition Options\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#stage-definition-options\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Stage Definition Options”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"option-1-stage-column\">Option 1: Stage Column\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#option-1-stage-column\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Option 1: Stage Column”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Add a column to your data indicating the stage:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Row\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>Stage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>10.2\u003C/td>\u003Ctd>Before\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>10.5\u003C/td>\u003Ctd>Before\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>…\u003C/td>\u003Ctd>…\u003C/td>\u003Ctd>…\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>50\u003C/td>\u003Ctd>9.8\u003C/td>\u003Ctd>After\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>51\u003C/td>\u003Ctd>9.7\u003C/td>\u003Ctd>After\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"option-2-date-based\">Option 2: Date-Based\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#option-2-date-based\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Option 2: Date-Based”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use a date column with a known cutoff:\u003C/p>\n\u003Cul>\n\u003Cli>Before: All rows before improvement date\u003C/li>\n\u003Cli>After: All rows on or after improvement date\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"option-3-row-position\">Option 3: Row Position\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#option-3-row-position\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Option 3: Row Position”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Define stage by row ranges:\u003C/p>\n\u003Cul>\n\u003Cli>Stage 1: Rows 1-100\u003C/li>\n\u003Cli>Stage 2: Rows 101-200\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"example-improvement-project\">Example: Improvement Project\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#example-improvement-project\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example: Improvement Project”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Scenario:\u003C/strong> Fill weight optimization project\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Before (n=50)\u003C/th>\u003Cth>After (n=50)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Mean\u003C/td>\u003Ctd>502.3g\u003C/td>\u003Ctd>500.1g\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Std Dev\u003C/td>\u003Ctd>2.8g\u003C/td>\u003Ctd>1.9g\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UCL\u003C/td>\u003Ctd>510.7g\u003C/td>\u003Ctd>505.8g\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LCL\u003C/td>\u003Ctd>493.9g\u003C/td>\u003Ctd>494.4g\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cpk\u003C/td>\u003Ctd>0.89\u003C/td>\u003Ctd>1.32\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Conclusion:\u003C/strong> Project succeeded - closer to target (500g) with less variation.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"avoiding-the-aggregation-trap\">Avoiding the “Aggregation Trap”\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#avoiding-the-aggregation-trap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Avoiding the “Aggregation Trap””\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Combined analysis can mislead:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Before: Mean = 502, StdDev = 2.8\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">After: Mean = 500, StdDev = 1.9\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Combined: Mean = 501, StdDev = 2.5 ← Hides both the shift and the improvement!\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Before: Mean = 502, StdDev = 2.8After: Mean = 500, StdDev = 1.9Combined: Mean = 501, StdDev = 2.5 ← Hides both the shift and the improvement!\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Staged analysis reveals the truth that aggregated data conceals.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-reference\">Technical Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s implementation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// From @variscout/core\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateStagedStats, getStageBoundaries } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Calculate per-stage statistics\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">stagedStats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateStagedStats\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// DataRow[]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measureColumn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// e.g., 'FillWeight'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stageColumn\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// e.g., 'Period'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stageOrder\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 'data' | 'alphabetical' | 'chronological'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Get boundaries for chart rendering\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">boundaries\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getStageBoundaries\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(sortedData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stagedStats);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// From @variscout/coreimport { calculateStagedStats, getStageBoundaries } from '@variscout/core';// Calculate per-stage statisticsconst stagedStats = calculateStagedStats( data, // DataRow[] measureColumn, // e.g., 'FillWeight' stageColumn, // e.g., 'Period' stageOrder // 'data' | 'alphabetical' | 'chronological');// Get boundaries for chart renderingconst boundaries = getStageBoundaries(sortedData, stagedStats);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Test coverage:\u003C/strong> See \u003Ccode dir=\"auto\">packages/core/src/__tests__/stats.test.ts\u003C/code> for stage boundary tests.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"i-chart.md\">I-Chart\u003C/a> - Where staged analysis is displayed\u003C/li>\n\u003Cli>\u003Ca href=\"nelson-rules.md\">Nelson Rules\u003C/a> - Detecting runs that signal shifts\u003C/li>\n\u003Cli>\u003Ca href=\"capability.md\">Capability\u003C/a> - Comparing Cpk between stages\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md#staged-analysis\">Glossary: Staged Analysis\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../04-cases/hospital-ward/index.md\">Case: Hospital Ward\u003C/a> - Aggregation trap example\u003C/li>\n\u003C/ul>", + { + "headings": 6708, + "localImagePaths": 6751, + "remoteImagePaths": 6752, + "frontmatter": 6753, + "imagePaths": 6754 + }, + [ + 6709, 6710, 6711, 6714, 6715, 6718, 6720, 6723, 6724, 6727, 6730, 6731, 6734, 6737, 6740, 6743, + 6746, 6749, 6750 + ], + { "depth": 30, "slug": 566, "text": 567 }, + { "depth": 33, "slug": 3911, "text": 3912 }, + { "depth": 33, "slug": 6712, "text": 6713 }, + "when-to-use-staged-analysis", + "When to Use Staged Analysis", + { "depth": 33, "slug": 1173, "text": 1174 }, + { "depth": 79, "slug": 6716, "text": 6717 }, + "combined-analysis", + "Combined Analysis", + { "depth": 79, "slug": 6719, "text": 567 }, + "staged-analysis-1", + { "depth": 33, "slug": 6721, "text": 6722 }, + "visual-example", + "Visual Example", + { "depth": 33, "slug": 3917, "text": 3918 }, + { "depth": 79, "slug": 6725, "text": 6726 }, + "comparing-stages", + "Comparing Stages", + { "depth": 79, "slug": 6728, "text": 6729 }, + "cpk-comparison", + "Cpk Comparison", + { "depth": 33, "slug": 6589, "text": 6590 }, + { "depth": 33, "slug": 6732, "text": 6733 }, + "stage-definition-options", + "Stage Definition Options", + { "depth": 79, "slug": 6735, "text": 6736 }, + "option-1-stage-column", + "Option 1: Stage Column", + { "depth": 79, "slug": 6738, "text": 6739 }, + "option-2-date-based", + "Option 2: Date-Based", + { "depth": 79, "slug": 6741, "text": 6742 }, + "option-3-row-position", + "Option 3: Row Position", + { "depth": 33, "slug": 6744, "text": 6745 }, + "example-improvement-project", + "Example: Improvement Project", + { "depth": 33, "slug": 6747, "text": 6748 }, + "avoiding-the-aggregation-trap", + "Avoiding the “Aggregation Trap”", + { "depth": 33, "slug": 3956, "text": 3957 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 567 }, + [], + "03-features/analysis/variation-decomposition", + { "id": 6755, "data": 6757, "body": 6762, "filePath": 6763, "digest": 6764, "rendered": 6765 }, + { + "title": 6758, + "editUrl": 16, + "head": 6759, + "template": 18, + "sidebar": 6760, + "pagefind": 16, + "draft": 20 + }, + "Variation Decomposition", + [], + { "hidden": 20, "attrs": 6761 }, + {}, + "# Variation Decomposition\n\nWhy VariScout uses different metrics for different questions, and how they relate to one-way ANOVA.\n\n---\n\n## The ANOVA Identity\n\nOne-way ANOVA decomposes total variation into two additive sources:\n\n**SS_Total = SS_Between + SS_Within**\n\n| Term | Formula | Meaning |\n| ---------- | ------------------ | ------------------------------------------------------------ |\n| SS_Total | Σ(x_ij − x̄)² | Total variation in the data (all deviations from grand mean) |\n| SS_Between | Σ n_j × (x̄_j − x̄)² | Variation explained by group membership (mean differences) |\n| SS_Within | ΣΣ (x_ij − x̄_j)² | Variation within each group (spread around group means) |\n\nThis identity always holds exactly. The cross term vanishes because the sum of deviations within any group is zero: Σ(x_ij − x̄_j) = 0.\n\n### Category-level decomposition\n\nThe identity also works at the category level. For any category _j_:\n\n**Category_SS_j = SS_Between_j + SS_Within_j**\n\nwhere:\n\n- SS_Between_j = n_j × (x̄_j − x̄)² — group mean vs grand mean\n- SS_Within_j = Σ_i (x_ij − x̄_j)² — spread within the group\n\nKey identity: **Σ_j Category_SS_j = SS_Total**\n\nThe total variation is fully partitioned across categories — every observation's deviation from the grand mean is accounted for by exactly one category. This means category percentages always sum to 100%.\n\nWith unbalanced data (unequal category sizes), larger categories contribute proportionally more to Total SS. This reflects their actual impact on the data but may overstate their importance per-observation.\n\n---\n\n## Three Metrics, Three Questions\n\nVariScout uses three different variation metrics, each answering a distinct question:\n\n| Metric | Formula | Question it answers | Where used in VariScout |\n| ------------------- | ------------------------ | -------------------------------------------------- | ------------------------------------------------------------------- |\n| η² (eta-squared) | SS_Between / SS_Total | \"How much variation does this **factor** explain?\" | ANOVA panel, Mindmap node circles, suggestion ranking (green pulse) |\n| Category Total SS % | Category_SS_j / SS_Total | \"How much does each **category** contribute?\" | Mindmap popover rows, contribution labels on Boxplot, filter chips |\n\n### Why η² for factor ranking\n\nη² measures only between-group variation (mean differences). This is the right metric for ranking **factors** because it is not distorted by the number of categories in a factor.\n\nA 5-category factor with diverse means (e.g. Step 1-5 with different cycle times) correctly ranks higher than a 2-category factor with similar means (e.g. Shift with Morning/Afternoon), because η² captures the total between-group effect regardless of how it is distributed across categories.\n\n> **Note on bias:** η² is a positively biased estimator — it tends to overstate the true population effect size, especially with small samples or many groups. VariScout uses η² (not the unbiased ω²) because it is the standard metric taught in Six Sigma training and because the drill-down use case involves relative ranking, not absolute estimation.\n\nMax-category Total SS is biased by category count: with 2 categories, each gets roughly 50% of variation; with 5 categories, each gets roughly 20%. A 2-category factor always looks \"bigger\" by this metric even when its η² is lower. That is why VariScout uses η² for the Mindmap suggestion ranking (the green pulse that highlights which factor to drill next).\n\n### Why Total SS (not between-group) for category contribution\n\nBetween-group SS only captures **mean shift**: n_j × (x̄_j − x̄)². A category whose mean equals the grand mean shows 0% — even if it has enormous spread. This is misleading: a category with high within-group variation is a real contributor to overall variation, regardless of where its mean sits.\n\nTotal SS contribution = (SS_Between_j + SS_Within_j) / SS_Total. This captures **both** mean shift **and** spread. Categories always sum to 100%.\n\nThe worked example below demonstrates why this matters.\n\n---\n\n## Worked Example: Bottleneck Data\n\nThe [Bottleneck case study](../../04-cases/bottleneck/index.md) has 150 cycle time measurements across 5 process steps (30 observations each). Grand mean = 36.24 seconds, SS_Total = 7,039.\n\n### Step-level decomposition\n\n| Step | n | Mean | SD | SS_Between | SS_Within | Category SS | Total SS % |\n| ---------- | --- | ----- | --- | ---------- | --------- | ----------- | ---------- |\n| Step 1 | 30 | 32.5 | 2.0 | 412 | 116 | 528 | **7.5%** |\n| **Step 2** | 30 | 39.4 | 8.9 | 306 | 2,393 | 2,699 | **38.3%** |\n| Step 3 | 30 | 45.1 | 1.5 | 2,355 | 71 | 2,426 | **34.5%** |\n| Step 4 | 30 | 33.7 | 1.9 | 194 | 104 | 298 | **4.2%** |\n| Step 5 | 30 | 30.4 | 1.6 | 1,012 | 77 | 1,089 | **15.5%** |\n| **Total** | 150 | 36.24 | | **4,278** | **2,761** | **7,039** | **100%** |\n\nη² for the Step factor = 4,278 / 7,039 = **0.61** (61% of variation explained by step differences).\n\n### The key comparison: Step 2 vs Step 3\n\n| Metric | Step 2 | Step 3 | Which looks bigger? |\n| ---------------------------- | ----------------- | ----------------- | ------------------- |\n| SS_Between (mean shift only) | 306 (4.3%) | 2,355 (33.5%) | Step 3 |\n| SS_Within (spread only) | 2,393 (34.0%) | 71 (1.0%) | Step 2 |\n| **Category Total SS** | **2,699 (38.3%)** | **2,426 (34.5%)** | **Step 2** |\n\nIf VariScout used **between-group SS** for the category popover, Step 2 would show just 4.3% contribution — it would look irrelevant. But Step 2 has the highest variance (SD = 8.9 vs the next highest at 2.0), and its inconsistency is what creates the production bottleneck.\n\n**Total SS contribution** correctly shows Step 2 at 38.3% — the single largest contributor to overall variation. This matches the case study finding: Step 2's unpredictability, not Step 3's consistently high mean, is the real problem.\n\n### What 38.3% means in practice\n\nIf you could eliminate Step 2's excess variation (bring its SD from 8.9 down to the average of other steps, ~1.8), you would remove approximately 34% of the total cycle time variation. Whether this translates to meaningful yield improvement depends on the specification limits — use the What-If Simulator to project the specific Cpk and yield change.\n\nThis matches the case study outcome: management was about to invest €50k upgrading Step 3 (highest mean). The variation analysis revealed Step 2 (highest spread) was the real bottleneck. The actual fix was €5k in training and standardized work instructions — a 10× better allocation of resources.\n\n---\n\n## How This Maps to the VariScout UI\n\n### ANOVA panel (Boxplot view)\n\nShows F-statistic, p-value, and η². These are factor-level metrics that answer \"does this factor matter?\" η² = 0.61 for Step means 61% of all cycle time variation is explained by which step you measure.\n\nF-test and p-value assume approximately normal data with similar spread across groups. η² and Total SS % are descriptive and do not require these assumptions.\n\n### Mindmap suggestion ranking\n\nThe green pulse highlights the factor with the highest η² among unexplored factors. This guides the analyst to drill the most impactful factor next.\n\n### Mindmap node circles\n\nEach available node displays **η²** for that factor — the same metric shown in the ANOVA panel. This answers \"how much variation does this factor explain?\" at a glance. The node number matches the ANOVA panel number, ensuring cross-view consistency. Drilled (active) nodes show no percentage — they display the filtered value label instead. The category-level detail (Total SS %) is available in the popover.\n\n### Category popover and contribution labels\n\nEach row shows **Category Total SS %** for every category within the selected factor. These always sum to 100%. The analyst sees exactly how variation is distributed across categories — capturing both mean differences and spread.\n\n### Drill-down filter chips\n\nWhen the analyst filters (e.g. clicks Step 2), the contribution percentage on the filter chip shows how much of the **original** total variation that filter captures. This keeps the analyst anchored to the original problem throughout the drill-down.\n\nThe cumulative percentage represents the fraction of the original total variation captured by your current filter combination. \"45% in focus\" means your current drill path accounts for 45% of all the variation in the dataset — the remaining 55% comes from data outside your filter selection.\n\n### A note on controllability\n\nIdentifying a variation source is necessary but not sufficient for improvement. Before committing resources, assess whether the source is controllable (can be changed with training, procedure, settings) or structural (requires equipment, material, or design changes). The What-If Simulator helps quantify the potential impact of changes; domain expertise determines feasibility.\n\n---\n\n## For the Quality Professional\n\nIf you've completed Six Sigma Green Belt training, you've seen one-way ANOVA in the Analyze phase. VariScout uses the same F-test, p-value, and η² — plus one extension at the category level. Here is how VariScout's metrics map to standard terminology:\n\n| Standard ANOVA term | VariScout equivalent | Notes |\n| ----------------------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| SS_Between / SS_Total | η² in ANOVA panel | Identical to standard η² |\n| MS_Between / MS_Within | F-statistic in ANOVA panel | Standard F-test |\n| SS for a specific group | Category Total SS % | VariScout adds within-group SS to give full picture |\n| Effect size (η²) | Suggestion ranking | Used to guide drill-down order |\n| Multi-Vari study | Mindmap progressive drill-down | VariScout automates the Multi-Vari decomposition: the analyst drills factors one at a time, and the tool quantifies each level's contribution |\n\nVariScout extends textbook ANOVA at the **category level**. Textbook ANOVA focuses on the F-test and η² (both factor-level metrics). VariScout extends the decomposition to individual categories by including within-group variation, because the drill-down workflow needs to answer \"which category should I investigate?\" — a question that between-group SS alone cannot answer reliably.\n\n**Confounding:** One-factor-at-a-time analysis does not account for confounding between factors. If Operator and Shift are correlated (certain operators only work nights), drilling by Shift may capture variation actually caused by Operator. Phase 2 will re-introduce the Mindmap interaction mode and Advanced Regression model to detect and untangle these effects (see [Phase 2 Regression Roadmap](../../05-technical/implementation/phase2-regression-roadmap.md)).\n\n---\n\n## Limitations and Assumptions\n\nThe variation decomposition system is a practical tool for process investigation. Understanding its limitations helps the analyst know when to trust the drill-down and when to move to more rigorous methods.\n\n### Path dependency\n\nThe drill-down examines one factor at a time. Different drill orders can produce different intermediate percentages — for example, drilling Shift → Operator may show different local scope fractions than Operator → Shift — but they converge on similar cumulative scope. For statistically rigorous joint analysis, the Regression panel planned for Phase 2 will provide correct multi-factor estimates (see [Phase 2 Regression Roadmap](../../05-technical/implementation/phase2-regression-roadmap.md)). See [Progressive Stratification](../../01-vision/progressive-stratification.md) Part 2 for a detailed treatment of this tension.\n\n### Confounding and correlated factors\n\nReal process data is rarely orthogonal. When factors are correlated (operator × shift, material × supplier), one-factor ANOVA misattributes variation. The drill-down can lead to incorrect factor prioritization. Phase 2 will re-introduce the Mindmap interaction mode as an early signal and the Advanced Regression model for the correct joint estimate (see [Phase 2 Regression Roadmap](../../05-technical/implementation/phase2-regression-roadmap.md)).\n\n### Cumulative scope approximation\n\nThe cumulative scope percentage (the \"in focus\" number on drill-down chips) is the multiplicative product of local scope fractions through the drill path. This is an intuitive \"funnel\" metaphor, not a statistically grounded quantity. It treats each drill level's local scope as independent, which fails when factors are correlated. The regression model planned for Phase 2 will provide the correct joint estimate of explained variation.\n\n### When to transition beyond drill-down\n\nUse the drill-down for initial investigation (3–5 minutes). If you suspect interactions, have confounded factors, or need a formal model for projection, use the What-If Simulator to test scenarios with direct adjustments. Advanced Regression (planned for Phase 2) will provide formal multi-factor modelling and an automated handoff from the Mindmap — see [Phase 2 Regression Roadmap](../../05-technical/implementation/phase2-regression-roadmap.md).\n\n---\n\n## Presenting Results\n\nWhen presenting variation findings to stakeholders, translate statistical metrics to business terms:\n\n- Instead of \"Step 2 contributes 38.3% of Total SS,\" say \"Step 2's inconsistency accounts for the largest share of cycle time variation.\"\n- Instead of \"η² = 0.61 for Process Step,\" say \"Which step the product is at explains 61% of the variation we see.\"\n- Use the What-If Simulator to generate specific before/after projections: \"Reducing Step 2's spread from 8.9 to 2.0 seconds would improve overall process capability from Cpk X to Cpk Y.\"\n\nThe chart copy and export features (clipboard, PNG, SVG) produce presentation-ready visuals that can be pasted directly into tollgate reviews and improvement reports.\n\n---\n\n## References\n\n- NIST/SEMATECH e-Handbook of Statistical Methods, Section 7.4.3.2 — One-Way ANOVA\n- Montgomery, D.C. _Introduction to Statistical Quality Control_ (8th ed.), Chapter 13\n- VariScout implementation: `packages/core/src/stats/anova.ts` (ANOVA), `packages/core/src/variation/contributions.ts` (category decomposition)\n\n---\n\n## Cross-references\n\n| Topic | Document |\n| ----------------------------------------------------- | --------------------------------------------------------------------------- |\n| UX rationale for drill-down | [Progressive Stratification](../../01-vision/progressive-stratification.md) |\n| Investigation workflow (Mindmap, Regression, What-If) | [Investigation to Action](../workflows/investigation-to-action.md) |\n| Boxplot ANOVA display | [Boxplot](boxplot.md) |\n| Category contribution labels | [Boxplot](boxplot.md) |\n| Regression and interaction analysis | [Regression](regression.md) |\n| Glossary: η², Total SS Contribution | `packages/core/src/glossary/terms.ts` |", + "src/content/docs/03-features/analysis/variation-decomposition.md", + "327b60738c52c26b", + { "html": 6766, "metadata": 6767 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"variation-decomposition\">Variation Decomposition\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#variation-decomposition\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Variation Decomposition”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Why VariScout uses different metrics for different questions, and how they relate to one-way ANOVA.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-anova-identity\">The ANOVA Identity\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-anova-identity\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The ANOVA Identity”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>One-way ANOVA decomposes total variation into two additive sources:\u003C/p>\n\u003Cp>\u003Cstrong>SS_Total = SS_Between + SS_Within\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Term\u003C/th>\u003Cth>Formula\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>SS_Total\u003C/td>\u003Ctd>Σ(x_ij − x̄)²\u003C/td>\u003Ctd>Total variation in the data (all deviations from grand mean)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SS_Between\u003C/td>\u003Ctd>Σ n_j × (x̄_j − x̄)²\u003C/td>\u003Ctd>Variation explained by group membership (mean differences)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SS_Within\u003C/td>\u003Ctd>ΣΣ (x_ij − x̄_j)²\u003C/td>\u003Ctd>Variation within each group (spread around group means)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>This identity always holds exactly. The cross term vanishes because the sum of deviations within any group is zero: Σ(x_ij − x̄_j) = 0.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"category-level-decomposition\">Category-level decomposition\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#category-level-decomposition\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Category-level decomposition”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The identity also works at the category level. For any category \u003Cem>j\u003C/em>:\u003C/p>\n\u003Cp>\u003Cstrong>Category_SS_j = SS_Between_j + SS_Within_j\u003C/strong>\u003C/p>\n\u003Cp>where:\u003C/p>\n\u003Cul>\n\u003Cli>SS_Between_j = n_j × (x̄_j − x̄)² — group mean vs grand mean\u003C/li>\n\u003Cli>SS_Within_j = Σ_i (x_ij − x̄_j)² — spread within the group\u003C/li>\n\u003C/ul>\n\u003Cp>Key identity: \u003Cstrong>Σ_j Category_SS_j = SS_Total\u003C/strong>\u003C/p>\n\u003Cp>The total variation is fully partitioned across categories — every observation’s deviation from the grand mean is accounted for by exactly one category. This means category percentages always sum to 100%.\u003C/p>\n\u003Cp>With unbalanced data (unequal category sizes), larger categories contribute proportionally more to Total SS. This reflects their actual impact on the data but may overstate their importance per-observation.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"three-metrics-three-questions\">Three Metrics, Three Questions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#three-metrics-three-questions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Three Metrics, Three Questions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses three different variation metrics, each answering a distinct question:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Formula\u003C/th>\u003Cth>Question it answers\u003C/th>\u003Cth>Where used in VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>η² (eta-squared)\u003C/td>\u003Ctd>SS_Between / SS_Total\u003C/td>\u003Ctd>”How much variation does this \u003Cstrong>factor\u003C/strong> explain?”\u003C/td>\u003Ctd>ANOVA panel, Mindmap node circles, suggestion ranking (green pulse)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Category Total SS %\u003C/td>\u003Ctd>Category_SS_j / SS_Total\u003C/td>\u003Ctd>”How much does each \u003Cstrong>category\u003C/strong> contribute?”\u003C/td>\u003Ctd>Mindmap popover rows, contribution labels on Boxplot, filter chips\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-η-for-factor-ranking\">Why η² for factor ranking\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-η-for-factor-ranking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why η² for factor ranking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>η² measures only between-group variation (mean differences). This is the right metric for ranking \u003Cstrong>factors\u003C/strong> because it is not distorted by the number of categories in a factor.\u003C/p>\n\u003Cp>A 5-category factor with diverse means (e.g. Step 1-5 with different cycle times) correctly ranks higher than a 2-category factor with similar means (e.g. Shift with Morning/Afternoon), because η² captures the total between-group effect regardless of how it is distributed across categories.\u003C/p>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note on bias:\u003C/strong> η² is a positively biased estimator — it tends to overstate the true population effect size, especially with small samples or many groups. VariScout uses η² (not the unbiased ω²) because it is the standard metric taught in Six Sigma training and because the drill-down use case involves relative ranking, not absolute estimation.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Max-category Total SS is biased by category count: with 2 categories, each gets roughly 50% of variation; with 5 categories, each gets roughly 20%. A 2-category factor always looks “bigger” by this metric even when its η² is lower. That is why VariScout uses η² for the Mindmap suggestion ranking (the green pulse that highlights which factor to drill next).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-total-ss-not-between-group-for-category-contribution\">Why Total SS (not between-group) for category contribution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-total-ss-not-between-group-for-category-contribution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Total SS (not between-group) for category contribution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Between-group SS only captures \u003Cstrong>mean shift\u003C/strong>: n_j × (x̄_j − x̄)². A category whose mean equals the grand mean shows 0% — even if it has enormous spread. This is misleading: a category with high within-group variation is a real contributor to overall variation, regardless of where its mean sits.\u003C/p>\n\u003Cp>Total SS contribution = (SS_Between_j + SS_Within_j) / SS_Total. This captures \u003Cstrong>both\u003C/strong> mean shift \u003Cstrong>and\u003C/strong> spread. Categories always sum to 100%.\u003C/p>\n\u003Cp>The worked example below demonstrates why this matters.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"worked-example-bottleneck-data\">Worked Example: Bottleneck Data\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#worked-example-bottleneck-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Worked Example: Bottleneck Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ca href=\"../../04-cases/bottleneck/index.md\">Bottleneck case study\u003C/a> has 150 cycle time measurements across 5 process steps (30 observations each). Grand mean = 36.24 seconds, SS_Total = 7,039.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-level-decomposition\">Step-level decomposition\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-level-decomposition\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step-level decomposition”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Step\u003C/th>\u003Cth>n\u003C/th>\u003Cth>Mean\u003C/th>\u003Cth>SD\u003C/th>\u003Cth>SS_Between\u003C/th>\u003Cth>SS_Within\u003C/th>\u003Cth>Category SS\u003C/th>\u003Cth>Total SS %\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Step 1\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>32.5\u003C/td>\u003Ctd>2.0\u003C/td>\u003Ctd>412\u003C/td>\u003Ctd>116\u003C/td>\u003Ctd>528\u003C/td>\u003Ctd>\u003Cstrong>7.5%\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Step 2\u003C/strong>\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>39.4\u003C/td>\u003Ctd>8.9\u003C/td>\u003Ctd>306\u003C/td>\u003Ctd>2,393\u003C/td>\u003Ctd>2,699\u003C/td>\u003Ctd>\u003Cstrong>38.3%\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step 3\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>45.1\u003C/td>\u003Ctd>1.5\u003C/td>\u003Ctd>2,355\u003C/td>\u003Ctd>71\u003C/td>\u003Ctd>2,426\u003C/td>\u003Ctd>\u003Cstrong>34.5%\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step 4\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>33.7\u003C/td>\u003Ctd>1.9\u003C/td>\u003Ctd>194\u003C/td>\u003Ctd>104\u003C/td>\u003Ctd>298\u003C/td>\u003Ctd>\u003Cstrong>4.2%\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step 5\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>30.4\u003C/td>\u003Ctd>1.6\u003C/td>\u003Ctd>1,012\u003C/td>\u003Ctd>77\u003C/td>\u003Ctd>1,089\u003C/td>\u003Ctd>\u003Cstrong>15.5%\u003C/strong>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total\u003C/strong>\u003C/td>\u003Ctd>150\u003C/td>\u003Ctd>36.24\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>4,278\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>2,761\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>7,039\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>100%\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>η² for the Step factor = 4,278 / 7,039 = \u003Cstrong>0.61\u003C/strong> (61% of variation explained by step differences).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-key-comparison-step-2-vs-step-3\">The key comparison: Step 2 vs Step 3\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-key-comparison-step-2-vs-step-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The key comparison: Step 2 vs Step 3”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Step 2\u003C/th>\u003Cth>Step 3\u003C/th>\u003Cth>Which looks bigger?\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>SS_Between (mean shift only)\u003C/td>\u003Ctd>306 (4.3%)\u003C/td>\u003Ctd>2,355 (33.5%)\u003C/td>\u003Ctd>Step 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SS_Within (spread only)\u003C/td>\u003Ctd>2,393 (34.0%)\u003C/td>\u003Ctd>71 (1.0%)\u003C/td>\u003Ctd>Step 2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Category Total SS\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>2,699 (38.3%)\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>2,426 (34.5%)\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>Step 2\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>If VariScout used \u003Cstrong>between-group SS\u003C/strong> for the category popover, Step 2 would show just 4.3% contribution — it would look irrelevant. But Step 2 has the highest variance (SD = 8.9 vs the next highest at 2.0), and its inconsistency is what creates the production bottleneck.\u003C/p>\n\u003Cp>\u003Cstrong>Total SS contribution\u003C/strong> correctly shows Step 2 at 38.3% — the single largest contributor to overall variation. This matches the case study finding: Step 2’s unpredictability, not Step 3’s consistently high mean, is the real problem.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-383-means-in-practice\">What 38.3% means in practice\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-383-means-in-practice\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What 38.3% means in practice”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>If you could eliminate Step 2’s excess variation (bring its SD from 8.9 down to the average of other steps, ~1.8), you would remove approximately 34% of the total cycle time variation. Whether this translates to meaningful yield improvement depends on the specification limits — use the What-If Simulator to project the specific Cpk and yield change.\u003C/p>\n\u003Cp>This matches the case study outcome: management was about to invest €50k upgrading Step 3 (highest mean). The variation analysis revealed Step 2 (highest spread) was the real bottleneck. The actual fix was €5k in training and standardized work instructions — a 10× better allocation of resources.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-this-maps-to-the-variscout-ui\">How This Maps to the VariScout UI\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-this-maps-to-the-variscout-ui\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How This Maps to the VariScout UI”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"anova-panel-boxplot-view\">ANOVA panel (Boxplot view)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#anova-panel-boxplot-view\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ANOVA panel (Boxplot view)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shows F-statistic, p-value, and η². These are factor-level metrics that answer “does this factor matter?” η² = 0.61 for Step means 61% of all cycle time variation is explained by which step you measure.\u003C/p>\n\u003Cp>F-test and p-value assume approximately normal data with similar spread across groups. η² and Total SS % are descriptive and do not require these assumptions.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mindmap-suggestion-ranking\">Mindmap suggestion ranking\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mindmap-suggestion-ranking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mindmap suggestion ranking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The green pulse highlights the factor with the highest η² among unexplored factors. This guides the analyst to drill the most impactful factor next.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mindmap-node-circles\">Mindmap node circles\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mindmap-node-circles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mindmap node circles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each available node displays \u003Cstrong>η²\u003C/strong> for that factor — the same metric shown in the ANOVA panel. This answers “how much variation does this factor explain?” at a glance. The node number matches the ANOVA panel number, ensuring cross-view consistency. Drilled (active) nodes show no percentage — they display the filtered value label instead. The category-level detail (Total SS %) is available in the popover.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"category-popover-and-contribution-labels\">Category popover and contribution labels\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#category-popover-and-contribution-labels\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Category popover and contribution labels”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each row shows \u003Cstrong>Category Total SS %\u003C/strong> for every category within the selected factor. These always sum to 100%. The analyst sees exactly how variation is distributed across categories — capturing both mean differences and spread.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"drill-down-filter-chips\">Drill-down filter chips\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#drill-down-filter-chips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill-down filter chips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When the analyst filters (e.g. clicks Step 2), the contribution percentage on the filter chip shows how much of the \u003Cstrong>original\u003C/strong> total variation that filter captures. This keeps the analyst anchored to the original problem throughout the drill-down.\u003C/p>\n\u003Cp>The cumulative percentage represents the fraction of the original total variation captured by your current filter combination. “45% in focus” means your current drill path accounts for 45% of all the variation in the dataset — the remaining 55% comes from data outside your filter selection.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"a-note-on-controllability\">A note on controllability\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#a-note-on-controllability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “A note on controllability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Identifying a variation source is necessary but not sufficient for improvement. Before committing resources, assess whether the source is controllable (can be changed with training, procedure, settings) or structural (requires equipment, material, or design changes). The What-If Simulator helps quantify the potential impact of changes; domain expertise determines feasibility.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"for-the-quality-professional\">For the Quality Professional\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#for-the-quality-professional\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “For the Quality Professional”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>If you’ve completed Six Sigma Green Belt training, you’ve seen one-way ANOVA in the Analyze phase. VariScout uses the same F-test, p-value, and η² — plus one extension at the category level. Here is how VariScout’s metrics map to standard terminology:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Standard ANOVA term\u003C/th>\u003Cth>VariScout equivalent\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>SS_Between / SS_Total\u003C/td>\u003Ctd>η² in ANOVA panel\u003C/td>\u003Ctd>Identical to standard η²\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>MS_Between / MS_Within\u003C/td>\u003Ctd>F-statistic in ANOVA panel\u003C/td>\u003Ctd>Standard F-test\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SS for a specific group\u003C/td>\u003Ctd>Category Total SS %\u003C/td>\u003Ctd>VariScout adds within-group SS to give full picture\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Effect size (η²)\u003C/td>\u003Ctd>Suggestion ranking\u003C/td>\u003Ctd>Used to guide drill-down order\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multi-Vari study\u003C/td>\u003Ctd>Mindmap progressive drill-down\u003C/td>\u003Ctd>VariScout automates the Multi-Vari decomposition: the analyst drills factors one at a time, and the tool quantifies each level’s contribution\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>VariScout extends textbook ANOVA at the \u003Cstrong>category level\u003C/strong>. Textbook ANOVA focuses on the F-test and η² (both factor-level metrics). VariScout extends the decomposition to individual categories by including within-group variation, because the drill-down workflow needs to answer “which category should I investigate?” — a question that between-group SS alone cannot answer reliably.\u003C/p>\n\u003Cp>\u003Cstrong>Confounding:\u003C/strong> One-factor-at-a-time analysis does not account for confounding between factors. If Operator and Shift are correlated (certain operators only work nights), drilling by Shift may capture variation actually caused by Operator. Phase 2 will re-introduce the Mindmap interaction mode and Advanced Regression model to detect and untangle these effects (see \u003Ca href=\"../../05-technical/implementation/phase2-regression-roadmap.md\">Phase 2 Regression Roadmap\u003C/a>).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"limitations-and-assumptions\">Limitations and Assumptions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#limitations-and-assumptions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Limitations and Assumptions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The variation decomposition system is a practical tool for process investigation. Understanding its limitations helps the analyst know when to trust the drill-down and when to move to more rigorous methods.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"path-dependency\">Path dependency\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#path-dependency\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Path dependency”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The drill-down examines one factor at a time. Different drill orders can produce different intermediate percentages — for example, drilling Shift → Operator may show different local scope fractions than Operator → Shift — but they converge on similar cumulative scope. For statistically rigorous joint analysis, the Regression panel planned for Phase 2 will provide correct multi-factor estimates (see \u003Ca href=\"../../05-technical/implementation/phase2-regression-roadmap.md\">Phase 2 Regression Roadmap\u003C/a>). See \u003Ca href=\"../../01-vision/progressive-stratification.md\">Progressive Stratification\u003C/a> Part 2 for a detailed treatment of this tension.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"confounding-and-correlated-factors\">Confounding and correlated factors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#confounding-and-correlated-factors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Confounding and correlated factors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Real process data is rarely orthogonal. When factors are correlated (operator × shift, material × supplier), one-factor ANOVA misattributes variation. The drill-down can lead to incorrect factor prioritization. Phase 2 will re-introduce the Mindmap interaction mode as an early signal and the Advanced Regression model for the correct joint estimate (see \u003Ca href=\"../../05-technical/implementation/phase2-regression-roadmap.md\">Phase 2 Regression Roadmap\u003C/a>).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cumulative-scope-approximation\">Cumulative scope approximation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cumulative-scope-approximation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cumulative scope approximation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The cumulative scope percentage (the “in focus” number on drill-down chips) is the multiplicative product of local scope fractions through the drill path. This is an intuitive “funnel” metaphor, not a statistically grounded quantity. It treats each drill level’s local scope as independent, which fails when factors are correlated. The regression model planned for Phase 2 will provide the correct joint estimate of explained variation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"when-to-transition-beyond-drill-down\">When to transition beyond drill-down\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-transition-beyond-drill-down\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to transition beyond drill-down”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use the drill-down for initial investigation (3–5 minutes). If you suspect interactions, have confounded factors, or need a formal model for projection, use the What-If Simulator to test scenarios with direct adjustments. Advanced Regression (planned for Phase 2) will provide formal multi-factor modelling and an automated handoff from the Mindmap — see \u003Ca href=\"../../05-technical/implementation/phase2-regression-roadmap.md\">Phase 2 Regression Roadmap\u003C/a>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"presenting-results\">Presenting Results\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#presenting-results\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Presenting Results”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When presenting variation findings to stakeholders, translate statistical metrics to business terms:\u003C/p>\n\u003Cul>\n\u003Cli>Instead of “Step 2 contributes 38.3% of Total SS,” say “Step 2’s inconsistency accounts for the largest share of cycle time variation.”\u003C/li>\n\u003Cli>Instead of “η² = 0.61 for Process Step,” say “Which step the product is at explains 61% of the variation we see.”\u003C/li>\n\u003Cli>Use the What-If Simulator to generate specific before/after projections: “Reducing Step 2’s spread from 8.9 to 2.0 seconds would improve overall process capability from Cpk X to Cpk Y.”\u003C/li>\n\u003C/ul>\n\u003Cp>The chart copy and export features (clipboard, PNG, SVG) produce presentation-ready visuals that can be pasted directly into tollgate reviews and improvement reports.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"references\">References\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>NIST/SEMATECH e-Handbook of Statistical Methods, Section 7.4.3.2 — One-Way ANOVA\u003C/li>\n\u003Cli>Montgomery, D.C. \u003Cem>Introduction to Statistical Quality Control\u003C/em> (8th ed.), Chapter 13\u003C/li>\n\u003Cli>VariScout implementation: \u003Ccode dir=\"auto\">packages/core/src/stats/anova.ts\u003C/code> (ANOVA), \u003Ccode dir=\"auto\">packages/core/src/variation/contributions.ts\u003C/code> (category decomposition)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-references\">Cross-references\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-references”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Topic\u003C/th>\u003Cth>Document\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>UX rationale for drill-down\u003C/td>\u003Ctd>\u003Ca href=\"../../01-vision/progressive-stratification.md\">Progressive Stratification\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Investigation workflow (Mindmap, Regression, What-If)\u003C/td>\u003Ctd>\u003Ca href=\"../workflows/investigation-to-action.md\">Investigation to Action\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot ANOVA display\u003C/td>\u003Ctd>\u003Ca href=\"boxplot.md\">Boxplot\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Category contribution labels\u003C/td>\u003Ctd>\u003Ca href=\"boxplot.md\">Boxplot\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regression and interaction analysis\u003C/td>\u003Ctd>\u003Ca href=\"regression.md\">Regression\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Glossary: η², Total SS Contribution\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/glossary/terms.ts\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 6768, + "localImagePaths": 6844, + "remoteImagePaths": 6845, + "frontmatter": 6846, + "imagePaths": 6847 + }, + [ + 6769, 6771, 6774, 6777, 6780, 6783, 6786, 6789, 6792, 6795, 6798, 6801, 6804, 6807, 6810, 6813, + 6816, 6819, 6822, 6825, 6828, 6831, 6834, 6837, 6840, 6841 + ], + { "depth": 30, "slug": 6770, "text": 6758 }, + "variation-decomposition", + { "depth": 33, "slug": 6772, "text": 6773 }, + "the-anova-identity", + "The ANOVA Identity", + { "depth": 79, "slug": 6775, "text": 6776 }, + "category-level-decomposition", + "Category-level decomposition", + { "depth": 33, "slug": 6778, "text": 6779 }, + "three-metrics-three-questions", + "Three Metrics, Three Questions", + { "depth": 79, "slug": 6781, "text": 6782 }, + "why-η-for-factor-ranking", + "Why η² for factor ranking", + { "depth": 79, "slug": 6784, "text": 6785 }, + "why-total-ss-not-between-group-for-category-contribution", + "Why Total SS (not between-group) for category contribution", + { "depth": 33, "slug": 6787, "text": 6788 }, + "worked-example-bottleneck-data", + "Worked Example: Bottleneck Data", + { "depth": 79, "slug": 6790, "text": 6791 }, + "step-level-decomposition", + "Step-level decomposition", + { "depth": 79, "slug": 6793, "text": 6794 }, + "the-key-comparison-step-2-vs-step-3", + "The key comparison: Step 2 vs Step 3", + { "depth": 79, "slug": 6796, "text": 6797 }, + "what-383-means-in-practice", + "What 38.3% means in practice", + { "depth": 33, "slug": 6799, "text": 6800 }, + "how-this-maps-to-the-variscout-ui", + "How This Maps to the VariScout UI", + { "depth": 79, "slug": 6802, "text": 6803 }, + "anova-panel-boxplot-view", + "ANOVA panel (Boxplot view)", + { "depth": 79, "slug": 6805, "text": 6806 }, + "mindmap-suggestion-ranking", + "Mindmap suggestion ranking", + { "depth": 79, "slug": 6808, "text": 6809 }, + "mindmap-node-circles", + "Mindmap node circles", + { "depth": 79, "slug": 6811, "text": 6812 }, + "category-popover-and-contribution-labels", + "Category popover and contribution labels", + { "depth": 79, "slug": 6814, "text": 6815 }, + "drill-down-filter-chips", + "Drill-down filter chips", + { "depth": 79, "slug": 6817, "text": 6818 }, + "a-note-on-controllability", + "A note on controllability", + { "depth": 33, "slug": 6820, "text": 6821 }, + "for-the-quality-professional", + "For the Quality Professional", + { "depth": 33, "slug": 6823, "text": 6824 }, + "limitations-and-assumptions", + "Limitations and Assumptions", + { "depth": 79, "slug": 6826, "text": 6827 }, + "path-dependency", + "Path dependency", + { "depth": 79, "slug": 6829, "text": 6830 }, + "confounding-and-correlated-factors", + "Confounding and correlated factors", + { "depth": 79, "slug": 6832, "text": 6833 }, + "cumulative-scope-approximation", + "Cumulative scope approximation", + { "depth": 79, "slug": 6835, "text": 6836 }, + "when-to-transition-beyond-drill-down", + "When to transition beyond drill-down", + { "depth": 33, "slug": 6838, "text": 6839 }, + "presenting-results", + "Presenting Results", + { "depth": 33, "slug": 878, "text": 879 }, + { "depth": 33, "slug": 6842, "text": 6843 }, + "cross-references", + "Cross-references", + [], + [], + { "title": 6758 }, + [], + "03-features/data/storage", + { "id": 6848, "data": 6850, "body": 6855, "filePath": 6856, "digest": 6857, "rendered": 6858 }, + { + "title": 6851, + "editUrl": 16, + "head": 6852, + "template": 18, + "sidebar": 6853, + "pagefind": 16, + "draft": 20 + }, + "Project Persistence", + [], + { "hidden": 20, "attrs": 6854 }, + {}, + "# Project Persistence\n\nHow VariScout saves and restores analyst workflow state.\n\n---\n\n## Overview\n\n| Product | Persistence Model | File Format |\n| --------- | -------------------------------------- | ----------- |\n| PWA | Session-only (React state, no storage) | N/A |\n| Azure App | IndexedDB + OneDrive sync (.vrs JSON) | `.vrs` |\n\nThe PWA is a free training tool — data lives in memory and is lost on page refresh. The Azure App persists full project state to IndexedDB (instant) and syncs to OneDrive (background).\n\n---\n\n## AnalysisState Contract\n\nEvery `.vrs` file contains an `AnalysisState` object. All fields marked optional use the listed default when absent (backward compatibility with older files).\n\n### Core Data\n\n| Field | Type | Default | Notes |\n| -------------- | ----------------------------------------- | ------- | --------------------------- |\n| `version` | `string` | — | Schema version |\n| `rawData` | `DataRow[]` | — | Full dataset (required) |\n| `outcome` | `string \\| null` | — | Y variable column name |\n| `factors` | `string[]` | — | Selected factor columns |\n| `specs` | `{ usl?, lsl?, target? }` | `{}` | Global specification limits |\n| `measureSpecs` | `Record\u003Cstring, { usl?, lsl?, target? }>` | `{}` | Per-measure spec overrides |\n\n### Filters\n\n| Field | Type | Default | Notes |\n| ------------- | ------------------------------------ | ------- | ------------------------------------------------- |\n| `filters` | `Record\u003Cstring, (string\\|number)[]>` | `{}` | Flat filter map (always present) |\n| `filterStack` | `FilterAction[]` | `[]` | Ordered drill trail for breadcrumb reconstruction |\n\nWhen `filterStack` is present, flat `filters` are derived from it on load. When absent (old `.vrs`), flat `filters` are used directly — breadcrumbs will be empty but data filtering works.\n\n### Display Options\n\n| Field | Type | Default | Notes |\n| ---------------- | ---------------- | ----------- | -------------------------------- |\n| `displayOptions` | `DisplayOptions` | (see below) | Toggles, annotations, highlights |\n\n`DisplayOptions` includes: `lockYAxisToFullData` (true), `showControlLimits` (true), `showViolin` (false), `showFilterContext` (true), `showSpecs` (true), `showCpk` (true), boxplot sort/highlights, pareto highlights, chart annotations (boxplot, pareto, I-Chart), and mindmap step annotations.\n\n### Settings\n\n| Field | Type | Default | Notes |\n| --------------- | ---------------------------------------- | ------- | --------------------------------------------- |\n| `axisSettings` | `{ min?, max?, scaleMode? }` | `{}` | Y-axis configuration |\n| `columnAliases` | `Record\u003Cstring, string>` | `{}` | Renamed column display names |\n| `valueLabels` | `Record\u003Cstring, Record\u003Cstring, string>>` | `{}` | Custom value labels |\n| `chartTitles` | `ChartTitles` | `{}` | Custom chart names (I-Chart, Boxplot, Pareto) |\n\n### Workflow State\n\n| Field | Type | Default | Notes |\n| ------------------- | ---------------- | ----------- | ------------------------------ |\n| `cpkTarget` | `number` | `1.33` | Performance Mode Cpk threshold |\n| `stageColumn` | `string \\| null` | `null` | Staged analysis column |\n| `stageOrderMode` | `StageOrderMode` | `'auto'` | Stage ordering |\n| `isPerformanceMode` | `boolean` | `false` | Performance Mode active |\n| `measureColumns` | `string[]` | `[]` | Selected measurement channels |\n| `selectedMeasure` | `string \\| null` | `null` | Active channel drill |\n| `measureLabel` | `string` | `'Measure'` | Measure axis label |\n\n### Regression State\n\n| Field | Type | Default | Notes |\n| ----------------- | ---------------------------- | ----------- | ------------------------------------- |\n| `regressionState` | `RegressionPersistenceState` | `undefined` | Regression panel selections + history |\n\n`RegressionPersistenceState` includes: `mode` ('simple' | 'advanced'), `selectedXColumns`, `advSelectedPredictors`, `categoricalColumns` (Set serialized as array), `includeInteractions`, `reductionHistory` (guided model reduction trail), and `dataRowCount` (row count at time of model fitting — used to detect data staleness). The regression model itself recomputes from data + predictors — only selections are persisted.\n\n### View State\n\n| Field | Type | Default | Notes |\n| ----------- | ----------- | ----------- | ----------------------------- |\n| `viewState` | `ViewState` | `undefined` | Where the analyst was working |\n\n`ViewState` includes: `activeTab` ('analysis' | 'performance'), `isFindingsOpen`, `isWhatIfOpen`, `focusedChart` ('ichart' | 'boxplot' | 'pareto' | null), `boxplotFactor`, `paretoFactor`, `findingsViewMode`. Captures the analyst's working position so reload resumes their context.\n\n---\n\n## What's NOT Saved (by Design)\n\nThese are ephemeral UI states that reset on each session:\n\n- What-If simulator slider positions\n- Point selections (Minitab-style brushing)\n- Data quality report (recomputed from raw data)\n- Investigation mindmap computation (recomputes from drill path + data)\n\n---\n\n## Save / Load Flow\n\n```\nSave:\n getCurrentState() → AnalysisState JSON → IndexedDB → OneDrive (.vrs)\n\nLoad:\n .vrs JSON → loadProject() → set all state fields → UI renders\n```\n\n`getCurrentState()` only includes non-default values for compact serialization. `loadProject()` guards every optional field with `state.xxx ?? default` for backward compatibility.\n\n---\n\n## Export / Import\n\n| Format | Contains | Use Case |\n| ------ | -------------------------------- | -------------------- |\n| `.vrs` | Full AnalysisState (JSON) | Project backup/share |\n| `.csv` | Raw data only (via downloadCSV) | Data portability |\n| `.png` | Chart screenshot (2x resolution) | Reports |\n| `.svg` | Chart vector export | Print/presentations |\n\n---\n\n## Backward Compatibility\n\nOld `.vrs` files load without error. Every new field is optional with a safe default:\n\n- Missing `filterStack` → breadcrumbs empty, flat `filters` still work\n- Missing `regressionState` → fresh regression panel\n- Missing `viewState` → Analysis tab, all panels closed\n- Missing `cpkTarget` → defaults to 1.33\n- Missing Performance Mode fields → Performance Mode off\n\n---\n\n## Data Evolution\n\nWhat happens to persisted state when data changes mid-analysis:\n\n| Change | filterStack | regressionState | viewState | specs |\n| ------------- | ----------- | ------------------------------ | ----------------- | ----- |\n| Edit cells | valid | stale (indicator shown) | valid | valid |\n| Append rows | valid | stale (indicator shown) | valid | valid |\n| Add columns | valid | valid | valid | valid |\n| Add factor | valid | valid | valid | valid |\n| Remove factor | cleaned | valid (predictors auto-remove) | factor refs reset | valid |\n\n**Staleness strategy:**\n\n- **Additive changes** (add rows, add columns, add factors): no invalidation. New data is available, old analysis stays valid.\n- **Subtractive changes** (remove factor): clean dependent state (filterStack, viewState factor refs).\n- **Mutation changes** (edit cells, add rows): regression model becomes stale. Amber indicator shown, model not auto-cleared.\n\n---\n\n## Privacy\n\n- **All data stays local** — never sent to VariScout servers\n- **No telemetry** — no usage tracking\n- **OneDrive sync** — data syncs to user's own OneDrive (Azure App only)\n- **Clear = Gone** — clearing browser data deletes local projects\n\n---\n\n## See Also\n\n- [OneDrive Sync](../../08-products/azure/onedrive-sync.md) — Azure-specific sync mechanism\n- [Offline-First Architecture](../../05-technical/architecture/offline-first.md) — Technical approach\n- [PWA Session Model](../../08-products/pwa/storage.md) — Why the PWA doesn't persist", + "src/content/docs/03-features/data/storage.md", + "bfa0e86621f7da09", + { "html": 6859, "metadata": 6860 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"project-persistence\">Project Persistence\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#project-persistence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Project Persistence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How VariScout saves and restores analyst workflow state.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth>Persistence Model\u003C/th>\u003Cth>File Format\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA\u003C/td>\u003Ctd>Session-only (React state, no storage)\u003C/td>\u003Ctd>N/A\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure App\u003C/td>\u003Ctd>IndexedDB + OneDrive sync (.vrs JSON)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">.vrs\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The PWA is a free training tool — data lives in memory and is lost on page refresh. The Azure App persists full project state to IndexedDB (instant) and syncs to OneDrive (background).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysisstate-contract\">AnalysisState Contract\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysisstate-contract\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “AnalysisState Contract”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every \u003Ccode dir=\"auto\">.vrs\u003C/code> file contains an \u003Ccode dir=\"auto\">AnalysisState\u003C/code> object. All fields marked optional use the listed default when absent (backward compatibility with older files).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-data\">Core Data\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Data”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Field\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">version\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string\u003C/code>\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Schema version\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">rawData\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code>\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Full dataset (required)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">outcome\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string | null\u003C/code>\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Y variable column name\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">factors\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string[]\u003C/code>\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Selected factor columns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">specs\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{ usl?, lsl?, target? }\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{}\u003C/code>\u003C/td>\u003Ctd>Global specification limits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">measureSpecs\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Record<string, { usl?, lsl?, target? }>\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{}\u003C/code>\u003C/td>\u003Ctd>Per-measure spec overrides\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filters\">Filters\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filters”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Field\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">filters\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Record<string, (string|number)[]>\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{}\u003C/code>\u003C/td>\u003Ctd>Flat filter map (always present)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">filterStack\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FilterAction[]\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">[]\u003C/code>\u003C/td>\u003Ctd>Ordered drill trail for breadcrumb reconstruction\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>When \u003Ccode dir=\"auto\">filterStack\u003C/code> is present, flat \u003Ccode dir=\"auto\">filters\u003C/code> are derived from it on load. When absent (old \u003Ccode dir=\"auto\">.vrs\u003C/code>), flat \u003Ccode dir=\"auto\">filters\u003C/code> are used directly — breadcrumbs will be empty but data filtering works.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-options\">Display Options\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-options\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Options”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Field\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">displayOptions\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DisplayOptions\u003C/code>\u003C/td>\u003Ctd>(see below)\u003C/td>\u003Ctd>Toggles, annotations, highlights\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Ccode dir=\"auto\">DisplayOptions\u003C/code> includes: \u003Ccode dir=\"auto\">lockYAxisToFullData\u003C/code> (true), \u003Ccode dir=\"auto\">showControlLimits\u003C/code> (true), \u003Ccode dir=\"auto\">showViolin\u003C/code> (false), \u003Ccode dir=\"auto\">showFilterContext\u003C/code> (true), \u003Ccode dir=\"auto\">showSpecs\u003C/code> (true), \u003Ccode dir=\"auto\">showCpk\u003C/code> (true), boxplot sort/highlights, pareto highlights, chart annotations (boxplot, pareto, I-Chart), and mindmap step annotations.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"settings\">Settings\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#settings\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Settings”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Field\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">axisSettings\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{ min?, max?, scaleMode? }\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{}\u003C/code>\u003C/td>\u003Ctd>Y-axis configuration\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">columnAliases\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Record<string, string>\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{}\u003C/code>\u003C/td>\u003Ctd>Renamed column display names\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">valueLabels\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Record<string, Record<string, string>>\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{}\u003C/code>\u003C/td>\u003Ctd>Custom value labels\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">chartTitles\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ChartTitles\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{}\u003C/code>\u003C/td>\u003Ctd>Custom chart names (I-Chart, Boxplot, Pareto)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"workflow-state\">Workflow State\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#workflow-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow State”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Field\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">cpkTarget\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">1.33\u003C/code>\u003C/td>\u003Ctd>Performance Mode Cpk threshold\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stageColumn\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string | null\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">null\u003C/code>\u003C/td>\u003Ctd>Staged analysis column\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stageOrderMode\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">StageOrderMode\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">'auto'\u003C/code>\u003C/td>\u003Ctd>Stage ordering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">isPerformanceMode\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">boolean\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">false\u003C/code>\u003C/td>\u003Ctd>Performance Mode active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">measureColumns\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string[]\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">[]\u003C/code>\u003C/td>\u003Ctd>Selected measurement channels\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">selectedMeasure\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string | null\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">null\u003C/code>\u003C/td>\u003Ctd>Active channel drill\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">measureLabel\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">'Measure'\u003C/code>\u003C/td>\u003Ctd>Measure axis label\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"regression-state\">Regression State\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#regression-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Regression State”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Field\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">regressionState\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">RegressionPersistenceState\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">undefined\u003C/code>\u003C/td>\u003Ctd>Regression panel selections + history\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Ccode dir=\"auto\">RegressionPersistenceState\u003C/code> includes: \u003Ccode dir=\"auto\">mode\u003C/code> (‘simple’ | ‘advanced’), \u003Ccode dir=\"auto\">selectedXColumns\u003C/code>, \u003Ccode dir=\"auto\">advSelectedPredictors\u003C/code>, \u003Ccode dir=\"auto\">categoricalColumns\u003C/code> (Set serialized as array), \u003Ccode dir=\"auto\">includeInteractions\u003C/code>, \u003Ccode dir=\"auto\">reductionHistory\u003C/code> (guided model reduction trail), and \u003Ccode dir=\"auto\">dataRowCount\u003C/code> (row count at time of model fitting — used to detect data staleness). The regression model itself recomputes from data + predictors — only selections are persisted.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"view-state\">View State\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#view-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “View State”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Field\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">viewState\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ViewState\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">undefined\u003C/code>\u003C/td>\u003Ctd>Where the analyst was working\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Ccode dir=\"auto\">ViewState\u003C/code> includes: \u003Ccode dir=\"auto\">activeTab\u003C/code> (‘analysis’ | ‘performance’), \u003Ccode dir=\"auto\">isFindingsOpen\u003C/code>, \u003Ccode dir=\"auto\">isWhatIfOpen\u003C/code>, \u003Ccode dir=\"auto\">focusedChart\u003C/code> (‘ichart’ | ‘boxplot’ | ‘pareto’ | null), \u003Ccode dir=\"auto\">boxplotFactor\u003C/code>, \u003Ccode dir=\"auto\">paretoFactor\u003C/code>, \u003Ccode dir=\"auto\">findingsViewMode\u003C/code>. Captures the analyst’s working position so reload resumes their context.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whats-not-saved-by-design\">What’s NOT Saved (by Design)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whats-not-saved-by-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What’s NOT Saved (by Design)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These are ephemeral UI states that reset on each session:\u003C/p>\n\u003Cul>\n\u003Cli>What-If simulator slider positions\u003C/li>\n\u003Cli>Point selections (Minitab-style brushing)\u003C/li>\n\u003Cli>Data quality report (recomputed from raw data)\u003C/li>\n\u003Cli>Investigation mindmap computation (recomputes from drill path + data)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"save--load-flow\">Save / Load Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#save--load-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Save / Load Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Save:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">getCurrentState() → AnalysisState JSON → IndexedDB → OneDrive (.vrs)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Load:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">.vrs JSON → loadProject() → set all state fields → UI renders\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Save: getCurrentState() → AnalysisState JSON → IndexedDB → OneDrive (.vrs)Load: .vrs JSON → loadProject() → set all state fields → UI renders\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">getCurrentState()\u003C/code> only includes non-default values for compact serialization. \u003Ccode dir=\"auto\">loadProject()\u003C/code> guards every optional field with \u003Ccode dir=\"auto\">state.xxx ?? default\u003C/code> for backward compatibility.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"export--import\">Export / Import\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#export--import\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Export / Import”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Format\u003C/th>\u003Cth>Contains\u003C/th>\u003Cth>Use Case\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">.vrs\u003C/code>\u003C/td>\u003Ctd>Full AnalysisState (JSON)\u003C/td>\u003Ctd>Project backup/share\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">.csv\u003C/code>\u003C/td>\u003Ctd>Raw data only (via downloadCSV)\u003C/td>\u003Ctd>Data portability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">.png\u003C/code>\u003C/td>\u003Ctd>Chart screenshot (2x resolution)\u003C/td>\u003Ctd>Reports\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">.svg\u003C/code>\u003C/td>\u003Ctd>Chart vector export\u003C/td>\u003Ctd>Print/presentations\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"backward-compatibility\">Backward Compatibility\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#backward-compatibility\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Backward Compatibility”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Old \u003Ccode dir=\"auto\">.vrs\u003C/code> files load without error. Every new field is optional with a safe default:\u003C/p>\n\u003Cul>\n\u003Cli>Missing \u003Ccode dir=\"auto\">filterStack\u003C/code> → breadcrumbs empty, flat \u003Ccode dir=\"auto\">filters\u003C/code> still work\u003C/li>\n\u003Cli>Missing \u003Ccode dir=\"auto\">regressionState\u003C/code> → fresh regression panel\u003C/li>\n\u003Cli>Missing \u003Ccode dir=\"auto\">viewState\u003C/code> → Analysis tab, all panels closed\u003C/li>\n\u003Cli>Missing \u003Ccode dir=\"auto\">cpkTarget\u003C/code> → defaults to 1.33\u003C/li>\n\u003Cli>Missing Performance Mode fields → Performance Mode off\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-evolution\">Data Evolution\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-evolution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Evolution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>What happens to persisted state when data changes mid-analysis:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Change\u003C/th>\u003Cth>filterStack\u003C/th>\u003Cth>regressionState\u003C/th>\u003Cth>viewState\u003C/th>\u003Cth>specs\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Edit cells\u003C/td>\u003Ctd>valid\u003C/td>\u003Ctd>stale (indicator shown)\u003C/td>\u003Ctd>valid\u003C/td>\u003Ctd>valid\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Append rows\u003C/td>\u003Ctd>valid\u003C/td>\u003Ctd>stale (indicator shown)\u003C/td>\u003Ctd>valid\u003C/td>\u003Ctd>valid\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Add columns\u003C/td>\u003Ctd>valid\u003C/td>\u003Ctd>valid\u003C/td>\u003Ctd>valid\u003C/td>\u003Ctd>valid\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Add factor\u003C/td>\u003Ctd>valid\u003C/td>\u003Ctd>valid\u003C/td>\u003Ctd>valid\u003C/td>\u003Ctd>valid\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Remove factor\u003C/td>\u003Ctd>cleaned\u003C/td>\u003Ctd>valid (predictors auto-remove)\u003C/td>\u003Ctd>factor refs reset\u003C/td>\u003Ctd>valid\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Staleness strategy:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Additive changes\u003C/strong> (add rows, add columns, add factors): no invalidation. New data is available, old analysis stays valid.\u003C/li>\n\u003Cli>\u003Cstrong>Subtractive changes\u003C/strong> (remove factor): clean dependent state (filterStack, viewState factor refs).\u003C/li>\n\u003Cli>\u003Cstrong>Mutation changes\u003C/strong> (edit cells, add rows): regression model becomes stale. Amber indicator shown, model not auto-cleared.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"privacy\">Privacy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#privacy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Privacy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>All data stays local\u003C/strong> — never sent to VariScout servers\u003C/li>\n\u003Cli>\u003Cstrong>No telemetry\u003C/strong> — no usage tracking\u003C/li>\n\u003Cli>\u003Cstrong>OneDrive sync\u003C/strong> — data syncs to user’s own OneDrive (Azure App only)\u003C/li>\n\u003Cli>\u003Cstrong>Clear = Gone\u003C/strong> — clearing browser data deletes local projects\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../08-products/azure/onedrive-sync.md\">OneDrive Sync\u003C/a> — Azure-specific sync mechanism\u003C/li>\n\u003Cli>\u003Ca href=\"../../05-technical/architecture/offline-first.md\">Offline-First Architecture\u003C/a> — Technical approach\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/pwa/storage.md\">PWA Session Model\u003C/a> — Why the PWA doesn’t persist\u003C/li>\n\u003C/ul>", + { + "headings": 6861, + "localImagePaths": 6906, + "remoteImagePaths": 6907, + "frontmatter": 6908, + "imagePaths": 6909 + }, + [ + 6862, 6864, 6865, 6868, 6871, 6874, 6877, 6878, 6881, 6884, 6887, 6890, 6893, 6896, 6899, 6902, + 6905 + ], + { "depth": 30, "slug": 6863, "text": 6851 }, + "project-persistence", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 6866, "text": 6867 }, + "analysisstate-contract", + "AnalysisState Contract", + { "depth": 79, "slug": 6869, "text": 6870 }, + "core-data", + "Core Data", + { "depth": 79, "slug": 6872, "text": 6873 }, + "filters", + "Filters", + { "depth": 79, "slug": 6875, "text": 6876 }, + "display-options", + "Display Options", + { "depth": 79, "slug": 4099, "text": 4100 }, + { "depth": 79, "slug": 6879, "text": 6880 }, + "workflow-state", + "Workflow State", + { "depth": 79, "slug": 6882, "text": 6883 }, + "regression-state", + "Regression State", + { "depth": 79, "slug": 6885, "text": 6886 }, + "view-state", + "View State", + { "depth": 33, "slug": 6888, "text": 6889 }, + "whats-not-saved-by-design", + "What’s NOT Saved (by Design)", + { "depth": 33, "slug": 6891, "text": 6892 }, + "save--load-flow", + "Save / Load Flow", + { "depth": 33, "slug": 6894, "text": 6895 }, + "export--import", + "Export / Import", + { "depth": 33, "slug": 6897, "text": 6898 }, + "backward-compatibility", + "Backward Compatibility", + { "depth": 33, "slug": 6900, "text": 6901 }, + "data-evolution", + "Data Evolution", + { "depth": 33, "slug": 6903, "text": 6904 }, + "privacy", + "Privacy", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6851 }, + [], + "03-features/data/data-input", + { "id": 6910, "data": 6912, "body": 6916, "filePath": 6917, "digest": 6918, "rendered": 6919 }, + { + "title": 975, + "editUrl": 16, + "head": 6913, + "template": 18, + "sidebar": 6914, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 6915 }, + {}, + "# Data Input\n\n\u003C!-- journey-phase: frame -->\n\nHow VariScout handles data input — paste (PWA and Azure App) and file upload (Azure App).\n\n---\n\n## Supported Formats\n\n| Format | Extension | Notes |\n| ------ | ----------- | ---------------------------- |\n| CSV | .csv | Comma or semicolon delimited |\n| Excel | .xlsx, .xls | First sheet used |\n| TSV | .tsv | Tab delimited |\n\n---\n\n## Column Detection\n\nVariScout auto-detects column types and displays them as **colored type badges** in the ColumnMapping screen:\n\n| Type | Detection | Badge Color |\n| --------------- | ------------------------------------ | ----------- |\n| Numeric measure | All values are numbers | Blue |\n| Date/time | Parseable date formats | Amber |\n| Categorical | Repeated string values | Green |\n| Identifier | Unique values (ignored for analysis) | Slate |\n\n---\n\n## Required Columns\n\n| Column Type | Required? | Purpose |\n| ----------- | ---------------- | ----------------------- |\n| Measure | Yes (at least 1) | Values to analyze |\n| Factor | No | Categories for grouping |\n| Date/Time | No | Time-series ordering |\n\n---\n\n## Auto-Mapping\n\nKeywords trigger automatic column assignment:\n\n| Keywords | Maps To |\n| ------------------------------ | -------------------- |\n| \"value\", \"measure\", \"result\" | Measure column |\n| \"shift\", \"machine\", \"operator\" | Factor columns |\n| \"date\", \"time\", \"timestamp\" | Time column |\n| \"usl\", \"lsl\", \"target\", \"spec\" | Specification values |\n\n---\n\n## Paste Flow (PWA and Azure App)\n\nBoth the PWA and Azure App support paste input — users paste tab- or comma-separated text from Excel or Google Sheets.\n\n```\nTEXT PASTED\n │\n ▼\nPARSE (tab/comma auto-detected via parseText())\n │\n ▼\nDETECT COLUMNS (type, sample values, unique count, missing count via detectColumns())\n │\n ▼\nVALIDATE DATA\n │\n ▼\nTIME EXTRACTION (if date column detected)\n │\n ▼\nUSER CONFIRMS/ADJUSTS MAPPING (ColumnMapping with data-rich cards)\n │\n ▼\nLOAD INTO ANALYSIS\n```\n\nThe paste flow uses the same `parseText()` → `detectColumns()` → `ColumnMapping` pipeline as file upload. Tab and comma delimiters are auto-detected. The only difference is `maxFactors`: PWA allows 3 factors, Azure allows 6. The PWA HomeScreen also offers sample datasets as an alternative entry point.\n\n`PasteScreenBase` accepts optional `title` and `submitLabel` props, allowing the Azure \"Add Data\" flow to reuse the same component with contextual labels (e.g., \"Paste Data to Add\" / \"Add Data\").\n\n### ColumnMapping Features\n\nThe ColumnMapping component displays detected columns as **data-rich cards** with:\n\n- **Type-separated sections**: The Y (Outcome) section shows numeric columns by default; the X (Factors) section shows categorical and date columns. A **\"Show all columns\"** toggle lets users see all columns in either section (useful when a numeric column needs to be treated as a factor).\n- **Data-rich cards**: Each column card shows a colored type badge (Numeric/Categorical/Date/Text), 3–4 sample values from the data, unique or category count (≤10 unique values shows \"N categories\", >10 shows \"N unique\"), and an amber warning icon when missing values are detected.\n- **Column renaming**: A pencil icon on each card opens an inline text input. Press Enter or click away to save the alias. The original column name appears as a subtitle. Aliases persist through the analysis — filter chips, chart axes, and breadcrumbs all use the renamed label.\n- **Collapsible data preview**: A \"Preview Data\" toggle expands a mini table showing the first 5 rows with color-coded column headers (blue for numeric, green for categorical, amber for date, slate for text) and a row/column summary.\n- **Specification limits**: An optional collapsible **\"Set Specification Limits\"** section (Target, LSL, USL) at the bottom, collapsed by default. Users who already know their spec limits can expand it and enter values before proceeding to analysis — values auto-apply on blur and carry through to the dashboard.\n\n### Time Factor Extraction\n\nWhen a date or datetime column is detected during column mapping, the **TimeExtractionPanel** appears inside the ColumnMapping screen. This lets users extract temporal factors from date columns for drill-down analysis (e.g., \"Does performance vary by day of week?\" or \"Are there monthly trends?\").\n\n**Checkboxes:**\n\n| Factor | Default | Description |\n| ----------- | ------- | --------------------------- |\n| Year | On | 4-digit year (e.g., 2026) |\n| Month | On | Month name (e.g., January) |\n| Week | Off | ISO week number |\n| Day of Week | On | Weekday name (e.g., Monday) |\n| Hour | Off\\* | Hour of day (0–23) |\n\n\\* Hour is auto-enabled when the data contains time components (timestamps with `T` or `:`).\n\n**Result:** New factor columns are added to the dataset (e.g., `Date_Year`, `Date_Month`, `Date_DayOfWeek`) and appear as available factors for drill-down analysis.\n\n**Availability:** Both PWA and Azure App.\n\n**Technical details:** Uses `augmentWithTimeColumns()` from `@variscout/core/time.ts`. See [Technical: Data Input](../../05-technical/implementation/data-input.md) for the extraction pipeline.\n\n---\n\n## Data Table Editor (PWA and Azure App)\n\nBoth the PWA and Azure App include an inline **Data Table Editor** for correcting or extending data without re-importing.\n\n### How to Open\n\n- **PWA**: Click the **Data Table** button in the toolbar header\n- **Azure App**: Click the **Pencil** icon in the toolbar, or the pencil icon in the DataPanel header\n\n### Features\n\n| Feature | Description |\n| -------------------------------- | -------------------------------------------------------------------------------- |\n| **Cell editing** | Click any cell to edit its value inline |\n| **Keyboard navigation** | Tab (next cell), Shift+Tab (previous), Enter (save + move down), Escape (cancel) |\n| **Add row** | Adds a new empty row at the bottom |\n| **Delete row** | Trash icon on each row |\n| **Spec status** | Outcome column shows PASS/USL/LSL badges |\n| **Excluded row indicators** | Amber warning icon with hover tooltip |\n| **Control violation indicators** | Red icon for UCL/LCL and Nelson Rule violations (Azure) |\n| **Column aliases** | Displays renamed column headers (Azure) |\n| **Pagination** | Automatic for datasets > 500 rows |\n\n### Batch Save Workflow\n\nEdits are made on a **local copy** of the data. Nothing changes until you click **Apply Changes**:\n\n1. Open the Data Table Editor\n2. Make edits (cells, add rows, delete rows)\n3. A **(unsaved changes)** indicator appears in the header\n4. Click **Apply Changes** to commit all edits at once — charts update immediately\n5. Or click **Cancel** to discard all changes\n\n---\n\n## Add Data During Analysis (Azure App)\n\nThe Azure App's \"Add Data\" dropdown lets analysts bring in additional data without restarting the analysis. It appears in the Editor toolbar header once data is loaded.\n\n### Three Options\n\n| Option | Source | Notes |\n| ---------------- | -------------------------- | ----------------------------------------------- |\n| **Paste Data** | Clipboard (tab/comma) | Opens PasteScreenBase with append-context label |\n| **Upload File** | CSV or Excel file | Same parse pipeline as initial upload |\n| **Manual Entry** | Keyboard (ManualEntryBase) | Opens the manual entry grid |\n\n### Auto-Detection (Merge Strategy)\n\nWhen new data arrives, `useDataMerge` determines the merge strategy automatically via `detectMergeStrategy()`:\n\n| Condition | Strategy | Behavior |\n| -------------------------------- | --------------- | ---------------------------------------------------- |\n| All columns match existing data | **Append rows** | New rows concatenated; column union filled with null |\n| New columns detected | **Add columns** | Index-aligned join; shorter side padded with null |\n| No overlap / completely new data | **Replace** | Confirmation dialog before replacing current dataset |\n\n- **Row append**: concat existing + new rows, union of all columns, missing values filled with `null`.\n- **Column merge**: index-aligned join (row 0 ↔ row 0), shorter side padded with `null`.\n- **After adding columns**: ColumnMapping is shown for the new columns so the analyst can assign roles (factor, outcome, etc.).\n- **Replace confirmation**: When the incoming data doesn't match existing columns, a confirmation dialog warns before replacing the current dataset.\n\n### Feedback\n\nA toast notification (auto-clears after 3 seconds) confirms the result — e.g., \"Added 50 rows\" or \"Added 2 columns\".\n\n---\n\n## Upload Flow (Azure App)\n\nFile upload (CSV/Excel drag-and-drop) is available in the Azure App.\n\n```\nFILE SELECTED\n │\n ▼\nPARSE (CSV/Excel)\n │\n ▼\nDETECT COLUMNS\n │\n ▼\nAUTO-MAP (if keywords found)\n │\n ▼\nVALIDATE DATA\n │\n ▼\nTIME EXTRACTION (if date column detected)\n │\n ▼\nUSER CONFIRMS/ADJUSTS\n │\n ▼\nLOAD INTO ANALYSIS\n```\n\nFile upload in the append context (via \"Add Data\" → \"Upload File\") follows the same merge logic described in [Add Data During Analysis](#add-data-during-analysis-azure-app) above.\n\n---\n\n## See Also\n\n- [Validation](validation.md)\n- [Storage](storage.md)\n- [Technical: Data Input](../../05-technical/implementation/data-input.md)", + "src/content/docs/03-features/data/data-input.md", + "9bc9f81417ed04cd", + { "html": 6920, "metadata": 6921 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"data-input\">Data Input\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#data-input\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Input”\u003C/span>\u003C/a>\u003C/div>\n\u003C!-- journey-phase: frame -->\n\u003Cp>How VariScout handles data input — paste (PWA and Azure App) and file upload (Azure App).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"supported-formats\">Supported Formats\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#supported-formats\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Supported Formats”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Format\u003C/th>\u003Cth>Extension\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>CSV\u003C/td>\u003Ctd>.csv\u003C/td>\u003Ctd>Comma or semicolon delimited\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel\u003C/td>\u003Ctd>.xlsx, .xls\u003C/td>\u003Ctd>First sheet used\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>TSV\u003C/td>\u003Ctd>.tsv\u003C/td>\u003Ctd>Tab delimited\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"column-detection\">Column Detection\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#column-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Column Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout auto-detects column types and displays them as \u003Cstrong>colored type badges\u003C/strong> in the ColumnMapping screen:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Detection\u003C/th>\u003Cth>Badge Color\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Numeric measure\u003C/td>\u003Ctd>All values are numbers\u003C/td>\u003Ctd>Blue\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Date/time\u003C/td>\u003Ctd>Parseable date formats\u003C/td>\u003Ctd>Amber\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Categorical\u003C/td>\u003Ctd>Repeated string values\u003C/td>\u003Ctd>Green\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Identifier\u003C/td>\u003Ctd>Unique values (ignored for analysis)\u003C/td>\u003Ctd>Slate\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"required-columns\">Required Columns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#required-columns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Required Columns”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Column Type\u003C/th>\u003Cth>Required?\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Measure\u003C/td>\u003Ctd>Yes (at least 1)\u003C/td>\u003Ctd>Values to analyze\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Factor\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Categories for grouping\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Date/Time\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Time-series ordering\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"auto-mapping\">Auto-Mapping\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#auto-mapping\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Auto-Mapping”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Keywords trigger automatic column assignment:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Keywords\u003C/th>\u003Cth>Maps To\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”value”, “measure”, “result”\u003C/td>\u003Ctd>Measure column\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”shift”, “machine”, “operator”\u003C/td>\u003Ctd>Factor columns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”date”, “time”, “timestamp”\u003C/td>\u003Ctd>Time column\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”usl”, “lsl”, “target”, “spec”\u003C/td>\u003Ctd>Specification values\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"paste-flow-pwa-and-azure-app\">Paste Flow (PWA and Azure App)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#paste-flow-pwa-and-azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Paste Flow (PWA and Azure App)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both the PWA and Azure App support paste input — users paste tab- or comma-separated text from Excel or Google Sheets.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">TEXT PASTED\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PARSE (tab/comma auto-detected via parseText())\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DETECT COLUMNS (type, sample values, unique count, missing count via detectColumns())\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">VALIDATE DATA\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">TIME EXTRACTION (if date column detected)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USER CONFIRMS/ADJUSTS MAPPING (ColumnMapping with data-rich cards)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LOAD INTO ANALYSIS\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"TEXT PASTED │ ▼PARSE (tab/comma auto-detected via parseText()) │ ▼DETECT COLUMNS (type, sample values, unique count, missing count via detectColumns()) │ ▼VALIDATE DATA │ ▼TIME EXTRACTION (if date column detected) │ ▼USER CONFIRMS/ADJUSTS MAPPING (ColumnMapping with data-rich cards) │ ▼LOAD INTO ANALYSIS\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The paste flow uses the same \u003Ccode dir=\"auto\">parseText()\u003C/code> → \u003Ccode dir=\"auto\">detectColumns()\u003C/code> → \u003Ccode dir=\"auto\">ColumnMapping\u003C/code> pipeline as file upload. Tab and comma delimiters are auto-detected. The only difference is \u003Ccode dir=\"auto\">maxFactors\u003C/code>: PWA allows 3 factors, Azure allows 6. The PWA HomeScreen also offers sample datasets as an alternative entry point.\u003C/p>\n\u003Cp>\u003Ccode dir=\"auto\">PasteScreenBase\u003C/code> accepts optional \u003Ccode dir=\"auto\">title\u003C/code> and \u003Ccode dir=\"auto\">submitLabel\u003C/code> props, allowing the Azure “Add Data” flow to reuse the same component with contextual labels (e.g., “Paste Data to Add” / “Add Data”).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"columnmapping-features\">ColumnMapping Features\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#columnmapping-features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ColumnMapping Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The ColumnMapping component displays detected columns as \u003Cstrong>data-rich cards\u003C/strong> with:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Type-separated sections\u003C/strong>: The Y (Outcome) section shows numeric columns by default; the X (Factors) section shows categorical and date columns. A \u003Cstrong>“Show all columns”\u003C/strong> toggle lets users see all columns in either section (useful when a numeric column needs to be treated as a factor).\u003C/li>\n\u003Cli>\u003Cstrong>Data-rich cards\u003C/strong>: Each column card shows a colored type badge (Numeric/Categorical/Date/Text), 3–4 sample values from the data, unique or category count (≤10 unique values shows “N categories”, >10 shows “N unique”), and an amber warning icon when missing values are detected.\u003C/li>\n\u003Cli>\u003Cstrong>Column renaming\u003C/strong>: A pencil icon on each card opens an inline text input. Press Enter or click away to save the alias. The original column name appears as a subtitle. Aliases persist through the analysis — filter chips, chart axes, and breadcrumbs all use the renamed label.\u003C/li>\n\u003Cli>\u003Cstrong>Collapsible data preview\u003C/strong>: A “Preview Data” toggle expands a mini table showing the first 5 rows with color-coded column headers (blue for numeric, green for categorical, amber for date, slate for text) and a row/column summary.\u003C/li>\n\u003Cli>\u003Cstrong>Specification limits\u003C/strong>: An optional collapsible \u003Cstrong>“Set Specification Limits”\u003C/strong> section (Target, LSL, USL) at the bottom, collapsed by default. Users who already know their spec limits can expand it and enter values before proceeding to analysis — values auto-apply on blur and carry through to the dashboard.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"time-factor-extraction\">Time Factor Extraction\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#time-factor-extraction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Time Factor Extraction”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When a date or datetime column is detected during column mapping, the \u003Cstrong>TimeExtractionPanel\u003C/strong> appears inside the ColumnMapping screen. This lets users extract temporal factors from date columns for drill-down analysis (e.g., “Does performance vary by day of week?” or “Are there monthly trends?”).\u003C/p>\n\u003Cp>\u003Cstrong>Checkboxes:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Factor\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Year\u003C/td>\u003Ctd>On\u003C/td>\u003Ctd>4-digit year (e.g., 2026)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Month\u003C/td>\u003Ctd>On\u003C/td>\u003Ctd>Month name (e.g., January)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Week\u003C/td>\u003Ctd>Off\u003C/td>\u003Ctd>ISO week number\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Day of Week\u003C/td>\u003Ctd>On\u003C/td>\u003Ctd>Weekday name (e.g., Monday)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hour\u003C/td>\u003Ctd>Off*\u003C/td>\u003Ctd>Hour of day (0–23)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>* Hour is auto-enabled when the data contains time components (timestamps with \u003Ccode dir=\"auto\">T\u003C/code> or \u003Ccode dir=\"auto\">:\u003C/code>).\u003C/p>\n\u003Cp>\u003Cstrong>Result:\u003C/strong> New factor columns are added to the dataset (e.g., \u003Ccode dir=\"auto\">Date_Year\u003C/code>, \u003Ccode dir=\"auto\">Date_Month\u003C/code>, \u003Ccode dir=\"auto\">Date_DayOfWeek\u003C/code>) and appear as available factors for drill-down analysis.\u003C/p>\n\u003Cp>\u003Cstrong>Availability:\u003C/strong> Both PWA and Azure App.\u003C/p>\n\u003Cp>\u003Cstrong>Technical details:\u003C/strong> Uses \u003Ccode dir=\"auto\">augmentWithTimeColumns()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core/time.ts\u003C/code>. See \u003Ca href=\"../../05-technical/implementation/data-input.md\">Technical: Data Input\u003C/a> for the extraction pipeline.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-table-editor-pwa-and-azure-app\">Data Table Editor (PWA and Azure App)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-table-editor-pwa-and-azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Table Editor (PWA and Azure App)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both the PWA and Azure App include an inline \u003Cstrong>Data Table Editor\u003C/strong> for correcting or extending data without re-importing.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"how-to-open\">How to Open\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#how-to-open\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How to Open”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>PWA\u003C/strong>: Click the \u003Cstrong>Data Table\u003C/strong> button in the toolbar header\u003C/li>\n\u003Cli>\u003Cstrong>Azure App\u003C/strong>: Click the \u003Cstrong>Pencil\u003C/strong> icon in the toolbar, or the pencil icon in the DataPanel header\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"features\">Features\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Features”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Cell editing\u003C/strong>\u003C/td>\u003Ctd>Click any cell to edit its value inline\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Keyboard navigation\u003C/strong>\u003C/td>\u003Ctd>Tab (next cell), Shift+Tab (previous), Enter (save + move down), Escape (cancel)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Add row\u003C/strong>\u003C/td>\u003Ctd>Adds a new empty row at the bottom\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Delete row\u003C/strong>\u003C/td>\u003Ctd>Trash icon on each row\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Spec status\u003C/strong>\u003C/td>\u003Ctd>Outcome column shows PASS/USL/LSL badges\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Excluded row indicators\u003C/strong>\u003C/td>\u003Ctd>Amber warning icon with hover tooltip\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Control violation indicators\u003C/strong>\u003C/td>\u003Ctd>Red icon for UCL/LCL and Nelson Rule violations (Azure)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Column aliases\u003C/strong>\u003C/td>\u003Ctd>Displays renamed column headers (Azure)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pagination\u003C/strong>\u003C/td>\u003Ctd>Automatic for datasets > 500 rows\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"batch-save-workflow\">Batch Save Workflow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#batch-save-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Batch Save Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Edits are made on a \u003Cstrong>local copy\u003C/strong> of the data. Nothing changes until you click \u003Cstrong>Apply Changes\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>Open the Data Table Editor\u003C/li>\n\u003Cli>Make edits (cells, add rows, delete rows)\u003C/li>\n\u003Cli>A \u003Cstrong>(unsaved changes)\u003C/strong> indicator appears in the header\u003C/li>\n\u003Cli>Click \u003Cstrong>Apply Changes\u003C/strong> to commit all edits at once — charts update immediately\u003C/li>\n\u003Cli>Or click \u003Cstrong>Cancel\u003C/strong> to discard all changes\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"add-data-during-analysis-azure-app\">Add Data During Analysis (Azure App)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#add-data-during-analysis-azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Add Data During Analysis (Azure App)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure App’s “Add Data” dropdown lets analysts bring in additional data without restarting the analysis. It appears in the Editor toolbar header once data is loaded.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"three-options\">Three Options\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#three-options\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Three Options”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Option\u003C/th>\u003Cth>Source\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Paste Data\u003C/strong>\u003C/td>\u003Ctd>Clipboard (tab/comma)\u003C/td>\u003Ctd>Opens PasteScreenBase with append-context label\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Upload File\u003C/strong>\u003C/td>\u003Ctd>CSV or Excel file\u003C/td>\u003Ctd>Same parse pipeline as initial upload\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Manual Entry\u003C/strong>\u003C/td>\u003Ctd>Keyboard (ManualEntryBase)\u003C/td>\u003Ctd>Opens the manual entry grid\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"auto-detection-merge-strategy\">Auto-Detection (Merge Strategy)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#auto-detection-merge-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Auto-Detection (Merge Strategy)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When new data arrives, \u003Ccode dir=\"auto\">useDataMerge\u003C/code> determines the merge strategy automatically via \u003Ccode dir=\"auto\">detectMergeStrategy()\u003C/code>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Condition\u003C/th>\u003Cth>Strategy\u003C/th>\u003Cth>Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>All columns match existing data\u003C/td>\u003Ctd>\u003Cstrong>Append rows\u003C/strong>\u003C/td>\u003Ctd>New rows concatenated; column union filled with null\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>New columns detected\u003C/td>\u003Ctd>\u003Cstrong>Add columns\u003C/strong>\u003C/td>\u003Ctd>Index-aligned join; shorter side padded with null\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No overlap / completely new data\u003C/td>\u003Ctd>\u003Cstrong>Replace\u003C/strong>\u003C/td>\u003Ctd>Confirmation dialog before replacing current dataset\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cul>\n\u003Cli>\u003Cstrong>Row append\u003C/strong>: concat existing + new rows, union of all columns, missing values filled with \u003Ccode dir=\"auto\">null\u003C/code>.\u003C/li>\n\u003Cli>\u003Cstrong>Column merge\u003C/strong>: index-aligned join (row 0 ↔ row 0), shorter side padded with \u003Ccode dir=\"auto\">null\u003C/code>.\u003C/li>\n\u003Cli>\u003Cstrong>After adding columns\u003C/strong>: ColumnMapping is shown for the new columns so the analyst can assign roles (factor, outcome, etc.).\u003C/li>\n\u003Cli>\u003Cstrong>Replace confirmation\u003C/strong>: When the incoming data doesn’t match existing columns, a confirmation dialog warns before replacing the current dataset.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"feedback\">Feedback\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#feedback\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feedback”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A toast notification (auto-clears after 3 seconds) confirms the result — e.g., “Added 50 rows” or “Added 2 columns”.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"upload-flow-azure-app\">Upload Flow (Azure App)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#upload-flow-azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Upload Flow (Azure App)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>File upload (CSV/Excel drag-and-drop) is available in the Azure App.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">FILE SELECTED\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PARSE (CSV/Excel)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DETECT COLUMNS\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">AUTO-MAP (if keywords found)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">VALIDATE DATA\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">TIME EXTRACTION (if date column detected)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USER CONFIRMS/ADJUSTS\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LOAD INTO ANALYSIS\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"FILE SELECTED │ ▼PARSE (CSV/Excel) │ ▼DETECT COLUMNS │ ▼AUTO-MAP (if keywords found) │ ▼VALIDATE DATA │ ▼TIME EXTRACTION (if date column detected) │ ▼USER CONFIRMS/ADJUSTS │ ▼LOAD INTO ANALYSIS\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>File upload in the append context (via “Add Data” → “Upload File”) follows the same merge logic described in \u003Ca href=\"#add-data-during-analysis-azure-app\">Add Data During Analysis\u003C/a> above.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"validation.md\">Validation\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"storage.md\">Storage\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../05-technical/implementation/data-input.md\">Technical: Data Input\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 6922, + "localImagePaths": 6971, + "remoteImagePaths": 6972, + "frontmatter": 6973, + "imagePaths": 6974 + }, + [ + 6923, 6924, 6927, 6930, 6933, 6936, 6939, 6942, 6945, 6948, 6951, 6952, 6955, 6958, 6961, 6964, + 6967, 6970 + ], + { "depth": 30, "slug": 974, "text": 975 }, + { "depth": 33, "slug": 6925, "text": 6926 }, + "supported-formats", + "Supported Formats", + { "depth": 33, "slug": 6928, "text": 6929 }, + "column-detection", + "Column Detection", + { "depth": 33, "slug": 6931, "text": 6932 }, + "required-columns", + "Required Columns", + { "depth": 33, "slug": 6934, "text": 6935 }, + "auto-mapping", + "Auto-Mapping", + { "depth": 33, "slug": 6937, "text": 6938 }, + "paste-flow-pwa-and-azure-app", + "Paste Flow (PWA and Azure App)", + { "depth": 79, "slug": 6940, "text": 6941 }, + "columnmapping-features", + "ColumnMapping Features", + { "depth": 79, "slug": 6943, "text": 6944 }, + "time-factor-extraction", + "Time Factor Extraction", + { "depth": 33, "slug": 6946, "text": 6947 }, + "data-table-editor-pwa-and-azure-app", + "Data Table Editor (PWA and Azure App)", + { "depth": 79, "slug": 6949, "text": 6950 }, + "how-to-open", + "How to Open", + { "depth": 79, "slug": 1082, "text": 1070 }, + { "depth": 79, "slug": 6953, "text": 6954 }, + "batch-save-workflow", + "Batch Save Workflow", + { "depth": 33, "slug": 6956, "text": 6957 }, + "add-data-during-analysis-azure-app", + "Add Data During Analysis (Azure App)", + { "depth": 79, "slug": 6959, "text": 6960 }, + "three-options", + "Three Options", + { "depth": 79, "slug": 6962, "text": 6963 }, + "auto-detection-merge-strategy", + "Auto-Detection (Merge Strategy)", + { "depth": 79, "slug": 6965, "text": 6966 }, + "feedback", + "Feedback", + { "depth": 33, "slug": 6968, "text": 6969 }, + "upload-flow-azure-app", + "Upload Flow (Azure App)", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 975 }, + [], + "03-features/data/validation", + { "id": 6975, "data": 6977, "body": 6981, "filePath": 6982, "digest": 6983, "rendered": 6984 }, + { + "title": 1228, + "editUrl": 16, + "head": 6978, + "template": 18, + "sidebar": 6979, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 6980 }, + {}, + "# Data Validation\n\nQuality checks applied to uploaded data.\n\n---\n\n## Validation Rules\n\n| Check | Severity | Description |\n| ----------------- | -------- | -------------------------- |\n| Empty file | Error | File has no data rows |\n| No measure column | Error | No numeric column detected |\n| All values same | Warning | Zero variation |\n| Too few points | Warning | \u003C10 data points |\n| Outlier detected | Info | Values >3σ from mean |\n| Missing values | Info | Nulls in measure column |\n\n---\n\n## Severity Levels\n\n| Level | Effect |\n| ------- | ---------------------------- |\n| Error | Blocks analysis |\n| Warning | Allows analysis with caution |\n| Info | Informational only |\n\n---\n\n## Validation Banner\n\nResults shown in DataQualityBanner:\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│ ⚠️ Data Quality Check │\n│ │\n│ ✓ 1,234 rows loaded │\n│ ⚠ 12 missing values in 'Temperature' (will be excluded) │\n│ ℹ 3 potential outliers detected │\n│ │\n│ [Proceed Anyway] [Review Data] │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Missing Value Handling\n\n| Option | Behavior |\n| ------- | ------------------------------- |\n| Exclude | Skip rows with missing values |\n| Include | Use available values, note gaps |\n\n---\n\n## See Also\n\n- [Data Input](data-input.md)\n- [Storage](storage.md)", + "src/content/docs/03-features/data/validation.md", + "7bd8d4ff9b9cf76f", + { "html": 6985, "metadata": 6986 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"data-validation\">Data Validation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#data-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Quality checks applied to uploaded data.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"validation-rules\">Validation Rules\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#validation-rules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Validation Rules”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Check\u003C/th>\u003Cth>Severity\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Empty file\u003C/td>\u003Ctd>Error\u003C/td>\u003Ctd>File has no data rows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No measure column\u003C/td>\u003Ctd>Error\u003C/td>\u003Ctd>No numeric column detected\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>All values same\u003C/td>\u003Ctd>Warning\u003C/td>\u003Ctd>Zero variation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Too few points\u003C/td>\u003Ctd>Warning\u003C/td>\u003Ctd><10 data points\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Outlier detected\u003C/td>\u003Ctd>Info\u003C/td>\u003Ctd>Values >3σ from mean\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Missing values\u003C/td>\u003Ctd>Info\u003C/td>\u003Ctd>Nulls in measure column\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"severity-levels\">Severity Levels\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#severity-levels\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Severity Levels”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Level\u003C/th>\u003Cth>Effect\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Error\u003C/td>\u003Ctd>Blocks analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Warning\u003C/td>\u003Ctd>Allows analysis with caution\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Info\u003C/td>\u003Ctd>Informational only\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"validation-banner\">Validation Banner\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#validation-banner\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Validation Banner”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Results shown in DataQualityBanner:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ⚠️ Data Quality Check │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ✓ 1,234 rows loaded │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ⚠ 12 missing values in 'Temperature' (will be excluded) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ℹ 3 potential outliers detected │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Proceed Anyway] [Review Data] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────┐│ ⚠️ Data Quality Check ││ ││ ✓ 1,234 rows loaded ││ ⚠ 12 missing values in 'Temperature' (will be excluded) ││ ℹ 3 potential outliers detected ││ ││ [Proceed Anyway] [Review Data] │└─────────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"missing-value-handling\">Missing Value Handling\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#missing-value-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Missing Value Handling”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Option\u003C/th>\u003Cth>Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Exclude\u003C/td>\u003Ctd>Skip rows with missing values\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Include\u003C/td>\u003Ctd>Use available values, note gaps\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"data-input.md\">Data Input\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"storage.md\">Storage\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 6987, + "localImagePaths": 7002, + "remoteImagePaths": 7003, + "frontmatter": 7004, + "imagePaths": 7005 + }, + [6988, 6989, 6992, 6995, 6998, 7001], + { "depth": 30, "slug": 1227, "text": 1228 }, + { "depth": 33, "slug": 6990, "text": 6991 }, + "validation-rules", + "Validation Rules", + { "depth": 33, "slug": 6993, "text": 6994 }, + "severity-levels", + "Severity Levels", + { "depth": 33, "slug": 6996, "text": 6997 }, + "validation-banner", + "Validation Banner", + { "depth": 33, "slug": 6999, "text": 7000 }, + "missing-value-handling", + "Missing Value Handling", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 1228 }, + [], + "03-features/learning/case-based-learning", + { "id": 7006, "data": 7008, "body": 7013, "filePath": 7014, "digest": 7015, "rendered": 7016 }, + { + "title": 7009, + "editUrl": 16, + "head": 7010, + "template": 18, + "sidebar": 7011, + "pagefind": 16, + "draft": 20 + }, + "Case-Based Learning", + [], + { "hidden": 20, "attrs": 7012 }, + {}, + "# Case-Based Learning\n\nLearning through real-world examples and the 3-act case structure.\n\n---\n\n## Philosophy\n\n> \"Let them fail so they ask why.\"\n\nVariScout uses \"guided frustration\" pedagogy:\n\n1. **Phase 1: Immersion in Chaos** — See the messy data\n2. **Phase 2: Physical Stratification** — Peel back layers\n3. **Phase 3: System Understanding** — Connect to real system\n\n---\n\n## 3-Act Case Structure\n\nEvery case follows this narrative arc:\n\n### Act 1: The Setup\n\n- Present the problem as management sees it\n- Show the averages, the dashboard view\n- \"Line B is 3% under target\"\n- Create cognitive dissonance: \"But wait...\"\n\n### Act 2: Your Turn\n\n- Interactive demo with the case data\n- User explores freely\n- Some hints available if stuck\n- \"Can you find where the 46% is hiding?\"\n\n### Act 3: The Solution\n\n- Scroll-based reveal of the analysis journey\n- Step by step: I-Chart → Boxplot → Pareto → Drill-down\n- The \"aha moment\": \"46% was in Machine C, Shift 2\"\n- Methodology connection: This is the Four Lenses in action\n\n---\n\n## Case Library\n\n| Case | Industry | Primary Lesson |\n| ------------------------------------------------------ | ------------- | ------------------------ |\n| [Bottleneck](../../04-cases/bottleneck/index.md) | Manufacturing | Process flow, drill-down |\n| [Hospital Ward](../../04-cases/hospital-ward/index.md) | Healthcare | Aggregation trap |\n| [Coffee](../../04-cases/coffee/index.md) | Agriculture | Factor comparison, MSA |\n| [Packaging](../../04-cases/packaging/index.md) | Manufacturing | Pareto, capability |\n| [Avocado](../../04-cases/avocado/index.md) | Agriculture | Regression, MSA |\n\n---\n\n## Teaching Flow\n\n```\nWEEK N: Analysis reveals a problem\n ↓\n\"Bed C has high moisture\"\n ↓\nWEEK N+1: \"But wait...\"\n ↓\n\"Which factor explains most of the variation?\"\n ↓\nDRILL-DOWN ANALYSIS → Isolate the root cause\n```\n\n---\n\n## See Also\n\n- [Cases](../../04-cases/index.md)\n- [Four Lenses](../../01-vision/four-lenses/index.md)", + "src/content/docs/03-features/learning/case-based-learning.md", + "736f3eb80ec2ab8a", + { "html": 7017, "metadata": 7018 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"case-based-learning\">Case-Based Learning\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#case-based-learning\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Case-Based Learning”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Learning through real-world examples and the 3-act case structure.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy\">Philosophy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“Let them fail so they ask why.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>VariScout uses “guided frustration” pedagogy:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Phase 1: Immersion in Chaos\u003C/strong> — See the messy data\u003C/li>\n\u003Cli>\u003Cstrong>Phase 2: Physical Stratification\u003C/strong> — Peel back layers\u003C/li>\n\u003Cli>\u003Cstrong>Phase 3: System Understanding\u003C/strong> — Connect to real system\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"3-act-case-structure\">3-Act Case Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#3-act-case-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3-Act Case Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every case follows this narrative arc:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-1-the-setup\">Act 1: The Setup\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-1-the-setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 1: The Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Present the problem as management sees it\u003C/li>\n\u003Cli>Show the averages, the dashboard view\u003C/li>\n\u003Cli>“Line B is 3% under target”\u003C/li>\n\u003Cli>Create cognitive dissonance: “But wait…”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-2-your-turn\">Act 2: Your Turn\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-2-your-turn\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 2: Your Turn”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Interactive demo with the case data\u003C/li>\n\u003Cli>User explores freely\u003C/li>\n\u003Cli>Some hints available if stuck\u003C/li>\n\u003Cli>“Can you find where the 46% is hiding?”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-3-the-solution\">Act 3: The Solution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-3-the-solution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 3: The Solution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Scroll-based reveal of the analysis journey\u003C/li>\n\u003Cli>Step by step: I-Chart → Boxplot → Pareto → Drill-down\u003C/li>\n\u003Cli>The “aha moment”: “46% was in Machine C, Shift 2”\u003C/li>\n\u003Cli>Methodology connection: This is the Four Lenses in action\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"case-library\">Case Library\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#case-library\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Case Library”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Case\u003C/th>\u003Cth>Industry\u003C/th>\u003Cth>Primary Lesson\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"../../04-cases/bottleneck/index.md\">Bottleneck\u003C/a>\u003C/td>\u003Ctd>Manufacturing\u003C/td>\u003Ctd>Process flow, drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"../../04-cases/hospital-ward/index.md\">Hospital Ward\u003C/a>\u003C/td>\u003Ctd>Healthcare\u003C/td>\u003Ctd>Aggregation trap\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"../../04-cases/coffee/index.md\">Coffee\u003C/a>\u003C/td>\u003Ctd>Agriculture\u003C/td>\u003Ctd>Factor comparison, MSA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"../../04-cases/packaging/index.md\">Packaging\u003C/a>\u003C/td>\u003Ctd>Manufacturing\u003C/td>\u003Ctd>Pareto, capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"../../04-cases/avocado/index.md\">Avocado\u003C/a>\u003C/td>\u003Ctd>Agriculture\u003C/td>\u003Ctd>Regression, MSA\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teaching-flow\">Teaching Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teaching-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teaching Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">WEEK N: Analysis reveals a problem\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"Bed C has high moisture\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">WEEK N+1: \"But wait...\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"Which factor explains most of the variation?\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DRILL-DOWN ANALYSIS → Isolate the root cause\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"WEEK N: Analysis reveals a problem ↓"Bed C has high moisture" ↓WEEK N+1: "But wait..." ↓"Which factor explains most of the variation?" ↓DRILL-DOWN ANALYSIS → Isolate the root cause\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../04-cases/index.md\">Cases\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/index.md\">Four Lenses\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7019, + "localImagePaths": 7036, + "remoteImagePaths": 7037, + "frontmatter": 7038, + "imagePaths": 7039 + }, + [7020, 7022, 7023, 7026, 7027, 7028, 7029, 7032, 7035], + { "depth": 30, "slug": 7021, "text": 7009 }, + "case-based-learning", + { "depth": 33, "slug": 965, "text": 966 }, + { "depth": 33, "slug": 7024, "text": 7025 }, + "3-act-case-structure", + "3-Act Case Structure", + { "depth": 79, "slug": 4584, "text": 4585 }, + { "depth": 79, "slug": 4587, "text": 4588 }, + { "depth": 79, "slug": 4590, "text": 4591 }, + { "depth": 33, "slug": 7030, "text": 7031 }, + "case-library", + "Case Library", + { "depth": 33, "slug": 7033, "text": 7034 }, + "teaching-flow", + "Teaching Flow", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 7009 }, + [], + "03-features/learning/glossary", + { "id": 7040, "data": 7042, "body": 7047, "filePath": 7048, "digest": 7049, "rendered": 7050 }, + { + "title": 7043, + "editUrl": 16, + "head": 7044, + "template": 18, + "sidebar": 7045, + "pagefind": 16, + "draft": 20 + }, + "Glossary Feature", + [], + { "hidden": 20, "attrs": 7046 }, + {}, + "# Glossary Feature\n\nContextual term definitions throughout the application.\n\n---\n\n## Purpose\n\nHelp users understand statistical terms without leaving their analysis.\n\n---\n\n## Implementation\n\nTerms are defined in `packages/core/src/glossary/terms.ts` and accessed via the `useGlossary` hook.\n\n```typescript\nimport { useGlossary } from '@variscout/ui';\n\nconst { getTerm, hasTerm } = useGlossary();\n\nconst cpkTerm = getTerm('cpk');\n// { id: 'cpk', label: 'Cpk', definition: '...', description: '...' }\n```\n\n---\n\n## Term Structure\n\n```typescript\ninterface GlossaryTerm {\n id: string; // Unique identifier\n label: string; // Display label\n definition: string; // Short definition\n description: string; // Detailed explanation\n category: string; // Grouping category\n learnMorePath?: string; // Link to deeper content\n relatedTerms?: string[]; // Related term IDs\n}\n```\n\n---\n\n## Categories\n\n| Category | Terms |\n| -------------- | --------------------------------------- |\n| control-limits | UCL, LCL, USL, LSL, Target |\n| capability | Cp, Cpk, Pass Rate, Rejected |\n| statistics | Mean, Std Dev, F-Statistic, p-value, η² |\n| regression | R², Slope, Intercept, VIF |\n| charts | Violin Plot |\n| methodology | Staged Analysis, Probability Plot |\n\n---\n\n## See Also\n\n- [Help Tooltips](help-tooltips.md)\n- [Full Glossary](../../glossary.md)", + "src/content/docs/03-features/learning/glossary.md", + "3f4c2ce6e6a5fb57", + { "html": 7051, "metadata": 7052 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"glossary-feature\">Glossary Feature\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#glossary-feature\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Glossary Feature”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Contextual term definitions throughout the application.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Help users understand statistical terms without leaving their analysis.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation\">Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Terms are defined in \u003Ccode dir=\"auto\">packages/core/src/glossary/terms.ts\u003C/code> and accessed via the \u003Ccode dir=\"auto\">useGlossary\u003C/code> hook.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useGlossary } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getTerm\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hasTerm\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useGlossary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cpkTerm\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getTerm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// { id: 'cpk', label: 'Cpk', definition: '...', description: '...' }\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useGlossary } from '@variscout/ui';const { getTerm, hasTerm } = useGlossary();const cpkTerm = getTerm('cpk');// { id: 'cpk', label: 'Cpk', definition: '...', description: '...' }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"term-structure\">Term Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#term-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Term Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> GlossaryTerm {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Unique identifier\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Display label\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">definition\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Short definition\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">description\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Detailed explanation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">category\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Grouping category\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">learnMorePath\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Link to deeper content\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">relatedTerms\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Related term IDs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface GlossaryTerm { id: string; // Unique identifier label: string; // Display label definition: string; // Short definition description: string; // Detailed explanation category: string; // Grouping category learnMorePath?: string; // Link to deeper content relatedTerms?: string[]; // Related term IDs}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"categories\">Categories\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#categories\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Categories”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Category\u003C/th>\u003Cth>Terms\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>control-limits\u003C/td>\u003Ctd>UCL, LCL, USL, LSL, Target\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>capability\u003C/td>\u003Ctd>Cp, Cpk, Pass Rate, Rejected\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>statistics\u003C/td>\u003Ctd>Mean, Std Dev, F-Statistic, p-value, η²\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>regression\u003C/td>\u003Ctd>R², Slope, Intercept, VIF\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>charts\u003C/td>\u003Ctd>Violin Plot\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>methodology\u003C/td>\u003Ctd>Staged Analysis, Probability Plot\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"help-tooltips.md\">Help Tooltips\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../glossary.md\">Full Glossary\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7053, + "localImagePaths": 7065, + "remoteImagePaths": 7066, + "frontmatter": 7067, + "imagePaths": 7068 + }, + [7054, 7056, 7057, 7058, 7061, 7064], + { "depth": 30, "slug": 7055, "text": 7043 }, + "glossary-feature", + { "depth": 33, "slug": 3911, "text": 3912 }, + { "depth": 33, "slug": 1885, "text": 1886 }, + { "depth": 33, "slug": 7059, "text": 7060 }, + "term-structure", + "Term Structure", + { "depth": 33, "slug": 7062, "text": 7063 }, + "categories", + "Categories", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 7043 }, + [], + "03-features/learning/help-tooltips", + { "id": 7069, "data": 7071, "body": 7076, "filePath": 7077, "digest": 7078, "rendered": 7079 }, + { + "title": 7072, + "editUrl": 16, + "head": 7073, + "template": 18, + "sidebar": 7074, + "pagefind": 16, + "draft": 20 + }, + "Help Tooltips", + [], + { "hidden": 20, "attrs": 7075 }, + {}, + "# Help Tooltips\n\nContextual help throughout the VariScout interface.\n\n---\n\n## Purpose\n\nProvide in-context explanations for statistical terms and concepts without interrupting the analysis workflow.\n\n---\n\n## Implementation\n\nThe `HelpTooltip` component from `@variscout/ui`:\n\n```tsx\nimport { HelpTooltip } from '@variscout/ui';\n\n\u003Cspan>\n Cpk \u003CHelpTooltip termId=\"cpk\" />\n\u003C/span>;\n```\n\n---\n\n## Tooltip Content\n\n| Element | Source |\n| ----------------- | ---------------------------- |\n| Term label | `glossaryTerm.label` |\n| Definition | `glossaryTerm.definition` |\n| \"Learn more\" link | `glossaryTerm.learnMorePath` |\n\n---\n\n## Design\n\n```\n┌─────────────────────────────────────┐\n│ Cpk │\n│ │\n│ Process Capability Index. Like Cp, │\n│ but accounts for how well centered │\n│ the process is. ≥1.33 is good. │\n│ │\n│ Learn more → │\n└─────────────────────────────────────┘\n```\n\n---\n\n## Platform Variants\n\n| Platform | Component |\n| --------- | --------------------------- |\n| PWA/Azure | `@variscout/ui` HelpTooltip |\n\n---\n\n## See Also\n\n- [Glossary Feature](glossary.md)\n- [Design System: HelpTooltip](../../06-design-system/components/modals.md)", + "src/content/docs/03-features/learning/help-tooltips.md", + "47c9d3c6237d6e09", + { "html": 7080, "metadata": 7081 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"help-tooltips\">Help Tooltips\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#help-tooltips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Help Tooltips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Contextual help throughout the VariScout interface.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Provide in-context explanations for statistical terms and concepts without interrupting the analysis workflow.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation\">Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">HelpTooltip\u003C/code> component from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { HelpTooltip } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Cpk \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">HelpTooltip\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">termId\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { HelpTooltip } from '@variscout/ui';\u003Cspan> Cpk \u003CHelpTooltip termId="cpk" />\u003C/span>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tooltip-content\">Tooltip Content\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tooltip-content\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tooltip Content”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Source\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Term label\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">glossaryTerm.label\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Definition\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">glossaryTerm.definition\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Learn more” link\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">glossaryTerm.learnMorePath\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"design\">Design\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Cpk │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Process Capability Index. Like Cp, │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ but accounts for how well centered │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ the process is. ≥1.33 is good. │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Learn more → │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────┐│ Cpk ││ ││ Process Capability Index. Like Cp, ││ but accounts for how well centered ││ the process is. ≥1.33 is good. ││ ││ Learn more → │└─────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-variants\">Platform Variants\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-variants\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Variants”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Component\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA/Azure\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code> HelpTooltip\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"glossary.md\">Glossary Feature\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/components/modals.md\">Design System: HelpTooltip\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7082, + "localImagePaths": 7097, + "remoteImagePaths": 7098, + "frontmatter": 7099, + "imagePaths": 7100 + }, + [7083, 7085, 7086, 7087, 7090, 7093, 7096], + { "depth": 30, "slug": 7084, "text": 7072 }, + "help-tooltips", + { "depth": 33, "slug": 3911, "text": 3912 }, + { "depth": 33, "slug": 1885, "text": 1886 }, + { "depth": 33, "slug": 7088, "text": 7089 }, + "tooltip-content", + "Tooltip Content", + { "depth": 33, "slug": 7091, "text": 7092 }, + "design", + "Design", + { "depth": 33, "slug": 7094, "text": 7095 }, + "platform-variants", + "Platform Variants", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 7072 }, + [], + "03-features/navigation/breadcrumbs", + { "id": 7101, "data": 7103, "body": 7108, "filePath": 7109, "digest": 7110, "rendered": 7111 }, + { + "title": 7104, + "editUrl": 16, + "head": 7105, + "template": 18, + "sidebar": 7106, + "pagefind": 16, + "draft": 20 + }, + "Filter Chips Navigation", + [], + { "hidden": 20, "attrs": 7107 }, + {}, + "# Filter Chips Navigation\n\nFilter chips provide an intuitive way to see and manage active filters with their contribution to total variation.\n\n---\n\n## UI Design\n\nFilter chips replace the traditional breadcrumb trail with a chips-based interface:\n\n```\n┌─────────────────────────────────────────────────────────────────────────┐\n│ ACTIVE FILTERS │\n│ │\n│ ┌────────────────────┐ ┌────────────────────┐ ┌──────────────────┐ │\n│ │ Shift: Night ▼ 45% │ │ Machine: A, C ▼ 32%│ │ Operator: Kim ▼ │ │\n│ └────────────────────┘ └────────────────────┘ └──────────────────┘ │\n│ │\n│ CUMULATIVE: 77% of total variation isolated │\n│ \"Focus on this combination to address most of your quality problems\" │\n└─────────────────────────────────────────────────────────────────────────┘\n```\n\nEach chip shows:\n\n- **Factor name**: The column being filtered\n- **Selected values**: Current selection (truncated if multiple)\n- **Dropdown arrow**: Click to see all values with contribution %\n- **Contribution %**: Combined contribution of selected values to TOTAL variation\n\n---\n\n## Multi-Select Support\n\nUnlike traditional drill-down, filter chips support selecting multiple values within a factor:\n\n| Selection | Display | Contribution |\n| ------------ | ---------------------------- | ------------------- |\n| Single value | `Shift: Night ▼ 45%` | That value's % |\n| Two values | `Shift: Day, Night ▼ 78%` | Sum of both values |\n| 3+ values | `Shift: Day, Night +1 ▼ 89%` | Sum of all selected |\n\n---\n\n## Dropdown Values\n\nClicking a chip reveals all available values with their individual contributions:\n\n```\n┌─────────────────────────┐\n│ Shift │\n├─────────────────────────┤\n│ ☑ Night 45% │\n│ ☐ Day 33% │\n│ ☐ Evening 22% │\n├─────────────────────────┤\n│ [Remove Filter] │\n└─────────────────────────┘\n```\n\nValues are sorted by contribution (highest first) to guide users toward high-impact selections.\n\n---\n\n## Contribution % vs Local η²\n\n**Important distinction:**\n\n- **Contribution %** (shown in chips): Percentage of TOTAL variation from original data\n- **Local η²** (legacy): Percentage of variation at the current filtered level\n\nFilter chips always show contribution to TOTAL variation, making it easier to understand cumulative impact.\n\n---\n\n## Navigation Actions\n\n| Action | Result |\n| --------------------- | ------------------------------------ |\n| Click chip dropdown | Show all values with contribution % |\n| Toggle value checkbox | Add/remove value from selection |\n| Click \"Remove Filter\" | Remove entire filter for that factor |\n| Click \"Clear All\" | Reset to unfiltered view |\n| Keyboard: Backspace | Remove last filter |\n\n---\n\n## Component API\n\n```typescript\nimport { useFilterNavigation, useVariationTracking } from '@variscout/hooks';\n\nconst { filterStack, updateFilterValues, removeFilter } = useFilterNavigation(\n { filters, setFilters, columnAliases }\n);\n\nconst { filterChipData } = useVariationTracking(rawData, filterStack, outcome, factors);\n\n// Render chips\n{filterChipData.map(chip => (\n \u003CFilterChip\n key={chip.factor}\n factor={chip.factor}\n values={chip.values}\n contributionPct={chip.contributionPct}\n availableValues={chip.availableValues}\n onValuesChange={(newValues) => updateFilterValues(chip.factor, newValues)}\n onRemove={() => removeFilter(chip.factor)}\n />\n))}\n```\n\n---\n\n## FilterChipData Interface\n\n```typescript\ninterface FilterChipData {\n factor: string;\n values: (string | number)[];\n contributionPct: number; // % of TOTAL variation\n availableValues: {\n value: string | number;\n contributionPct: number;\n isSelected: boolean;\n }[];\n}\n```\n\n---\n\n## See Also\n\n- [Drill-Down](drill-down.md)\n- [Four Lenses: Drill-Down](../../01-vision/four-lenses/drilldown.md)", + "src/content/docs/03-features/navigation/breadcrumbs.md", + "e9bfb65eba4e2eff", + { "html": 7112, "metadata": 7113 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"filter-chips-navigation\">Filter Chips Navigation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#filter-chips-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter Chips Navigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Filter chips provide an intuitive way to see and manage active filters with their contribution to total variation.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ui-design\">UI Design\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ui-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “UI Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Filter chips replace the traditional breadcrumb trail with a chips-based interface:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ACTIVE FILTERS │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌────────────────────┐ ┌────────────────────┐ ┌──────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Shift: Night ▼ 45% │ │ Machine: A, C ▼ 32%│ │ Operator: Kim ▼ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └────────────────────┘ └────────────────────┘ └──────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CUMULATIVE: 77% of total variation isolated │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ \"Focus on this combination to address most of your quality problems\" │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────────────┐│ ACTIVE FILTERS ││ ││ ┌────────────────────┐ ┌────────────────────┐ ┌──────────────────┐ ││ │ Shift: Night ▼ 45% │ │ Machine: A, C ▼ 32%│ │ Operator: Kim ▼ │ ││ └────────────────────┘ └────────────────────┘ └──────────────────┘ ││ ││ CUMULATIVE: 77% of total variation isolated ││ "Focus on this combination to address most of your quality problems" │└─────────────────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Each chip shows:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Factor name\u003C/strong>: The column being filtered\u003C/li>\n\u003Cli>\u003Cstrong>Selected values\u003C/strong>: Current selection (truncated if multiple)\u003C/li>\n\u003Cli>\u003Cstrong>Dropdown arrow\u003C/strong>: Click to see all values with contribution %\u003C/li>\n\u003Cli>\u003Cstrong>Contribution %\u003C/strong>: Combined contribution of selected values to TOTAL variation\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"multi-select-support\">Multi-Select Support\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#multi-select-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Multi-Select Support”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Unlike traditional drill-down, filter chips support selecting multiple values within a factor:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Selection\u003C/th>\u003Cth>Display\u003C/th>\u003Cth>Contribution\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Single value\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Shift: Night ▼ 45%\u003C/code>\u003C/td>\u003Ctd>That value’s %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Two values\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Shift: Day, Night ▼ 78%\u003C/code>\u003C/td>\u003Ctd>Sum of both values\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3+ values\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Shift: Day, Night +1 ▼ 89%\u003C/code>\u003C/td>\u003Ctd>Sum of all selected\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dropdown-values\">Dropdown Values\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dropdown-values\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dropdown Values”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Clicking a chip reveals all available values with their individual contributions:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Shift │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☑ Night 45% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☐ Day 33% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ☐ Evening 22% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Remove Filter] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────┐│ Shift │├─────────────────────────┤│ ☑ Night 45% ││ ☐ Day 33% ││ ☐ Evening 22% │├─────────────────────────┤│ [Remove Filter] │└─────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Values are sorted by contribution (highest first) to guide users toward high-impact selections.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"contribution--vs-local-η\">Contribution % vs Local η²\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#contribution--vs-local-η\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Contribution % vs Local η²”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Important distinction:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Contribution %\u003C/strong> (shown in chips): Percentage of TOTAL variation from original data\u003C/li>\n\u003Cli>\u003Cstrong>Local η²\u003C/strong> (legacy): Percentage of variation at the current filtered level\u003C/li>\n\u003C/ul>\n\u003Cp>Filter chips always show contribution to TOTAL variation, making it easier to understand cumulative impact.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"navigation-actions\">Navigation Actions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#navigation-actions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Navigation Actions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>Result\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Click chip dropdown\u003C/td>\u003Ctd>Show all values with contribution %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Toggle value checkbox\u003C/td>\u003Ctd>Add/remove value from selection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Click “Remove Filter”\u003C/td>\u003Ctd>Remove entire filter for that factor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Click “Clear All”\u003C/td>\u003Ctd>Reset to unfiltered view\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Keyboard: Backspace\u003C/td>\u003Ctd>Remove last filter\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"component-api\">Component API\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#component-api\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Component API”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useFilterNavigation, useVariationTracking } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/hooks\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterStack\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeFilter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useFilterNavigation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setFilters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">columnAliases\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterChipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useVariationTracking\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(rawData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterStack\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factors);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Render chips\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{filterChipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">chip\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">FilterChip\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chip.factor}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chip.factor}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chip.values}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contributionPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chip.contributionPct}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">availableValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chip.availableValues}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onValuesChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{(newValues) => \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">chip.factor, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">newValues\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onRemove\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{() => \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeFilter\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chip.factor\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useFilterNavigation, useVariationTracking } from '@variscout/hooks';const { filterStack, updateFilterValues, removeFilter } = useFilterNavigation( { filters, setFilters, columnAliases });const { filterChipData } = useVariationTracking(rawData, filterStack, outcome, factors);// Render chips{filterChipData.map(chip => ( \u003CFilterChip key={chip.factor} factor={chip.factor} values={chip.values} contributionPct={chip.contributionPct} availableValues={chip.availableValues} onValuesChange={(newValues) => updateFilterValues(chip.factor, newValues)} onRemove={() => removeFilter(chip.factor)} />))}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"filterchipdata-interface\">FilterChipData Interface\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#filterchipdata-interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “FilterChipData Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FilterChipData {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contributionPct\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// % of TOTAL variation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">availableValues\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contributionPct\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isSelected\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface FilterChipData { factor: string; values: (string | number)[]; contributionPct: number; // % of TOTAL variation availableValues: { value: string | number; contributionPct: number; isSelected: boolean; }[];}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"drill-down.md\">Drill-Down\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/drilldown.md\">Four Lenses: Drill-Down\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7114, + "localImagePaths": 7139, + "remoteImagePaths": 7140, + "frontmatter": 7141, + "imagePaths": 7142 + }, + [7115, 7117, 7120, 7123, 7126, 7129, 7132, 7135, 7138], + { "depth": 30, "slug": 7116, "text": 7104 }, + "filter-chips-navigation", + { "depth": 33, "slug": 7118, "text": 7119 }, + "ui-design", + "UI Design", + { "depth": 33, "slug": 7121, "text": 7122 }, + "multi-select-support", + "Multi-Select Support", + { "depth": 33, "slug": 7124, "text": 7125 }, + "dropdown-values", + "Dropdown Values", + { "depth": 33, "slug": 7127, "text": 7128 }, + "contribution--vs-local-η", + "Contribution % vs Local η²", + { "depth": 33, "slug": 7130, "text": 7131 }, + "navigation-actions", + "Navigation Actions", + { "depth": 33, "slug": 7133, "text": 7134 }, + "component-api", + "Component API", + { "depth": 33, "slug": 7136, "text": 7137 }, + "filterchipdata-interface", + "FilterChipData Interface", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 7104 }, + [], + "03-features/navigation/drill-down", + { "id": 7143, "data": 7145, "body": 7150, "filePath": 7151, "digest": 7152, "rendered": 7153 }, + { + "title": 7146, + "editUrl": 16, + "head": 7147, + "template": 18, + "sidebar": 7148, + "pagefind": 16, + "draft": 20 + }, + "Drill-Down Navigation", + [], + { "hidden": 20, "attrs": 7149 }, + {}, + "# Drill-Down Navigation\n\nDrill-down is VariScout's core methodology for isolating variation sources through progressive stratification.\n\n---\n\n## Concept\n\nStart with all data, then progressively filter to find where variation concentrates. Filter chips show contribution to TOTAL variation:\n\n```\n┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐\n│ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │\n└────────────────────┘ └────────────────────┘ └────────────────────┘\n```\n\nEach chip shows how much of the TOTAL variation that filter captures.\n\n---\n\n## Decision Thresholds\n\n| Variation % | Action |\n| ----------- | ---------------------------------------- |\n| **>50%** | Auto-drill — this is the primary driver |\n| **>80%** | Strong focus — highly concentrated issue |\n| **30-50%** | Recommend investigating, ask user |\n| **\u003C30%** | Multiple factors — check interactions |\n\n---\n\n## When to Check for Interactions\n\nThe drill-down methodology captures **main effects** — how much variation each factor explains independently. But factors can also **interact**:\n\n> \"Machine C is only problematic on Night shift\"\n\n### The Guidance Prompt\n\nWhen 2+ factors are in your drill stack, the Investigation Mindmap's Interaction mode shows factor relationships visually as edges between nodes. The Mindmap also surfaces a guidance prompt:\n\n```\n┌────────────────────────────────────────────────┐\n│ Analyzing multiple factors? │\n│ │\n│ Your drill-down shows main effects. To check │\n│ if factors interact, use the Regression Panel │\n│ with \"Include interactions\". │\n│ │\n│ [Check Interactions →] │\n└────────────────────────────────────────────────┘\n```\n\n### When Interactions Matter\n\n| Scenario | Recommendation |\n| ---------------------------- | ----------------------------------------------------------------- |\n| **\u003C30% variation explained** | Check for interactions — combined effect may be stronger |\n| **Factors seem related** | Machine type + Operator experience often interact |\n| **Action seems ambiguous** | \"Fix Machine C\" vs \"Change Night process\" — interaction clarifies |\n\n### Statistical Difference\n\n| Method | What it captures |\n| ----------------------------- | ----------------------------------- |\n| Sequential ANOVA (drill-down) | Main effects only (η² per factor) |\n| GLM with interactions | Main effects + two-way interactions |\n\nSee [Regression Analysis: Interaction Effects](../analysis/regression.md#interaction-effects) for details.\n\n---\n\n## Cumulative Impact\n\nThe real power is cumulative calculation of contribution percentages:\n\n```\nFILTER CHIPS CONTRIBUTION TO TOTAL\n─────────────────────────────────────────────────────────\n[Shift: Night ▼ 67%] 67% of total variation\n[Machine: C ▼ 24%] (within Night Shift context)\n[Operator: Kim ▼ 9%] (within Machine C + Night)\n\nCUMULATIVE: Focused on ~46% of TOTAL variation\n```\n\n**Result:** Three filters focus on nearly half of ALL variation in ONE condition.\n\n---\n\n## Implementation\n\n```typescript\nimport { useFilterNavigation, useVariationTracking } from '@variscout/hooks';\n\n// Filter navigation with multi-select support\nconst { filterStack, applyFilter, updateFilterValues, removeFilter, clearFilters, hasFilters } =\n useFilterNavigation(\n { filters, setFilters, columnAliases },\n { enableHistory: true, enableUrlSync: true }\n );\n\n// Variation tracking for filter chip data\nconst {\n filterChipData, // Data for rendering filter chips\n cumulativeVariationPct, // Total SS scope % in focus\n impactLevel, // 'high' | 'moderate' | 'low'\n factorVariations, // η² for each factor (internal drill suggestion)\n} = useVariationTracking(rawData, filterStack, outcome, factors);\n\n// Update filter with multiple values (multi-select)\nupdateFilterValues('Machine', ['A', 'C'], 'boxplot');\n\n// Remove a specific filter\nremoveFilter('Shift');\n```\n\n---\n\n## User Interaction\n\n1. **View Boxplot** - See factor comparison with contribution %\n2. **Click category** - Filter into that factor value\n3. **Filter chip appears** - Shows selected value(s) and contribution %\n4. **Click chip dropdown** - Select/deselect additional values\n5. **Repeat** - Until actionable condition found\n6. **Remove filter** - Click X or use \"Remove Filter\" in dropdown\n\n---\n\n## Multi-Select Workflow\n\nFilter chips support selecting multiple values within a factor:\n\n```typescript\n// Single value selection (traditional drill)\napplyFilter({\n type: 'filter',\n source: 'boxplot',\n factor: 'Shift',\n values: ['Night'],\n});\n\n// Add another value (multi-select)\nupdateFilterValues('Shift', ['Night', 'Day'], 'boxplot');\n\n// Remove one value, keep the other\nupdateFilterValues('Shift', ['Night'], 'boxplot');\n\n// Remove filter entirely\nremoveFilter('Shift');\n```\n\n---\n\n## See Also\n\n- [Four Lenses: Drill-Down](../../01-vision/four-lenses/drilldown.md)\n- [Filter Chips](breadcrumbs.md)\n- [Linked Filtering](linked-filtering.md)", + "src/content/docs/03-features/navigation/drill-down.md", + "2e1ff83a0a757e50", + { "html": 7154, "metadata": 7155 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"drill-down-navigation\">Drill-Down Navigation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#drill-down-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill-Down Navigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Drill-down is VariScout’s core methodology for isolating variation sources through progressive stratification.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"concept\">Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Start with all data, then progressively filter to find where variation concentrates. Filter chips show contribution to TOTAL variation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────────────┘ └────────────────────┘ └────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐│ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │└────────────────────┘ └────────────────────┘ └────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Each chip shows how much of the TOTAL variation that filter captures.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision-thresholds\">Decision Thresholds\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision-thresholds\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision Thresholds”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variation %\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>>50%\u003C/strong>\u003C/td>\u003Ctd>Auto-drill — this is the primary driver\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>>80%\u003C/strong>\u003C/td>\u003Ctd>Strong focus — highly concentrated issue\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>30-50%\u003C/strong>\u003C/td>\u003Ctd>Recommend investigating, ask user\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong><30%\u003C/strong>\u003C/td>\u003Ctd>Multiple factors — check interactions\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"when-to-check-for-interactions\">When to Check for Interactions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-check-for-interactions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Check for Interactions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The drill-down methodology captures \u003Cstrong>main effects\u003C/strong> — how much variation each factor explains independently. But factors can also \u003Cstrong>interact\u003C/strong>:\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Machine C is only problematic on Night shift”\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-guidance-prompt\">The Guidance Prompt\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-guidance-prompt\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Guidance Prompt”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When 2+ factors are in your drill stack, the Investigation Mindmap’s Interaction mode shows factor relationships visually as edges between nodes. The Mindmap also surfaces a guidance prompt:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Analyzing multiple factors? │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Your drill-down shows main effects. To check │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ if factors interact, use the Regression Panel │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ with \"Include interactions\". │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ [Check Interactions →] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌────────────────────────────────────────────────┐│ Analyzing multiple factors? ││ ││ Your drill-down shows main effects. To check ││ if factors interact, use the Regression Panel ││ with "Include interactions". ││ ││ [Check Interactions →] │└────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"when-interactions-matter\">When Interactions Matter\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#when-interactions-matter\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When Interactions Matter”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Scenario\u003C/th>\u003Cth>Recommendation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong><30% variation explained\u003C/strong>\u003C/td>\u003Ctd>Check for interactions — combined effect may be stronger\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Factors seem related\u003C/strong>\u003C/td>\u003Ctd>Machine type + Operator experience often interact\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Action seems ambiguous\u003C/strong>\u003C/td>\u003Ctd>”Fix Machine C” vs “Change Night process” — interaction clarifies\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"statistical-difference\">Statistical Difference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#statistical-difference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Statistical Difference”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Method\u003C/th>\u003Cth>What it captures\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Sequential ANOVA (drill-down)\u003C/td>\u003Ctd>Main effects only (η² per factor)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>GLM with interactions\u003C/td>\u003Ctd>Main effects + two-way interactions\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"../analysis/regression.md#interaction-effects\">Regression Analysis: Interaction Effects\u003C/a> for details.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cumulative-impact\">Cumulative Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cumulative-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cumulative Impact”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The real power is cumulative calculation of contribution percentages:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">FILTER CHIPS CONTRIBUTION TO TOTAL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">─────────────────────────────────────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Shift: Night ▼ 67%] 67% of total variation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Machine: C ▼ 24%] (within Night Shift context)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Operator: Kim ▼ 9%] (within Machine C + Night)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CUMULATIVE: Focused on ~46% of TOTAL variation\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"FILTER CHIPS CONTRIBUTION TO TOTAL─────────────────────────────────────────────────────────[Shift: Night ▼ 67%] 67% of total variation[Machine: C ▼ 24%] (within Night Shift context)[Operator: Kim ▼ 9%] (within Machine C + Night)CUMULATIVE: Focused on ~46% of TOTAL variation\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Result:\u003C/strong> Three filters focus on nearly half of ALL variation in ONE condition.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation\">Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useFilterNavigation, useVariationTracking } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/hooks\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Filter navigation with multi-select support\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterStack\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">applyFilter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeFilter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">clearFilters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hasFilters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } =\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useFilterNavigation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setFilters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">columnAliases\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ enableHistory: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, enableUrlSync: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Variation tracking for filter chip data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterChipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Data for rendering filter chips\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cumulativeVariationPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Total SS scope % in focus\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">impactLevel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 'high' | 'moderate' | 'low'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">factorVariations\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// η² for each factor (internal drill suggestion)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">} = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useVariationTracking\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(rawData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterStack\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factors);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Update filter with multiple values (multi-select)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Machine\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">A\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">C\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">], \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Remove a specific filter\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeFilter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useFilterNavigation, useVariationTracking } from '@variscout/hooks';// Filter navigation with multi-select supportconst { filterStack, applyFilter, updateFilterValues, removeFilter, clearFilters, hasFilters } = useFilterNavigation( { filters, setFilters, columnAliases }, { enableHistory: true, enableUrlSync: true } );// Variation tracking for filter chip dataconst { filterChipData, // Data for rendering filter chips cumulativeVariationPct, // Total SS scope % in focus impactLevel, // 'high' | 'moderate' | 'low' factorVariations, // η² for each factor (internal drill suggestion)} = useVariationTracking(rawData, filterStack, outcome, factors);// Update filter with multiple values (multi-select)updateFilterValues('Machine', ['A', 'C'], 'boxplot');// Remove a specific filterremoveFilter('Shift');\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"user-interaction\">User Interaction\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#user-interaction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Interaction”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>View Boxplot\u003C/strong> - See factor comparison with contribution %\u003C/li>\n\u003Cli>\u003Cstrong>Click category\u003C/strong> - Filter into that factor value\u003C/li>\n\u003Cli>\u003Cstrong>Filter chip appears\u003C/strong> - Shows selected value(s) and contribution %\u003C/li>\n\u003Cli>\u003Cstrong>Click chip dropdown\u003C/strong> - Select/deselect additional values\u003C/li>\n\u003Cli>\u003Cstrong>Repeat\u003C/strong> - Until actionable condition found\u003C/li>\n\u003Cli>\u003Cstrong>Remove filter\u003C/strong> - Click X or use “Remove Filter” in dropdown\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"multi-select-workflow\">Multi-Select Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#multi-select-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Multi-Select Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Filter chips support selecting multiple values within a factor:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Single value selection (traditional drill)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">applyFilter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">type: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">filter\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">source: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values: [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Night\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Add another value (multi-select)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Night\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Day\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">], \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Remove one value, keep the other\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Night\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">], \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Remove filter entirely\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeFilter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Single value selection (traditional drill)applyFilter({ type: 'filter', source: 'boxplot', factor: 'Shift', values: ['Night'],});// Add another value (multi-select)updateFilterValues('Shift', ['Night', 'Day'], 'boxplot');// Remove one value, keep the otherupdateFilterValues('Shift', ['Night'], 'boxplot');// Remove filter entirelyremoveFilter('Shift');\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/drilldown.md\">Four Lenses: Drill-Down\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"breadcrumbs.md\">Filter Chips\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"linked-filtering.md\">Linked Filtering\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7156, + "localImagePaths": 7186, + "remoteImagePaths": 7187, + "frontmatter": 7188, + "imagePaths": 7189 + }, + [7157, 7159, 7162, 7163, 7166, 7169, 7172, 7175, 7178, 7179, 7182, 7185], + { "depth": 30, "slug": 7158, "text": 7146 }, + "drill-down-navigation", + { "depth": 33, "slug": 7160, "text": 7161 }, + "concept", + "Concept", + { "depth": 33, "slug": 6153, "text": 6154 }, + { "depth": 33, "slug": 7164, "text": 7165 }, + "when-to-check-for-interactions", + "When to Check for Interactions", + { "depth": 79, "slug": 7167, "text": 7168 }, + "the-guidance-prompt", + "The Guidance Prompt", + { "depth": 79, "slug": 7170, "text": 7171 }, + "when-interactions-matter", + "When Interactions Matter", + { "depth": 79, "slug": 7173, "text": 7174 }, + "statistical-difference", + "Statistical Difference", + { "depth": 33, "slug": 7176, "text": 7177 }, + "cumulative-impact", + "Cumulative Impact", + { "depth": 33, "slug": 1885, "text": 1886 }, + { "depth": 33, "slug": 7180, "text": 7181 }, + "user-interaction", + "User Interaction", + { "depth": 33, "slug": 7183, "text": 7184 }, + "multi-select-workflow", + "Multi-Select Workflow", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 7146 }, + [], + "03-features/navigation/linked-filtering", + { "id": 7190, "data": 7192, "body": 7196, "filePath": 7197, "digest": 7198, "rendered": 7199 }, + { + "title": 6359, + "editUrl": 16, + "head": 7193, + "template": 18, + "sidebar": 7194, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 7195 }, + {}, + "# Linked Filtering\n\nLinked filtering connects all charts so clicking one filters all others.\n\n---\n\n## Concept\n\nWhen you click on one chart, all others respond:\n\n| Action | System Response |\n| ---------------------------- | ---------------------------------------------------------- |\n| Click \"Machine B\" in Boxplot | I-Chart shows only Machine B's timeline |\n| | Pareto shows only Machine B's failure modes |\n| | Capability recalculates for Machine B alone |\n| Click \"Above UCL\" in I-Chart | Boxplot highlights which factors had out-of-control points |\n| | Pareto shows defect types during unstable periods |\n\n---\n\n## Why It Matters\n\nThis isn't just a UI feature — it's how the Four Lenses interconnect:\n\n```\n ┌─────────┐\n │ CHANGE │ ← Click a time region\n │(I-Chart)│\n └────┬────┘\n │\n ▼\n┌─────────┐ ┌─────────┐\n│ FLOW │◄───►│ FAILURE │ ← See which factors/failures\n│(Boxplot)│ │(Pareto) │ were active then\n└────┬────┘ └────┬────┘\n │ │\n └───────┬───────┘\n │\n ▼\n ┌─────────┐\n │ VALUE │ ← Capability updates\n │(Capable)│ for filtered subset\n └─────────┘\n```\n\n---\n\n## Implementation\n\n### State Management\n\n```typescript\nimport { useFilterNavigation, useVariationTracking } from '@variscout/hooks';\n\n// Filter navigation manages active filters\nconst {\n filterStack,\n applyFilter,\n updateFilterValues,\n removeFilter,\n clearFilters,\n hasFilters,\n} = useFilterNavigation(\n { filters, setFilters, columnAliases },\n { enableHistory: true }\n);\n\n// Variation tracking provides filter chip data\nconst { filterChipData, cumulativeVariationPct } = useVariationTracking(\n rawData,\n filterStack,\n outcome,\n factors\n);\n\n// Filters propagate to all charts via filteredData\n\u003CIChart data={filteredData} />\n\u003CBoxplot data={filteredData} />\n\u003CParetoChart data={filteredData} />\n```\n\n### Click Handlers\n\n```typescript\n// Boxplot click handler - single value\nconst handleBoxClick = (factor: string, level: string) => {\n applyFilter({\n type: 'filter',\n source: 'boxplot',\n factor,\n values: [level],\n });\n // All charts automatically re-render with filtered data\n};\n\n// Multi-select handler - toggle value in existing filter\nconst handleMultiSelect = (factor: string, value: string, currentValues: string[]) => {\n const newValues = currentValues.includes(value)\n ? currentValues.filter(v => v !== value)\n : [...currentValues, value];\n updateFilterValues(factor, newValues, 'boxplot');\n};\n```\n\n### Filter Chip Rendering\n\n```typescript\n// Render filter chips from variation tracking\n{filterChipData.map(chip => (\n \u003CFilterChipDropdown\n key={chip.factor}\n factor={chip.factor}\n values={chip.values}\n contributionPct={chip.contributionPct}\n availableValues={chip.availableValues}\n onValuesChange={(newValues) => updateFilterValues(chip.factor, newValues)}\n onRemove={() => removeFilter(chip.factor)}\n />\n))}\n```\n\n---\n\n## Platform Support\n\n| Platform | Implementation |\n| -------- | ----------------------- |\n| PWA | React Context state |\n| Excel | Native Excel slicers |\n| Azure | React Context state |\n| Power BI | Native Power BI slicers |\n\n---\n\n## See Also\n\n- [Drill-Down](drill-down.md)\n- [Filter Chips](breadcrumbs.md)\n- [Four Lenses](../../01-vision/four-lenses/index.md)", + "src/content/docs/03-features/navigation/linked-filtering.md", + "d04b2f9e8403f2c4", + { "html": 7200, "metadata": 7201 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"linked-filtering\">Linked Filtering\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#linked-filtering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Linked Filtering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Linked filtering connects all charts so clicking one filters all others.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"concept\">Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When you click on one chart, all others respond:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>System Response\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Click “Machine B” in Boxplot\u003C/td>\u003Ctd>I-Chart shows only Machine B’s timeline\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003C/td>\u003Ctd>Pareto shows only Machine B’s failure modes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003C/td>\u003Ctd>Capability recalculates for Machine B alone\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Click “Above UCL” in I-Chart\u003C/td>\u003Ctd>Boxplot highlights which factors had out-of-control points\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003C/td>\u003Ctd>Pareto shows defect types during unstable periods\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-it-matters\">Why It Matters\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-it-matters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why It Matters”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This isn’t just a UI feature — it’s how the Four Lenses interconnect:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CHANGE │ ← Click a time region\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│(I-Chart)│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────┬────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────┐ ┌─────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ FLOW │◄───►│ FAILURE │ ← See which factors/failures\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│(Boxplot)│ │(Pareto) │ were active then\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────┬────┘ └────┬────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───────┬───────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ VALUE │ ← Capability updates\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│(Capable)│ for filtered subset\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" ┌─────────┐ │ CHANGE │ ← Click a time region │(I-Chart)│ └────┬────┘ │ ▼┌─────────┐ ┌─────────┐│ FLOW │◄───►│ FAILURE │ ← See which factors/failures│(Boxplot)│ │(Pareto) │ were active then└────┬────┘ └────┬────┘ │ │ └───────┬───────┘ │ ▼ ┌─────────┐ │ VALUE │ ← Capability updates │(Capable)│ for filtered subset └─────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation\">Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"state-management\">State Management\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#state-management\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “State Management”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useFilterNavigation, useVariationTracking } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/hooks\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Filter navigation manages active filters\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterStack\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">applyFilter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeFilter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">clearFilters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hasFilters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">} = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useFilterNavigation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setFilters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">columnAliases\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ enableHistory: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Variation tracking provides filter chip data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterChipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cumulativeVariationPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useVariationTracking\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">rawData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterStack\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Filters propagate to all charts via filteredData\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">IChart data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{filteredData} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Boxplot data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{filteredData} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ParetoChart data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{filteredData} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useFilterNavigation, useVariationTracking } from '@variscout/hooks';// Filter navigation manages active filtersconst { filterStack, applyFilter, updateFilterValues, removeFilter, clearFilters, hasFilters,} = useFilterNavigation( { filters, setFilters, columnAliases }, { enableHistory: true });// Variation tracking provides filter chip dataconst { filterChipData, cumulativeVariationPct } = useVariationTracking( rawData, filterStack, outcome, factors);// Filters propagate to all charts via filteredData\u003CIChart data={filteredData} />\u003CBoxplot data={filteredData} />\u003CParetoChart data={filteredData} />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"click-handlers\">Click Handlers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#click-handlers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Click Handlers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Boxplot click handler - single value\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleBoxClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">level\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">applyFilter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">filter\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">source: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">values:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [level]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// All charts automatically re-render with filtered data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Multi-select handler - toggle value in existing filter\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleMultiSelect\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">currentValues\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">newValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">currentValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">includes\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(value)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">? \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">currentValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filter\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">v\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">v\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> !== \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">currentValues, value]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(factor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">newValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Boxplot click handler - single valueconst handleBoxClick = (factor: string, level: string) => { applyFilter({ type: 'filter', source: 'boxplot', factor, values: [level], }); // All charts automatically re-render with filtered data};// Multi-select handler - toggle value in existing filterconst handleMultiSelect = (factor: string, value: string, currentValues: string[]) => { const newValues = currentValues.includes(value) ? currentValues.filter(v => v !== value) : [...currentValues, value]; updateFilterValues(factor, newValues, 'boxplot');};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filter-chip-rendering\">Filter Chip Rendering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filter-chip-rendering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter Chip Rendering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Render filter chips from variation tracking\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{filterChipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">chip\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">FilterChipDropdown\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chip.factor}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chip.factor}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chip.values}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contributionPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chip.contributionPct}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">availableValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chip.availableValues}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onValuesChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{(newValues) => \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">chip.factor, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">newValues\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onRemove\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{() => \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeFilter\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chip.factor\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Render filter chips from variation tracking{filterChipData.map(chip => ( \u003CFilterChipDropdown key={chip.factor} factor={chip.factor} values={chip.values} contributionPct={chip.contributionPct} availableValues={chip.availableValues} onValuesChange={(newValues) => updateFilterValues(chip.factor, newValues)} onRemove={() => removeFilter(chip.factor)} />))}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-support\">Platform Support\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Support”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Implementation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA\u003C/td>\u003Ctd>React Context state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel\u003C/td>\u003Ctd>Native Excel slicers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure\u003C/td>\u003Ctd>React Context state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Power BI\u003C/td>\u003Ctd>Native Power BI slicers\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"drill-down.md\">Drill-Down\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"breadcrumbs.md\">Filter Chips\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/index.md\">Four Lenses\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7202, + "localImagePaths": 7218, + "remoteImagePaths": 7219, + "frontmatter": 7220, + "imagePaths": 7221 + }, + [7203, 7204, 7205, 7206, 7207, 7208, 7211, 7214, 7217], + { "depth": 30, "slug": 6358, "text": 6359 }, + { "depth": 33, "slug": 7160, "text": 7161 }, + { "depth": 33, "slug": 6541, "text": 6542 }, + { "depth": 33, "slug": 1885, "text": 1886 }, + { "depth": 79, "slug": 3402, "text": 3403 }, + { "depth": 79, "slug": 7209, "text": 7210 }, + "click-handlers", + "Click Handlers", + { "depth": 79, "slug": 7212, "text": 7213 }, + "filter-chip-rendering", + "Filter Chip Rendering", + { "depth": 33, "slug": 7215, "text": 7216 }, + "platform-support", + "Platform Support", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 6359 }, + [], + "03-features/workflows/decision-trees", + { "id": 7222, "data": 7224, "body": 7229, "filePath": 7230, "digest": 7231, "rendered": 7232 }, + { + "title": 7225, + "editUrl": 16, + "head": 7226, + "template": 18, + "sidebar": 7227, + "pagefind": 16, + "draft": 20 + }, + "Decision Trees", + [], + { "hidden": 20, "attrs": 7228 }, + {}, + "# Decision Trees\n\nFlowcharts to answer common analyst questions: \"Which chart should I use?\" and \"What do I do next?\"\n\n## Which Chart Should I Use?\n\n```mermaid\nflowchart TD\n A[I have data] --> B{What's my question?}\n\n B -->|\"Is it stable over time?\"| C[I-Chart]\n B -->|\"Which factor causes variation?\"| D[Boxplot]\n B -->|\"Where do defects concentrate?\"| E[Pareto]\n B -->|\"Do we meet specs?\"| F[Capability]\n B -->|\"Is X related to Y?\"| G[Regression]\n B -->|\"Compare multiple channels?\"| I[Performance Mode]\n\n C --> C1[\"Shows: Control limits, trends, outliers\"]\n D --> D1[\"Shows: η² contribution, medians, spread\"]\n E --> E1[\"Shows: Ranked categories, 80/20\"]\n F --> F1[\"Shows: Cp, Cpk, histogram vs specs\"]\n G --> G1[\"Shows: Correlation, R², prediction\"]\n I --> I1[\"Shows: All channels ranked by Cpk\"]\n```\n\n## I Found Instability - Now What?\n\n```mermaid\nflowchart TD\n A[I-Chart shows instability] --> B{What pattern?}\n\n B -->|\"Point outside limits\"| C[Single special cause]\n B -->|\"9+ points same side\"| D[Process shifted]\n B -->|\"Trend up or down\"| E[Gradual drift]\n B -->|\"Cycles/waves\"| F[Periodic factor]\n B -->|\"Increasing spread\"| G[Stability degrading]\n\n C --> C1[Investigate that specific point]\n C1 --> C2[What happened at that time?]\n C2 --> C3[Check process logs, material, operator]\n C3 --> C4{Existing factor explains it?}\n C4 -->|Yes| C5[Drill down on that factor]\n C4 -->|No| C6[Brush anomalous points → Create Factor → drill down]\n\n D --> D1[Find when shift occurred]\n D1 --> D2[What changed then?]\n D2 --> D3[Settings, materials, personnel?]\n\n E --> E1[Check for wear or degradation]\n E1 --> E2[Tool wear? Calibration drift?]\n E2 --> E3[Maintenance or recalibration needed]\n\n F --> F1[Look for periodic causes]\n F1 --> F2[Temperature cycles? Shift changes?]\n F2 --> F3[Match cycle length to possible causes]\n\n G --> G1[Process becoming less predictable]\n G1 --> G2[Equipment wearing? Controls failing?]\n G2 --> G3[Major investigation needed]\n```\n\n## High Variation - Which Factor?\n\n```mermaid\nflowchart TD\n A[\"Boxplot: Multiple factors\"] --> B{Which has highest η²?}\n\n B -->|\"One factor dominates (>50%)\"| C[Clear primary driver]\n B -->|\"Two factors similar (30-40% each)\"| D[Possible interaction]\n B -->|\"All factors low (\u003C20%)\"| E[Check for missing factors]\n\n C --> C1[Drill into that factor]\n C1 --> C2[Which level is worst?]\n C2 --> C3[Investigate that specific level]\n\n D --> D1[Check interaction]\n D1 --> D2[Does Factor A effect depend on Factor B?]\n D2 --> D3[Multi-select to test combinations]\n\n E --> E1[Consider what's not in the data]\n E1 --> E2[Material batch? Environment? Supplier?]\n E2 --> E3[Collect additional data or brush anomalous points on I-Chart to create a new factor]\n```\n\n## Poor Capability - Why?\n\n```mermaid\nflowchart TD\n A[\"Cpk \u003C 1.0\"] --> B{Compare Cp vs Cpk}\n\n B -->|\"Cp >> Cpk\"| C[Centering problem]\n B -->|\"Cp ≈ Cpk (both low)\"| D[Spread problem]\n B -->|\"Cp ≈ Cpk (both OK)\"| E[Check histogram]\n\n C --> C1[\"Process off-target\"]\n C1 --> C2[\"Easy fix: adjust setpoint\"]\n C2 --> C3[\"Action: Recenter process\"]\n\n D --> D1[\"Variation too high\"]\n D1 --> D2[\"Need to reduce variation\"]\n D2 --> D3[\"Action: Investigate variation sources\"]\n\n E --> E1[\"Check distribution shape\"]\n E1 --> E2{Shape?}\n E2 -->|\"Bimodal\"| E3[\"Two populations mixed\"]\n E2 -->|\"Skewed\"| E4[\"Non-normal - check specs\"]\n E2 -->|\"Normal\"| E5[\"Re-check calculations\"]\n```\n\n## Defects Increasing - Where to Look?\n\n```mermaid\nflowchart TD\n A[\"Pareto shows defects\"] --> B{What's the pattern?}\n\n B -->|\"One defect type dominates\"| C[Focus on that type]\n B -->|\"Multiple types growing\"| D[Systematic issue]\n B -->|\"New defect appeared\"| E[Something changed]\n\n C --> C1[\"Drill down with filter\"]\n C1 --> C2[\"When/where does it occur?\"]\n C2 --> C3[\"Root cause for specific defect\"]\n\n D --> D1[\"Check common causes\"]\n D1 --> D2[\"Material? Equipment? Training?\"]\n D2 --> D3[\"Broader investigation needed\"]\n\n E --> E1[\"When did it start?\"]\n E1 --> E2[\"What changed then?\"]\n E2 --> E3[\"New process/material/operator?\"]\n```\n\n## Performance Mode - Which Channel?\n\n```mermaid\nflowchart TD\n A[\"Multiple channels\"] --> B{Pattern?}\n\n B -->|\"One clearly worst\"| C[Isolated problem]\n B -->|\"Group of bad channels\"| D[Position-based?]\n B -->|\"All similar (poor)\"| E[Systematic issue]\n B -->|\"All similar (good)\"| F[Equipment qualified]\n\n C --> C1[\"Drill into that channel\"]\n C1 --> C2[\"Use Four Lenses analysis\"]\n C2 --> C3[\"Fix channel-specific issue\"]\n\n D --> D1[\"Check physical arrangement\"]\n D1 --> D2[\"Adjacent channels? Same side?\"]\n D2 --> D3[\"Look for spatial cause\"]\n\n E --> E1[\"Not a channel problem\"]\n E1 --> E2[\"Check common inputs\"]\n E2 --> E3[\"Material, settings, environment\"]\n\n F --> F1[\"Equipment OK\"]\n F1 --> F2[\"Document and monitor\"]\n```\n\n## After Drill-Down - What Action?\n\n```mermaid\nflowchart TD\n A[\"Isolated the problem\"] --> B{What kind of issue?}\n\n B -->|\"One operator different\"| C[Training opportunity]\n B -->|\"One machine different\"| D[Maintenance/setup issue]\n B -->|\"One shift different\"| E[Process condition issue]\n B -->|\"One material batch\"| F[Supplier issue]\n B -->|\"One time period\"| G[Event-based cause]\n\n C --> C1[\"Compare techniques\"]\n C1 --> C2[\"Best practice → Training\"]\n\n D --> D1[\"Compare settings\"]\n D1 --> D2[\"Inspection → Repair/adjust\"]\n\n E --> E1[\"Compare conditions\"]\n E1 --> E2[\"Temperature? Staffing? Volume?\"]\n\n F --> F1[\"Check material properties\"]\n F1 --> F2[\"Incoming inspection? Supplier feedback?\"]\n\n G --> G1[\"Check logs for that period\"]\n G1 --> G2[\"What was unique about that time?\"]\n```\n\n## Quick Reference Card\n\n### Chart Selection\n\n| Question | Chart |\n| ----------------- | ---------------- |\n| Stable over time? | I-Chart |\n| Which factor? | Boxplot |\n| Which defects? | Pareto |\n| Meet specs? | Capability |\n| X vs Y related? | Regression |\n| Compare channels? | Performance Mode |\n\n### Next Steps\n\n| Finding | Action |\n| -------------------- | --------------------------- |\n| Point outside limits | Investigate that sample |\n| High η² factor | Drill down |\n| Poor Cpk | Check Cp vs Cpk |\n| New defect type | Find when it started |\n| Channel worst | Four Lenses on that channel |\n| Operator effect | Consider MSA first |\n\n### Warning Signs\n\n| Sign | Investigate |\n| ------------------ | ----------------- |\n| Bimodal histogram | Mixed populations |\n| Cp >> Cpk | Centering issue |\n| All factors low η² | Missing factor |\n| All channels poor | Systematic cause |\n\n## Related Documentation\n\n- [Four Lenses Workflow](four-lenses-workflow.md)\n- [Drill-Down Workflow](drill-down-workflow.md)\n- [Quick Check](quick-check.md)\n- [Deep Dive](deep-dive.md)", + "src/content/docs/03-features/workflows/decision-trees.md", + "56ca4008c7db38c5", + { "html": 7233, "metadata": 7234 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"decision-trees\">Decision Trees\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#decision-trees\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision Trees”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Flowcharts to answer common analyst questions: “Which chart should I use?” and “What do I do next?”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"which-chart-should-i-use\">Which Chart Should I Use?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#which-chart-should-i-use\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Which Chart Should I Use?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[I have data] --> B{What's my question?}\n\n B -->|\"Is it stable over time?\"| C[I-Chart]\n B -->|\"Which factor causes variation?\"| D[Boxplot]\n B -->|\"Where do defects concentrate?\"| E[Pareto]\n B -->|\"Do we meet specs?\"| F[Capability]\n B -->|\"Is X related to Y?\"| G[Regression]\n B -->|\"Compare multiple channels?\"| I[Performance Mode]\n\n C --> C1[\"Shows: Control limits, trends, outliers\"]\n D --> D1[\"Shows: η² contribution, medians, spread\"]\n E --> E1[\"Shows: Ranked categories, 80/20\"]\n F --> F1[\"Shows: Cp, Cpk, histogram vs specs\"]\n G --> G1[\"Shows: Correlation, R², prediction\"]\n I --> I1[\"Shows: All channels ranked by Cpk\"]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"i-found-instability---now-what\">I Found Instability - Now What?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#i-found-instability---now-what\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “I Found Instability - Now What?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[I-Chart shows instability] --> B{What pattern?}\n\n B -->|\"Point outside limits\"| C[Single special cause]\n B -->|\"9+ points same side\"| D[Process shifted]\n B -->|\"Trend up or down\"| E[Gradual drift]\n B -->|\"Cycles/waves\"| F[Periodic factor]\n B -->|\"Increasing spread\"| G[Stability degrading]\n\n C --> C1[Investigate that specific point]\n C1 --> C2[What happened at that time?]\n C2 --> C3[Check process logs, material, operator]\n C3 --> C4{Existing factor explains it?}\n C4 -->|Yes| C5[Drill down on that factor]\n C4 -->|No| C6[Brush anomalous points → Create Factor → drill down]\n\n D --> D1[Find when shift occurred]\n D1 --> D2[What changed then?]\n D2 --> D3[Settings, materials, personnel?]\n\n E --> E1[Check for wear or degradation]\n E1 --> E2[Tool wear? Calibration drift?]\n E2 --> E3[Maintenance or recalibration needed]\n\n F --> F1[Look for periodic causes]\n F1 --> F2[Temperature cycles? Shift changes?]\n F2 --> F3[Match cycle length to possible causes]\n\n G --> G1[Process becoming less predictable]\n G1 --> G2[Equipment wearing? Controls failing?]\n G2 --> G3[Major investigation needed]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"high-variation---which-factor\">High Variation - Which Factor?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#high-variation---which-factor\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “High Variation - Which Factor?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[\"Boxplot: Multiple factors\"] --> B{Which has highest η²?}\n\n B -->|\"One factor dominates (>50%)\"| C[Clear primary driver]\n B -->|\"Two factors similar (30-40% each)\"| D[Possible interaction]\n B -->|\"All factors low (<20%)\"| E[Check for missing factors]\n\n C --> C1[Drill into that factor]\n C1 --> C2[Which level is worst?]\n C2 --> C3[Investigate that specific level]\n\n D --> D1[Check interaction]\n D1 --> D2[Does Factor A effect depend on Factor B?]\n D2 --> D3[Multi-select to test combinations]\n\n E --> E1[Consider what's not in the data]\n E1 --> E2[Material batch? Environment? Supplier?]\n E2 --> E3[Collect additional data or brush anomalous points on I-Chart to create a new factor]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"poor-capability---why\">Poor Capability - Why?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#poor-capability---why\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Poor Capability - Why?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[\"Cpk < 1.0\"] --> B{Compare Cp vs Cpk}\n\n B -->|\"Cp >> Cpk\"| C[Centering problem]\n B -->|\"Cp ≈ Cpk (both low)\"| D[Spread problem]\n B -->|\"Cp ≈ Cpk (both OK)\"| E[Check histogram]\n\n C --> C1[\"Process off-target\"]\n C1 --> C2[\"Easy fix: adjust setpoint\"]\n C2 --> C3[\"Action: Recenter process\"]\n\n D --> D1[\"Variation too high\"]\n D1 --> D2[\"Need to reduce variation\"]\n D2 --> D3[\"Action: Investigate variation sources\"]\n\n E --> E1[\"Check distribution shape\"]\n E1 --> E2{Shape?}\n E2 -->|\"Bimodal\"| E3[\"Two populations mixed\"]\n E2 -->|\"Skewed\"| E4[\"Non-normal - check specs\"]\n E2 -->|\"Normal\"| E5[\"Re-check calculations\"]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"defects-increasing---where-to-look\">Defects Increasing - Where to Look?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#defects-increasing---where-to-look\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Defects Increasing - Where to Look?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[\"Pareto shows defects\"] --> B{What's the pattern?}\n\n B -->|\"One defect type dominates\"| C[Focus on that type]\n B -->|\"Multiple types growing\"| D[Systematic issue]\n B -->|\"New defect appeared\"| E[Something changed]\n\n C --> C1[\"Drill down with filter\"]\n C1 --> C2[\"When/where does it occur?\"]\n C2 --> C3[\"Root cause for specific defect\"]\n\n D --> D1[\"Check common causes\"]\n D1 --> D2[\"Material? Equipment? Training?\"]\n D2 --> D3[\"Broader investigation needed\"]\n\n E --> E1[\"When did it start?\"]\n E1 --> E2[\"What changed then?\"]\n E2 --> E3[\"New process/material/operator?\"]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performance-mode---which-channel\">Performance Mode - Which Channel?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performance-mode---which-channel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Mode - Which Channel?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[\"Multiple channels\"] --> B{Pattern?}\n\n B -->|\"One clearly worst\"| C[Isolated problem]\n B -->|\"Group of bad channels\"| D[Position-based?]\n B -->|\"All similar (poor)\"| E[Systematic issue]\n B -->|\"All similar (good)\"| F[Equipment qualified]\n\n C --> C1[\"Drill into that channel\"]\n C1 --> C2[\"Use Four Lenses analysis\"]\n C2 --> C3[\"Fix channel-specific issue\"]\n\n D --> D1[\"Check physical arrangement\"]\n D1 --> D2[\"Adjacent channels? Same side?\"]\n D2 --> D3[\"Look for spatial cause\"]\n\n E --> E1[\"Not a channel problem\"]\n E1 --> E2[\"Check common inputs\"]\n E2 --> E3[\"Material, settings, environment\"]\n\n F --> F1[\"Equipment OK\"]\n F1 --> F2[\"Document and monitor\"]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"after-drill-down---what-action\">After Drill-Down - What Action?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#after-drill-down---what-action\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “After Drill-Down - What Action?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[\"Isolated the problem\"] --> B{What kind of issue?}\n\n B -->|\"One operator different\"| C[Training opportunity]\n B -->|\"One machine different\"| D[Maintenance/setup issue]\n B -->|\"One shift different\"| E[Process condition issue]\n B -->|\"One material batch\"| F[Supplier issue]\n B -->|\"One time period\"| G[Event-based cause]\n\n C --> C1[\"Compare techniques\"]\n C1 --> C2[\"Best practice → Training\"]\n\n D --> D1[\"Compare settings\"]\n D1 --> D2[\"Inspection → Repair/adjust\"]\n\n E --> E1[\"Compare conditions\"]\n E1 --> E2[\"Temperature? Staffing? Volume?\"]\n\n F --> F1[\"Check material properties\"]\n F1 --> F2[\"Incoming inspection? Supplier feedback?\"]\n\n G --> G1[\"Check logs for that period\"]\n G1 --> G2[\"What was unique about that time?\"]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"quick-reference-card\">Quick Reference Card\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#quick-reference-card\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Reference Card”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"chart-selection\">Chart Selection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#chart-selection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Selection”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Question\u003C/th>\u003Cth>Chart\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Stable over time?\u003C/td>\u003Ctd>I-Chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Which factor?\u003C/td>\u003Ctd>Boxplot\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Which defects?\u003C/td>\u003Ctd>Pareto\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Meet specs?\u003C/td>\u003Ctd>Capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>X vs Y related?\u003C/td>\u003Ctd>Regression\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Compare channels?\u003C/td>\u003Ctd>Performance Mode\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"next-steps\">Next Steps\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#next-steps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Next Steps”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Finding\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Point outside limits\u003C/td>\u003Ctd>Investigate that sample\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>High η² factor\u003C/td>\u003Ctd>Drill down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Poor Cpk\u003C/td>\u003Ctd>Check Cp vs Cpk\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>New defect type\u003C/td>\u003Ctd>Find when it started\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Channel worst\u003C/td>\u003Ctd>Four Lenses on that channel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Operator effect\u003C/td>\u003Ctd>Consider MSA first\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"warning-signs\">Warning Signs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#warning-signs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Warning Signs”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Sign\u003C/th>\u003Cth>Investigate\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Bimodal histogram\u003C/td>\u003Ctd>Mixed populations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cp >> Cpk\u003C/td>\u003Ctd>Centering issue\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>All factors low η²\u003C/td>\u003Ctd>Missing factor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>All channels poor\u003C/td>\u003Ctd>Systematic cause\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"four-lenses-workflow.md\">Four Lenses Workflow\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"drill-down-workflow.md\">Drill-Down Workflow\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"quick-check.md\">Quick Check\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"deep-dive.md\">Deep Dive\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7235, + "localImagePaths": 7272, + "remoteImagePaths": 7273, + "frontmatter": 7274, + "imagePaths": 7275 + }, + [7236, 7238, 7241, 7244, 7247, 7250, 7253, 7256, 7259, 7262, 7265, 7268, 7271], + { "depth": 30, "slug": 7237, "text": 7225 }, + "decision-trees", + { "depth": 33, "slug": 7239, "text": 7240 }, + "which-chart-should-i-use", + "Which Chart Should I Use?", + { "depth": 33, "slug": 7242, "text": 7243 }, + "i-found-instability---now-what", + "I Found Instability - Now What?", + { "depth": 33, "slug": 7245, "text": 7246 }, + "high-variation---which-factor", + "High Variation - Which Factor?", + { "depth": 33, "slug": 7248, "text": 7249 }, + "poor-capability---why", + "Poor Capability - Why?", + { "depth": 33, "slug": 7251, "text": 7252 }, + "defects-increasing---where-to-look", + "Defects Increasing - Where to Look?", + { "depth": 33, "slug": 7254, "text": 7255 }, + "performance-mode---which-channel", + "Performance Mode - Which Channel?", + { "depth": 33, "slug": 7257, "text": 7258 }, + "after-drill-down---what-action", + "After Drill-Down - What Action?", + { "depth": 33, "slug": 7260, "text": 7261 }, + "quick-reference-card", + "Quick Reference Card", + { "depth": 79, "slug": 7263, "text": 7264 }, + "chart-selection", + "Chart Selection", + { "depth": 79, "slug": 7266, "text": 7267 }, + "next-steps", + "Next Steps", + { "depth": 79, "slug": 7269, "text": 7270 }, + "warning-signs", + "Warning Signs", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 7225 }, + [], + "03-features/workflows/deep-dive", + { "id": 7276, "data": 7278, "body": 7283, "filePath": 7284, "digest": 7285, "rendered": 7286 }, + { + "title": 7279, + "editUrl": 16, + "head": 7280, + "template": 18, + "sidebar": 7281, + "pagefind": 16, + "draft": 20 + }, + "Deep Dive Workflow", + [], + { "hidden": 20, "attrs": 7282 }, + {}, + "# Deep Dive Workflow\n\n\u003C!-- journey-phase: scout -->\n\nA 30-minute systematic investigation pattern for problem-solving.\n\n## Overview\n\nThe Deep Dive is a structured analysis approach for investigating problems. Use it when a Quick Check reveals issues, or when you need to thoroughly understand a process.\n\n## When to Use\n\n- Quick Check found an alert\n- Customer complaint received\n- Process change evaluation\n- Root cause investigation\n- Process improvement project\n- New process qualification\n\n## The 30-Minute Structure\n\n| Phase | Focus | Deliverable |\n| ----------------- | --------------------- | -------------------------- |\n| 1. Baseline | Full dataset overview | Current state summary |\n| 2. Stability | I-Chart analysis | Stability assessment |\n| 3. Stratification | Drill-down workflow | Top variation drivers |\n| 4. Capability | Filtered subset Cpk | Capability of problem area |\n| 5. Documentation | Export findings | Filter path + evidence |\n\n## Phase 1: Baseline (5 minutes)\n\n### Objective\n\nUnderstand what you're working with before diving in.\n\n### Actions\n\n1. **Review the data**\n - How many samples?\n - What time period?\n - Which factors are available?\n\n2. **Check overall metrics**\n - Mean and standard deviation\n - Overall Cpk\n - Total defect count\n\n3. **Note the context**\n - What's the business problem?\n - What changed recently?\n - What do stakeholders expect?\n\n### Deliverable\n\n```\nBASELINE SUMMARY\n───────────────────────────\nSamples: 847\nPeriod: 2024-01-15 to 2024-01-21\nFactors: Shift (3), Operator (5), Machine (4)\n\nOverall Cpk: 0.89 (Poor)\nMean: 100.3g (Target: 100.0g)\nDefects: 42 (5.0%)\n\nContext: Customer complaint about underweight packages\nQuestion: Why is Cpk below 1.0?\n```\n\n## Phase 2: Stability (5 minutes)\n\n### Objective\n\nDetermine if the process is in statistical control.\n\n### Actions\n\n1. **Review I-Chart**\n - Any points outside limits?\n - Any Nelson Rule violations?\n - Patterns or trends?\n\n2. **Identify special causes**\n - When did they occur?\n - How many are there?\n - Single events or recurring?\n\n3. **If special causes don't align with existing factors**\n - Use **point selection** (drag-brush) on the I-Chart to select the anomalous points\n - Click **Create Factor** to name the group\n - This bridges the CHANGE lens (time-series instability) to the FLOW lens (factor-based stratification)\n\n4. **Assess stability**\n - Stable: Common cause variation only\n - Unstable: Special causes present\n\n### Deliverable\n\n```\nSTABILITY ASSESSMENT\n───────────────────────────\nStatus: UNSTABLE\n\nViolations found:\n- 3 points above UCL (samples 45, 189, 567)\n- Run of 9 below mean (samples 200-208)\n\nPattern: Special causes cluster on Day shift\nImplication: Need to investigate Day shift separately\n```\n\n### Decision Point\n\n| Finding | Next Step |\n| -------- | -------------------------------- |\n| Stable | Proceed to stratification |\n| Unstable | Investigate special causes first |\n\n## Phase 3: Stratification (10 minutes)\n\n### Objective\n\nIdentify what factors explain the variation.\n\n### Actions\n\n1. **Review Boxplot η² values**\n - Which factor explains most?\n - Are there multiple significant factors?\n - Enable **Show distribution shape** to check for bimodal patterns before drilling\n\n2. **Drill down systematically**\n - Start with highest η²\n - Apply filter\n - Check remaining factors\n - Continue until 50%+ isolated\n\n3. **Track your path**\n - Note each filter applied\n - Record contribution percentages\n - Watch VariationBar progress\n\n### Drill-Down Record\n\n```\nSTRATIFICATION PATH\n───────────────────────────\nAll data → Cpk: 0.89\n\nFilter: Shift = Day (η² = 42%)\n└─ Cpk: 0.71\n Remaining: Machine (η² = 28%)\n\nFilter: Machine = 3 (η² = 28%)\n└─ Cpk: 0.52\n Remaining: Operator (η² = 12%)\n\nFilter: Operator = New (η² = 12%)\n└─ Cpk: 0.38\n\nTotal variation isolated: 82%\n```\n\n### Interpretation\n\n```\nSTRATIFICATION FINDINGS\n───────────────────────────\nPrimary driver: Day shift + Machine 3 + New Operator\nCombined effect: 82% of variation explained\n\nThis combination represents:\n- 15% of samples\n- But causes most of the capability problems\n```\n\n## Phase 4: Capability (5 minutes)\n\n### Objective\n\nQuantify the impact and identify improvement potential.\n\n### Actions\n\n1. **Check capability at each level**\n - Compare filtered vs unfiltered Cpk\n - Identify where capability fails\n\n2. **Calculate improvement potential**\n - What if we fixed the worst area?\n - What Cpk would we achieve?\n\n3. **Check distribution shape**\n - Normal distribution?\n - Bimodal (mixed populations)?\n - Skewed?\n\n### Capability Analysis\n\n```\nCAPABILITY COMPARISON\n───────────────────────────\nSubset Cpk n\n───────────────────────────────────────────\nAll data 0.89 847\nExcluding Day shift 1.24 412\nExcluding Machine 3 1.18 695\nDay + Machine 3 + New Operator 0.38 127\n\nIMPROVEMENT POTENTIAL\nIf Day/Machine 3/New Operator fixed:\n- Expected Cpk: 1.15 to 1.35\n- Defects reduced by ~70%\n```\n\n## Phase 5: Documentation (5 minutes)\n\n### Objective\n\nCreate actionable output that can be shared and tracked.\n\n### Actions\n\n1. **Summarize findings**\n - What's the root cause?\n - How certain are we?\n - What's the impact?\n\n2. **Export evidence**\n - Filter path used (automatically included via filter context bar on chart copies)\n - Key charts as images (copy chart includes filter provenance)\n - Statistical summary\n\n3. **Recommend actions**\n - What should be fixed?\n - Who owns it?\n - How will we verify?\n\n### Deep Dive Report\n\n```\nDEEP DIVE REPORT\n═══════════════════════════════════════════════════\n\nPROBLEM STATEMENT\nCustomer complaints about underweight packages (5% defect rate)\n\nFINDINGS\nRoot Cause: Machine 3 operated by New Operator on Day shift\nConfidence: High (82% of variation explained)\nImpact: This combination creates 70% of underweight packages\n\nEVIDENCE\n- Filter path: Shift=Day → Machine=3 → Operator=New\n- Cpk drops from 0.89 (overall) to 0.38 (filtered)\n- I-Chart shows special causes during Day shift\n\nANALYSIS\nNew Operator was not trained on Machine 3's specific quirks.\nMachine 3 requires different fill timing due to worn seals.\n\nRECOMMENDED ACTIONS\n1. Train New Operator on Machine 3 setup [Owner: Training]\n2. Schedule Machine 3 seal replacement [Owner: Maintenance]\n3. Re-run analysis after fixes [Owner: Quality]\n\nVERIFICATION CRITERIA\n- Cpk ≥ 1.0 for Day/Machine 3/New Operator subset\n- No points outside control limits\n- Customer complaint rate \u003C 1%\n\nTIMELINE\nTraining: Complete by Friday\nSeal replacement: Complete by end of month\nVerification: 1 week after both actions complete\n\n───────────────────────────────────────────────────\nAnalyst: [Name]\nDate: [Date]\nFilter path: Shift=Day → Machine=3 → Operator=New\n```\n\n## Time Management Tips\n\n| Phase | If Running Short | If Have Extra Time |\n| -------------- | --------------------------- | ------------------------- |\n| Baseline | Focus on key metrics | Explore data distribution |\n| Stability | Note obvious violations | Check all Nelson Rules |\n| Stratification | Stop at 50% explained | Continue to 70%+ |\n| Capability | Compare overall vs filtered | Check Cp vs Cpk |\n| Documentation | Summary only | Full report + charts |\n\n## Integration with Quick Check\n\n```\nQuick Check (5 min) → Alert found\n ↓\nDeep Dive (30 min) → Root cause identified\n ↓\nAction plan → Fix implemented\n ↓\nQuick Check (5 min) → Verify improvement\n```\n\n## When 30 Minutes Isn't Enough\n\n### Extend to 60 Minutes\n\n- More complex problems\n- Multiple interacting factors\n- Need to check interactions\n\n### Split into Sessions\n\n1. Session 1: Baseline + Stability\n2. Session 2: Stratification (more thorough)\n3. Session 3: Capability + Documentation\n\n### Involve Others\n\n- Bring in process experts\n- Review findings with operators\n- Get engineering input\n\n## Checklist\n\n```\nDEEP DIVE CHECKLIST\n═══════════════════════════════════════════════════\n\nPhase 1: Baseline (5 min)\n[ ] Reviewed data scope\n[ ] Noted overall metrics\n[ ] Understood business context\n\nPhase 2: Stability (5 min)\n[ ] Checked I-Chart\n[ ] Identified special causes\n[ ] Assessed stability status\n\nPhase 3: Stratification (10 min)\n[ ] Reviewed all factors\n[ ] Drilled down systematically\n[ ] Isolated 50%+ of variation\n[ ] Recorded filter path\n\nPhase 4: Capability (5 min)\n[ ] Compared filtered vs unfiltered Cpk\n[ ] Calculated improvement potential\n[ ] Checked distribution shape\n\nPhase 5: Documentation (5 min)\n[ ] Summarized findings\n[ ] Exported evidence\n[ ] Recommended actions\n\nTotal time: _____ minutes\n```\n\n## Related Documentation\n\n- [Quick Check Workflow](quick-check.md)\n- [Four Lenses Workflow](four-lenses-workflow.md)\n- [Drill-Down Workflow](drill-down-workflow.md)\n- [Decision Trees](decision-trees.md)", + "src/content/docs/03-features/workflows/deep-dive.md", + "ff6c1faff0dcf5a2", + { "html": 7287, "metadata": 7288 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"deep-dive-workflow\">Deep Dive Workflow\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#deep-dive-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deep Dive Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003C!-- journey-phase: scout -->\n\u003Cp>A 30-minute systematic investigation pattern for problem-solving.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Deep Dive is a structured analysis approach for investigating problems. Use it when a Quick Check reveals issues, or when you need to thoroughly understand a process.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"when-to-use\">When to Use\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-use\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Use”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Quick Check found an alert\u003C/li>\n\u003Cli>Customer complaint received\u003C/li>\n\u003Cli>Process change evaluation\u003C/li>\n\u003Cli>Root cause investigation\u003C/li>\n\u003Cli>Process improvement project\u003C/li>\n\u003Cli>New process qualification\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-30-minute-structure\">The 30-Minute Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-30-minute-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The 30-Minute Structure”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Phase\u003C/th>\u003Cth>Focus\u003C/th>\u003Cth>Deliverable\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1. Baseline\u003C/td>\u003Ctd>Full dataset overview\u003C/td>\u003Ctd>Current state summary\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2. Stability\u003C/td>\u003Ctd>I-Chart analysis\u003C/td>\u003Ctd>Stability assessment\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3. Stratification\u003C/td>\u003Ctd>Drill-down workflow\u003C/td>\u003Ctd>Top variation drivers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4. Capability\u003C/td>\u003Ctd>Filtered subset Cpk\u003C/td>\u003Ctd>Capability of problem area\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5. Documentation\u003C/td>\u003Ctd>Export findings\u003C/td>\u003Ctd>Filter path + evidence\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-1-baseline-5-minutes\">Phase 1: Baseline (5 minutes)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-1-baseline-5-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 1: Baseline (5 minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"objective\">Objective\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#objective\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Objective”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Understand what you’re working with before diving in.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"actions\">Actions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#actions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Actions”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Review the data\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>How many samples?\u003C/li>\n\u003Cli>What time period?\u003C/li>\n\u003Cli>Which factors are available?\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Check overall metrics\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Mean and standard deviation\u003C/li>\n\u003Cli>Overall Cpk\u003C/li>\n\u003Cli>Total defect count\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Note the context\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>What’s the business problem?\u003C/li>\n\u003Cli>What changed recently?\u003C/li>\n\u003Cli>What do stakeholders expect?\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deliverable\">Deliverable\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deliverable\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deliverable”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">BASELINE SUMMARY\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">───────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Samples: 847\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Period: 2024-01-15 to 2024-01-21\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Factors: Shift (3), Operator (5), Machine (4)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Overall Cpk: 0.89 (Poor)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Mean: 100.3g (Target: 100.0g)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Defects: 42 (5.0%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Context: Customer complaint about underweight packages\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Question: Why is Cpk below 1.0?\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"BASELINE SUMMARY───────────────────────────Samples: 847Period: 2024-01-15 to 2024-01-21Factors: Shift (3), Operator (5), Machine (4)Overall Cpk: 0.89 (Poor)Mean: 100.3g (Target: 100.0g)Defects: 42 (5.0%)Context: Customer complaint about underweight packagesQuestion: Why is Cpk below 1.0?\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-2-stability-5-minutes\">Phase 2: Stability (5 minutes)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-stability-5-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2: Stability (5 minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"objective-1\">Objective\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#objective-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Objective”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Determine if the process is in statistical control.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"actions-1\">Actions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#actions-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Actions”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Review I-Chart\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Any points outside limits?\u003C/li>\n\u003Cli>Any Nelson Rule violations?\u003C/li>\n\u003Cli>Patterns or trends?\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Identify special causes\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>When did they occur?\u003C/li>\n\u003Cli>How many are there?\u003C/li>\n\u003Cli>Single events or recurring?\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>If special causes don’t align with existing factors\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Use \u003Cstrong>point selection\u003C/strong> (drag-brush) on the I-Chart to select the anomalous points\u003C/li>\n\u003Cli>Click \u003Cstrong>Create Factor\u003C/strong> to name the group\u003C/li>\n\u003Cli>This bridges the CHANGE lens (time-series instability) to the FLOW lens (factor-based stratification)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Assess stability\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Stable: Common cause variation only\u003C/li>\n\u003Cli>Unstable: Special causes present\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deliverable-1\">Deliverable\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deliverable-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deliverable”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">STABILITY ASSESSMENT\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">───────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Status: UNSTABLE\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Violations found:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- 3 points above UCL (samples 45, 189, 567)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Run of 9 below mean (samples 200-208)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Pattern: Special causes cluster on Day shift\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Implication: Need to investigate Day shift separately\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"STABILITY ASSESSMENT───────────────────────────Status: UNSTABLEViolations found:- 3 points above UCL (samples 45, 189, 567)- Run of 9 below mean (samples 200-208)Pattern: Special causes cluster on Day shiftImplication: Need to investigate Day shift separately\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"decision-point\">Decision Point\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#decision-point\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision Point”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Finding\u003C/th>\u003Cth>Next Step\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Stable\u003C/td>\u003Ctd>Proceed to stratification\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Unstable\u003C/td>\u003Ctd>Investigate special causes first\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-3-stratification-10-minutes\">Phase 3: Stratification (10 minutes)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3-stratification-10-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3: Stratification (10 minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"objective-2\">Objective\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#objective-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Objective”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Identify what factors explain the variation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"actions-2\">Actions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#actions-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Actions”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Review Boxplot η² values\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Which factor explains most?\u003C/li>\n\u003Cli>Are there multiple significant factors?\u003C/li>\n\u003Cli>Enable \u003Cstrong>Show distribution shape\u003C/strong> to check for bimodal patterns before drilling\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Drill down systematically\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Start with highest η²\u003C/li>\n\u003Cli>Apply filter\u003C/li>\n\u003Cli>Check remaining factors\u003C/li>\n\u003Cli>Continue until 50%+ isolated\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Track your path\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Note each filter applied\u003C/li>\n\u003Cli>Record contribution percentages\u003C/li>\n\u003Cli>Watch VariationBar progress\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"drill-down-record\">Drill-Down Record\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#drill-down-record\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill-Down Record”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">STRATIFICATION PATH\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">───────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">All data → Cpk: 0.89\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Filter: Shift = Day (η² = 42%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ Cpk: 0.71\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Remaining: Machine (η² = 28%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Filter: Machine = 3 (η² = 28%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ Cpk: 0.52\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Remaining: Operator (η² = 12%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Filter: Operator = New (η² = 12%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ Cpk: 0.38\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Total variation isolated: 82%\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"STRATIFICATION PATH───────────────────────────All data → Cpk: 0.89Filter: Shift = Day (η² = 42%)└─ Cpk: 0.71 Remaining: Machine (η² = 28%)Filter: Machine = 3 (η² = 28%)└─ Cpk: 0.52 Remaining: Operator (η² = 12%)Filter: Operator = New (η² = 12%)└─ Cpk: 0.38Total variation isolated: 82%\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interpretation\">Interpretation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interpretation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpretation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">STRATIFICATION FINDINGS\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">───────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Primary driver: Day shift + Machine 3 + New Operator\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Combined effect: 82% of variation explained\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">This combination represents:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- 15% of samples\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- But causes most of the capability problems\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"STRATIFICATION FINDINGS───────────────────────────Primary driver: Day shift + Machine 3 + New OperatorCombined effect: 82% of variation explainedThis combination represents:- 15% of samples- But causes most of the capability problems\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-4-capability-5-minutes\">Phase 4: Capability (5 minutes)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-4-capability-5-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 4: Capability (5 minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"objective-3\">Objective\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#objective-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Objective”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Quantify the impact and identify improvement potential.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"actions-3\">Actions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#actions-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Actions”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Check capability at each level\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Compare filtered vs unfiltered Cpk\u003C/li>\n\u003Cli>Identify where capability fails\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Calculate improvement potential\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>What if we fixed the worst area?\u003C/li>\n\u003Cli>What Cpk would we achieve?\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Check distribution shape\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Normal distribution?\u003C/li>\n\u003Cli>Bimodal (mixed populations)?\u003C/li>\n\u003Cli>Skewed?\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"capability-analysis\">Capability Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#capability-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CAPABILITY COMPARISON\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">───────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Subset Cpk n\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">───────────────────────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">All data 0.89 847\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Excluding Day shift 1.24 412\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Excluding Machine 3 1.18 695\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Day + Machine 3 + New Operator 0.38 127\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">IMPROVEMENT POTENTIAL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">If Day/Machine 3/New Operator fixed:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Expected Cpk: 1.15 to 1.35\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Defects reduced by ~70%\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"CAPABILITY COMPARISON───────────────────────────Subset Cpk n───────────────────────────────────────────All data 0.89 847Excluding Day shift 1.24 412Excluding Machine 3 1.18 695Day + Machine 3 + New Operator 0.38 127IMPROVEMENT POTENTIALIf Day/Machine 3/New Operator fixed:- Expected Cpk: 1.15 to 1.35- Defects reduced by ~70%\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"phase-5-documentation-5-minutes\">Phase 5: Documentation (5 minutes)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#phase-5-documentation-5-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 5: Documentation (5 minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"objective-4\">Objective\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#objective-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Objective”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Create actionable output that can be shared and tracked.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"actions-4\">Actions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#actions-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Actions”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Summarize findings\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>What’s the root cause?\u003C/li>\n\u003Cli>How certain are we?\u003C/li>\n\u003Cli>What’s the impact?\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Export evidence\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Filter path used (automatically included via filter context bar on chart copies)\u003C/li>\n\u003Cli>Key charts as images (copy chart includes filter provenance)\u003C/li>\n\u003Cli>Statistical summary\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Recommend actions\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>What should be fixed?\u003C/li>\n\u003Cli>Who owns it?\u003C/li>\n\u003Cli>How will we verify?\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deep-dive-report\">Deep Dive Report\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deep-dive-report\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deep Dive Report”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DEEP DIVE REPORT\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">═══════════════════════════════════════════════════\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PROBLEM STATEMENT\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Customer complaints about underweight packages (5% defect rate)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">FINDINGS\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Root Cause: Machine 3 operated by New Operator on Day shift\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Confidence: High (82% of variation explained)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Impact: This combination creates 70% of underweight packages\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">EVIDENCE\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Filter path: Shift=Day → Machine=3 → Operator=New\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Cpk drops from 0.89 (overall) to 0.38 (filtered)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- I-Chart shows special causes during Day shift\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">ANALYSIS\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">New Operator was not trained on Machine 3's specific quirks.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Machine 3 requires different fill timing due to worn seals.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">RECOMMENDED ACTIONS\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">1. Train New Operator on Machine 3 setup [Owner: Training]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">2. Schedule Machine 3 seal replacement [Owner: Maintenance]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">3. Re-run analysis after fixes [Owner: Quality]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">VERIFICATION CRITERIA\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Cpk ≥ 1.0 for Day/Machine 3/New Operator subset\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- No points outside control limits\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">- Customer complaint rate < 1%\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">TIMELINE\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Training: Complete by Friday\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Seal replacement: Complete by end of month\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Verification: 1 week after both actions complete\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">───────────────────────────────────────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Analyst: [Name]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Date: [Date]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Filter path: Shift=Day → Machine=3 → Operator=New\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DEEP DIVE REPORT═══════════════════════════════════════════════════PROBLEM STATEMENTCustomer complaints about underweight packages (5% defect rate)FINDINGSRoot Cause: Machine 3 operated by New Operator on Day shiftConfidence: High (82% of variation explained)Impact: This combination creates 70% of underweight packagesEVIDENCE- Filter path: Shift=Day → Machine=3 → Operator=New- Cpk drops from 0.89 (overall) to 0.38 (filtered)- I-Chart shows special causes during Day shiftANALYSISNew Operator was not trained on Machine 3's specific quirks.Machine 3 requires different fill timing due to worn seals.RECOMMENDED ACTIONS1. Train New Operator on Machine 3 setup [Owner: Training]2. Schedule Machine 3 seal replacement [Owner: Maintenance]3. Re-run analysis after fixes [Owner: Quality]VERIFICATION CRITERIA- Cpk ≥ 1.0 for Day/Machine 3/New Operator subset- No points outside control limits- Customer complaint rate \u003C 1%TIMELINETraining: Complete by FridaySeal replacement: Complete by end of monthVerification: 1 week after both actions complete───────────────────────────────────────────────────Analyst: [Name]Date: [Date]Filter path: Shift=Day → Machine=3 → Operator=New\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"time-management-tips\">Time Management Tips\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#time-management-tips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Time Management Tips”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Phase\u003C/th>\u003Cth>If Running Short\u003C/th>\u003Cth>If Have Extra Time\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Baseline\u003C/td>\u003Ctd>Focus on key metrics\u003C/td>\u003Ctd>Explore data distribution\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Stability\u003C/td>\u003Ctd>Note obvious violations\u003C/td>\u003Ctd>Check all Nelson Rules\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Stratification\u003C/td>\u003Ctd>Stop at 50% explained\u003C/td>\u003Ctd>Continue to 70%+\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability\u003C/td>\u003Ctd>Compare overall vs filtered\u003C/td>\u003Ctd>Check Cp vs Cpk\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Documentation\u003C/td>\u003Ctd>Summary only\u003C/td>\u003Ctd>Full report + charts\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"integration-with-quick-check\">Integration with Quick Check\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#integration-with-quick-check\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integration with Quick Check”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Quick Check (5 min) → Alert found\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Deep Dive (30 min) → Root cause identified\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Action plan → Fix implemented\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Quick Check (5 min) → Verify improvement\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Quick Check (5 min) → Alert found ↓Deep Dive (30 min) → Root cause identified ↓Action plan → Fix implemented ↓Quick Check (5 min) → Verify improvement\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"when-30-minutes-isnt-enough\">When 30 Minutes Isn’t Enough\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#when-30-minutes-isnt-enough\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When 30 Minutes Isn’t Enough”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"extend-to-60-minutes\">Extend to 60 Minutes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#extend-to-60-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Extend to 60 Minutes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>More complex problems\u003C/li>\n\u003Cli>Multiple interacting factors\u003C/li>\n\u003Cli>Need to check interactions\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"split-into-sessions\">Split into Sessions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#split-into-sessions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Split into Sessions”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Session 1: Baseline + Stability\u003C/li>\n\u003Cli>Session 2: Stratification (more thorough)\u003C/li>\n\u003Cli>Session 3: Capability + Documentation\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"involve-others\">Involve Others\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#involve-others\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Involve Others”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Bring in process experts\u003C/li>\n\u003Cli>Review findings with operators\u003C/li>\n\u003Cli>Get engineering input\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"checklist\">Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DEEP DIVE CHECKLIST\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">═══════════════════════════════════════════════════\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Phase 1: Baseline (5 min)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Reviewed data scope\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Noted overall metrics\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Understood business context\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Phase 2: Stability (5 min)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Checked I-Chart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Identified special causes\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Assessed stability status\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Phase 3: Stratification (10 min)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Reviewed all factors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Drilled down systematically\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Isolated 50%+ of variation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Recorded filter path\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Phase 4: Capability (5 min)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Compared filtered vs unfiltered Cpk\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Calculated improvement potential\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Checked distribution shape\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Phase 5: Documentation (5 min)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Summarized findings\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Exported evidence\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Recommended actions\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Total time: _____ minutes\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DEEP DIVE CHECKLIST═══════════════════════════════════════════════════Phase 1: Baseline (5 min)[ ] Reviewed data scope[ ] Noted overall metrics[ ] Understood business contextPhase 2: Stability (5 min)[ ] Checked I-Chart[ ] Identified special causes[ ] Assessed stability statusPhase 3: Stratification (10 min)[ ] Reviewed all factors[ ] Drilled down systematically[ ] Isolated 50%+ of variation[ ] Recorded filter pathPhase 4: Capability (5 min)[ ] Compared filtered vs unfiltered Cpk[ ] Calculated improvement potential[ ] Checked distribution shapePhase 5: Documentation (5 min)[ ] Summarized findings[ ] Exported evidence[ ] Recommended actionsTotal time: _____ minutes\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"quick-check.md\">Quick Check Workflow\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"four-lenses-workflow.md\">Four Lenses Workflow\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"drill-down-workflow.md\">Drill-Down Workflow\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"decision-trees.md\">Decision Trees\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7289, + "localImagePaths": 7372, + "remoteImagePaths": 7373, + "frontmatter": 7374, + "imagePaths": 7375 + }, + [ + 7290, 7292, 7293, 7294, 7297, 7300, 7303, 7306, 7309, 7312, 7314, 7316, 7318, 7321, 7324, 7326, + 7328, 7331, 7332, 7335, 7337, 7339, 7340, 7343, 7345, 7347, 7350, 7353, 7356, 7359, 7362, 7365, + 7368, 7371 + ], + { "depth": 30, "slug": 7291, "text": 7279 }, + "deep-dive-workflow", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 6509, "text": 6510 }, + { "depth": 33, "slug": 7295, "text": 7296 }, + "the-30-minute-structure", + "The 30-Minute Structure", + { "depth": 33, "slug": 7298, "text": 7299 }, + "phase-1-baseline-5-minutes", + "Phase 1: Baseline (5 minutes)", + { "depth": 79, "slug": 7301, "text": 7302 }, + "objective", + "Objective", + { "depth": 79, "slug": 7304, "text": 7305 }, + "actions", + "Actions", + { "depth": 79, "slug": 7307, "text": 7308 }, + "deliverable", + "Deliverable", + { "depth": 33, "slug": 7310, "text": 7311 }, + "phase-2-stability-5-minutes", + "Phase 2: Stability (5 minutes)", + { "depth": 79, "slug": 7313, "text": 7302 }, + "objective-1", + { "depth": 79, "slug": 7315, "text": 7305 }, + "actions-1", + { "depth": 79, "slug": 7317, "text": 7308 }, + "deliverable-1", + { "depth": 79, "slug": 7319, "text": 7320 }, + "decision-point", + "Decision Point", + { "depth": 33, "slug": 7322, "text": 7323 }, + "phase-3-stratification-10-minutes", + "Phase 3: Stratification (10 minutes)", + { "depth": 79, "slug": 7325, "text": 7302 }, + "objective-2", + { "depth": 79, "slug": 7327, "text": 7305 }, + "actions-2", + { "depth": 79, "slug": 7329, "text": 7330 }, + "drill-down-record", + "Drill-Down Record", + { "depth": 79, "slug": 6346, "text": 6347 }, + { "depth": 33, "slug": 7333, "text": 7334 }, + "phase-4-capability-5-minutes", + "Phase 4: Capability (5 minutes)", + { "depth": 79, "slug": 7336, "text": 7302 }, + "objective-3", + { "depth": 79, "slug": 7338, "text": 7305 }, + "actions-3", + { "depth": 79, "slug": 983, "text": 984 }, + { "depth": 33, "slug": 7341, "text": 7342 }, + "phase-5-documentation-5-minutes", + "Phase 5: Documentation (5 minutes)", + { "depth": 79, "slug": 7344, "text": 7302 }, + "objective-4", + { "depth": 79, "slug": 7346, "text": 7305 }, + "actions-4", + { "depth": 79, "slug": 7348, "text": 7349 }, + "deep-dive-report", + "Deep Dive Report", + { "depth": 33, "slug": 7351, "text": 7352 }, + "time-management-tips", + "Time Management Tips", + { "depth": 33, "slug": 7354, "text": 7355 }, + "integration-with-quick-check", + "Integration with Quick Check", + { "depth": 33, "slug": 7357, "text": 7358 }, + "when-30-minutes-isnt-enough", + "When 30 Minutes Isn’t Enough", + { "depth": 79, "slug": 7360, "text": 7361 }, + "extend-to-60-minutes", + "Extend to 60 Minutes", + { "depth": 79, "slug": 7363, "text": 7364 }, + "split-into-sessions", + "Split into Sessions", + { "depth": 79, "slug": 7366, "text": 7367 }, + "involve-others", + "Involve Others", + { "depth": 33, "slug": 7369, "text": 7370 }, + "checklist", + "Checklist", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 7279 }, + [], + "03-features/workflows/drill-down-workflow", + { "id": 7376, "data": 7378, "body": 7383, "filePath": 7384, "digest": 7385, "rendered": 7386 }, + { + "title": 7379, + "editUrl": 16, + "head": 7380, + "template": 18, + "sidebar": 7381, + "pagefind": 16, + "draft": 20 + }, + "Drill-Down Analysis Workflow", + [], + { "hidden": 20, "attrs": 7382 }, + {}, + "# Drill-Down Analysis Workflow\n\n\u003C!-- journey-phase: scout -->\n\nVariScout's signature interaction pattern—progressive stratification using filter chips to isolate variation sources.\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Ctrl+V in paste area\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Analyze Data\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Map Columns\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Outcome + 2 factors + \"Start\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">4 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read ANOVA\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Check eta-squared under Boxplot\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Filter Top Factor\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click highest-eta bar\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Filtered\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Variation explained? Cpk improved?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">8 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~5 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\n_See [all process maps](process-maps.md) for PWA and Azure variants._\n\n## Overview\n\nDrill-down analysis lets you progressively filter data to isolate specific variation sources. Each filter shows how much variation it explains, building a cumulative picture of your data.\n\n## The Drill-Down Pattern\n\n```mermaid\nflowchart TD\n A[Start: All data] --> B[Boxplot shows η² by factor]\n B --> C[Click highest η² factor value]\n C --> D[Filter applied]\n D --> E[\"Filter chip shows: Factor: Value ▼ XX%\"]\n E --> F[All charts update to subset]\n F --> G{Enough variation isolated?}\n G -->|\">50%\"| H[Actionable insight found]\n G -->|\"\u003C50%\"| I[Continue drilling]\n I --> B\n H --> J[Document finding]\n J --> K[Plan action]\n```\n\n## Filter Chips\n\n### What They Show\n\nWhen you apply a filter, a chip appears showing:\n\n```\n[Shift: Night ▼ 46%] [Operator: B ▼ 23%] [Machine: 3 ▼ 15%]\n```\n\n| Component | Meaning |\n| ----------- | ------------------------- |\n| Factor name | The column being filtered |\n| Value | The selected level |\n| ▼ | Click to remove |\n| Percentage | Variation contribution |\n\n### Contribution Percentage\n\nThe percentage on each chip shows that factor's **contribution to variation**:\n\n- Calculated as η² (eta-squared)\n- Shows proportion of variance explained\n- Helps prioritize which factors matter most\n\n:::note[Cumulative vs Individual]\nEach chip shows its individual contribution. The VariationBar and Investigation Mindmap footer show cumulative progress.\n:::\n\n## Tracking Your Investigation\n\nTwo mechanisms track your cumulative progress as you drill down:\n\n**VariationBar** — A horizontal progress bar visible above the charts showing the cumulative percentage of total variation currently in focus. As you apply filters, the bar fills to reflect how much of the overall variation your current filter path accounts for.\n\n**Investigation Mindmap footer** — The Mindmap's progress footer displays the same cumulative percentage alongside the drill trail, giving you a spatial view of your investigation path and how much variation each step captured.\n\nTogether, these tell you whether your drill-down has isolated enough variation to act on or whether further filtering is needed.\n\n### Interpreting Cumulative Progress\n\n| Variation outside focus | Interpretation |\n| ----------------------- | ------------------------- |\n| > 50% remaining | More drilling needed |\n| 30-50% remaining | Significant factors found |\n| \u003C 30% remaining | Good isolation |\n| \u003C 15% remaining | Common cause only |\n\n## Single-Select vs Multi-Select\n\n### Single-Select (Default)\n\nClick a value to filter to just that level:\n\n```\nShift: Night ▼ 46%\n```\n\n- Shows only Night shift data\n- Good for focusing on one problem area\n\n### Multi-Select\n\nHold Ctrl/Cmd and click multiple values:\n\n```\nShift: Night, Evening ▼ 52%\n```\n\n- Shows data from both shifts\n- Useful for comparing similar groups\n- Combined contribution may be higher\n\n## The Drill-Down Process\n\n### Step 1: Start with Full Data\n\nView the Boxplot with all data. Note which factor has highest η². Consider enabling **Show distribution shape** in Settings to reveal bimodal distributions before filtering.\n\n### Step 2: Click to Filter\n\nClick on the bar (or box) for the level you want to investigate:\n\n- Click the **highest** level to isolate the biggest contributor\n- Click an **outlier** level to focus on the problem area\n- Click a **good** level to understand what works\n\n### Step 3: Observe Changes\n\nAfter filtering:\n\n- Filter chip appears with contribution %\n- All charts update to show filtered subset\n- Boxplot recalculates η² for remaining factors\n- Capability shows filtered Cpk\n\n### Step 4: Continue or Stop\n\n**Continue drilling if:**\n\n- Still significant variation unexplained\n- Next factor has meaningful η² (> 10%)\n- Enough data remains for analysis (n > 20)\n\n**Stop drilling when:**\n\n- Variation sufficiently isolated (> 50-70%)\n- Remaining variation is common cause\n- Data too sparse for reliable statistics\n- Actionable insight found\n\n### Step 5: Document Path\n\nRecord your filter path for:\n\n- Reproducing the analysis\n- Explaining to others\n- Tracking improvements\n\n```\nFilter path: Shift=Night → Operator=B → Machine=3\nResult: Isolated 84% of variation\nFinding: Machine 3 accounts for most off-spec production on night shift\n```\n\n## Example: Coffee Case Study\n\n### Starting Point\n\nFull dataset: Fill weight variation\n\n| Factor | η² | Interpretation |\n| -------- | --- | ------------------- |\n| Batch | 45% | Biggest contributor |\n| Operator | 18% | Moderate |\n| Time | 12% | Some effect |\n\n### Drill-Down Sequence\n\n**Filter 1: Batch = 3**\n\n```\n[Batch: 3 ▼ 45%]\n```\n\nRemaining factors:\n\n| Factor | η² |\n| -------- | --- |\n| Operator | 32% |\n| Time | 8% |\n\nBatch 3 was different—now Operator is more prominent.\n\n**Filter 2: Operator = New**\n\n```\n[Batch: 3 ▼ 45%] [Operator: New ▼ 32%]\n```\n\nRemaining factors:\n\n| Factor | η² |\n| ------ | --- |\n| Time | 15% |\n\nCumulative: 77% isolated\n\n**Result**\n\n- New operator on Batch 3 explains most variation\n- Training opportunity identified\n- Time effect (15%) is shift-related—secondary factor\n\n## When to Use Multi-Select\n\n### Comparing Groups\n\nSelect multiple \"good\" values to establish baseline:\n\n```\n[Operator: A, C, D ▼ 8%] ← Combined good operators\n```\n\nThen compare against the excluded \"problem\" level.\n\n### Excluding Outliers\n\nSelect \"normal\" values to see process without anomalies:\n\n```\n[Shift: Day, Evening ▼ 52%] ← Excluding Night shift\n```\n\n### Investigating Interactions\n\nSelect combinations to test interaction effects:\n\n```\n[Shift: Night ▼] [Operator: New ▼]\n```\n\nvs\n\n```\n[Shift: Day ▼] [Operator: New ▼]\n```\n\nDoes new operator perform differently by shift?\n\n## Best Practices\n\n### Do\n\n- Start with the highest η² factor\n- Note the cumulative variation as you drill\n- Check Cpk at each level\n- Verify sample size remains adequate\n- Document your filter path\n\n### Don't\n\n- Don't drill too deep (sparse data)\n- Don't ignore factors with moderate η²\n- Don't forget to check stability at each level\n- Don't over-interpret small samples\n\n## Reading Chart Updates\n\n### Boxplot After Filtering\n\n- Shows remaining factors for filtered subset\n- η² values recalculated\n- May reveal hidden factors\n\n### I-Chart After Filtering\n\n- Shows only filtered time series\n- Control limits recalculated\n- May reveal pattern previously masked\n\n### Capability After Filtering\n\n- Shows Cpk for filtered subset\n- Compare to overall Cpk\n- Helps quantify factor impact\n\n### Pareto After Filtering\n\n- Shows defect types for filtered subset\n- May reveal concentrated failure modes\n- Connects variation to specific problems\n\n## Navigating Back\n\n### Remove Single Filter\n\nClick the ▼ on any filter chip to remove it.\n\n### Clear All Filters\n\nClick \"Clear all\" to return to full dataset.\n\n### Breadcrumb Navigation\n\nUse breadcrumbs to jump to any point in drill path:\n\n```\nAll Data > Shift: Night > Operator: B\n```\n\nClick \"Shift: Night\" to remove Operator filter but keep Shift.\n\n## Related Documentation\n\n- [Four Lenses Workflow](four-lenses-workflow.md)\n- [Linked Filtering](../navigation/linked-filtering.md)\n- [Breadcrumbs](../navigation/breadcrumbs.md)\n- [Boxplot Feature](../analysis/boxplot.md)", + "src/content/docs/03-features/workflows/drill-down-workflow.md", + "69c3c1b3481a5c3d", + { "html": 7387, "metadata": 7388 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"drill-down-analysis-workflow\">Drill-Down Analysis Workflow\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#drill-down-analysis-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill-Down Analysis Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003C!-- journey-phase: scout -->\n\u003Cp>VariScout’s signature interaction pattern—progressive stratification using filter chips to isolate variation sources.\u003C/p>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Ctrl+V in paste area\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Analyze Data\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Map Columns\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Outcome + 2 factors + \"Start\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">4 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read ANOVA\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Check eta-squared under Boxplot\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Filter Top Factor\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click highest-eta bar\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Filtered\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Variation explained? Cpk improved?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">8 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~5 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>\u003Cem>See \u003Ca href=\"process-maps.md\">all process maps\u003C/a> for PWA and Azure variants.\u003C/em>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Drill-down analysis lets you progressively filter data to isolate specific variation sources. Each filter shows how much variation it explains, building a cumulative picture of your data.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-drill-down-pattern\">The Drill-Down Pattern\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-drill-down-pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Drill-Down Pattern”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Start: All data] --> B[Boxplot shows η² by factor]\n B --> C[Click highest η² factor value]\n C --> D[Filter applied]\n D --> E[\"Filter chip shows: Factor: Value ▼ XX%\"]\n E --> F[All charts update to subset]\n F --> G{Enough variation isolated?}\n G -->|\">50%\"| H[Actionable insight found]\n G -->|\"<50%\"| I[Continue drilling]\n I --> B\n H --> J[Document finding]\n J --> K[Plan action]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"filter-chips\">Filter Chips\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#filter-chips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter Chips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-they-show\">What They Show\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-they-show\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What They Show”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When you apply a filter, a chip appears showing:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Shift: Night ▼ 46%] [Operator: B ▼ 23%] [Machine: 3 ▼ 15%]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Shift: Night ▼ 46%] [Operator: B ▼ 23%] [Machine: 3 ▼ 15%]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Factor name\u003C/td>\u003Ctd>The column being filtered\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Value\u003C/td>\u003Ctd>The selected level\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>▼\u003C/td>\u003Ctd>Click to remove\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Percentage\u003C/td>\u003Ctd>Variation contribution\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"contribution-percentage\">Contribution Percentage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#contribution-percentage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Contribution Percentage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The percentage on each chip shows that factor’s \u003Cstrong>contribution to variation\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Calculated as η² (eta-squared)\u003C/li>\n\u003Cli>Shows proportion of variance explained\u003C/li>\n\u003Cli>Helps prioritize which factors matter most\u003C/li>\n\u003C/ul>\n\u003Caside aria-label=\"Cumulative vs Individual\" class=\"starlight-aside starlight-aside--note\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath d=\"M12 11C11.7348 11 11.4804 11.1054 11.2929 11.2929C11.1054 11.4804 11 11.7348 11 12V16C11 16.2652 11.1054 16.5196 11.2929 16.7071C11.4804 16.8946 11.7348 17 12 17C12.2652 17 12.5196 16.8946 12.7071 16.7071C12.8946 16.5196 13 16.2652 13 16V12C13 11.7348 12.8946 11.4804 12.7071 11.2929C12.5196 11.1054 12.2652 11 12 11ZM12.38 7.08C12.1365 6.97998 11.8635 6.97998 11.62 7.08C11.4973 7.12759 11.3851 7.19896 11.29 7.29C11.2017 7.3872 11.1306 7.49882 11.08 7.62C11.024 7.73868 10.9966 7.86882 11 8C10.9992 8.13161 11.0245 8.26207 11.0742 8.38391C11.124 8.50574 11.1973 8.61656 11.29 8.71C11.3872 8.79833 11.4988 8.86936 11.62 8.92C11.7715 8.98224 11.936 9.00632 12.099 8.99011C12.2619 8.97391 12.4184 8.91792 12.5547 8.82707C12.691 8.73622 12.8029 8.61328 12.8805 8.46907C12.9582 8.32486 12.9992 8.16378 13 8C12.9963 7.73523 12.8927 7.48163 12.71 7.29C12.6149 7.19896 12.5028 7.12759 12.38 7.08ZM12 2C10.0222 2 8.08879 2.58649 6.4443 3.6853C4.79981 4.78412 3.51809 6.3459 2.76121 8.17317C2.00433 10.0004 1.8063 12.0111 2.19215 13.9509C2.578 15.8907 3.53041 17.6725 4.92894 19.0711C6.32746 20.4696 8.10929 21.422 10.0491 21.8079C11.9889 22.1937 13.9996 21.9957 15.8268 21.2388C17.6541 20.4819 19.2159 19.2002 20.3147 17.5557C21.4135 15.9112 22 13.9778 22 12C22 10.6868 21.7413 9.38642 21.2388 8.17317C20.7363 6.95991 19.9997 5.85752 19.0711 4.92893C18.1425 4.00035 17.0401 3.26375 15.8268 2.7612C14.6136 2.25866 13.3132 2 12 2ZM12 20C10.4178 20 8.87104 19.5308 7.55544 18.6518C6.23985 17.7727 5.21447 16.5233 4.60897 15.0615C4.00347 13.5997 3.84504 11.9911 4.15372 10.4393C4.4624 8.88743 5.22433 7.46197 6.34315 6.34315C7.46197 5.22433 8.88743 4.4624 10.4393 4.15372C11.9911 3.84504 13.5997 4.00346 15.0615 4.60896C16.5233 5.21447 17.7727 6.23984 18.6518 7.55544C19.5308 8.87103 20 10.4177 20 12C20 14.1217 19.1572 16.1566 17.6569 17.6569C16.1566 19.1571 14.1217 20 12 20Z\">\u003C/path>\u003C/svg>Cumulative vs Individual\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>Each chip shows its individual contribution. The VariationBar and Investigation Mindmap footer show cumulative progress.\u003C/p>\u003C/div>\u003C/aside>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tracking-your-investigation\">Tracking Your Investigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tracking-your-investigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tracking Your Investigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Two mechanisms track your cumulative progress as you drill down:\u003C/p>\n\u003Cp>\u003Cstrong>VariationBar\u003C/strong> — A horizontal progress bar visible above the charts showing the cumulative percentage of total variation currently in focus. As you apply filters, the bar fills to reflect how much of the overall variation your current filter path accounts for.\u003C/p>\n\u003Cp>\u003Cstrong>Investigation Mindmap footer\u003C/strong> — The Mindmap’s progress footer displays the same cumulative percentage alongside the drill trail, giving you a spatial view of your investigation path and how much variation each step captured.\u003C/p>\n\u003Cp>Together, these tell you whether your drill-down has isolated enough variation to act on or whether further filtering is needed.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interpreting-cumulative-progress\">Interpreting Cumulative Progress\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interpreting-cumulative-progress\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpreting Cumulative Progress”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variation outside focus\u003C/th>\u003Cth>Interpretation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>> 50% remaining\u003C/td>\u003Ctd>More drilling needed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>30-50% remaining\u003C/td>\u003Ctd>Significant factors found\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>< 30% remaining\u003C/td>\u003Ctd>Good isolation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>< 15% remaining\u003C/td>\u003Ctd>Common cause only\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"single-select-vs-multi-select\">Single-Select vs Multi-Select\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#single-select-vs-multi-select\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Single-Select vs Multi-Select”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"single-select-default\">Single-Select (Default)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#single-select-default\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Single-Select (Default)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click a value to filter to just that level:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Shift: Night ▼ 46%\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Shift: Night ▼ 46%\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cul>\n\u003Cli>Shows only Night shift data\u003C/li>\n\u003Cli>Good for focusing on one problem area\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"multi-select\">Multi-Select\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#multi-select\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Multi-Select”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Hold Ctrl/Cmd and click multiple values:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Shift: Night, Evening ▼ 52%\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Shift: Night, Evening ▼ 52%\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cul>\n\u003Cli>Shows data from both shifts\u003C/li>\n\u003Cli>Useful for comparing similar groups\u003C/li>\n\u003Cli>Combined contribution may be higher\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-drill-down-process\">The Drill-Down Process\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-drill-down-process\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Drill-Down Process”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-1-start-with-full-data\">Step 1: Start with Full Data\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-start-with-full-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Start with Full Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>View the Boxplot with all data. Note which factor has highest η². Consider enabling \u003Cstrong>Show distribution shape\u003C/strong> in Settings to reveal bimodal distributions before filtering.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-2-click-to-filter\">Step 2: Click to Filter\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-click-to-filter\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Click to Filter”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click on the bar (or box) for the level you want to investigate:\u003C/p>\n\u003Cul>\n\u003Cli>Click the \u003Cstrong>highest\u003C/strong> level to isolate the biggest contributor\u003C/li>\n\u003Cli>Click an \u003Cstrong>outlier\u003C/strong> level to focus on the problem area\u003C/li>\n\u003Cli>Click a \u003Cstrong>good\u003C/strong> level to understand what works\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-3-observe-changes\">Step 3: Observe Changes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-observe-changes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Observe Changes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After filtering:\u003C/p>\n\u003Cul>\n\u003Cli>Filter chip appears with contribution %\u003C/li>\n\u003Cli>All charts update to show filtered subset\u003C/li>\n\u003Cli>Boxplot recalculates η² for remaining factors\u003C/li>\n\u003Cli>Capability shows filtered Cpk\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-4-continue-or-stop\">Step 4: Continue or Stop\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-continue-or-stop\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Continue or Stop”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Continue drilling if:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Still significant variation unexplained\u003C/li>\n\u003Cli>Next factor has meaningful η² (> 10%)\u003C/li>\n\u003Cli>Enough data remains for analysis (n > 20)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Stop drilling when:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Variation sufficiently isolated (> 50-70%)\u003C/li>\n\u003Cli>Remaining variation is common cause\u003C/li>\n\u003Cli>Data too sparse for reliable statistics\u003C/li>\n\u003Cli>Actionable insight found\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-5-document-path\">Step 5: Document Path\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-document-path\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Document Path”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Record your filter path for:\u003C/p>\n\u003Cul>\n\u003Cli>Reproducing the analysis\u003C/li>\n\u003Cli>Explaining to others\u003C/li>\n\u003Cli>Tracking improvements\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Filter path: Shift=Night → Operator=B → Machine=3\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Result: Isolated 84% of variation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Finding: Machine 3 accounts for most off-spec production on night shift\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Filter path: Shift=Night → Operator=B → Machine=3Result: Isolated 84% of variationFinding: Machine 3 accounts for most off-spec production on night shift\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"example-coffee-case-study\">Example: Coffee Case Study\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#example-coffee-case-study\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example: Coffee Case Study”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"starting-point\">Starting Point\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#starting-point\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Starting Point”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Full dataset: Fill weight variation\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Factor\u003C/th>\u003Cth>η²\u003C/th>\u003Cth>Interpretation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Batch\u003C/td>\u003Ctd>45%\u003C/td>\u003Ctd>Biggest contributor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Operator\u003C/td>\u003Ctd>18%\u003C/td>\u003Ctd>Moderate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Time\u003C/td>\u003Ctd>12%\u003C/td>\u003Ctd>Some effect\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"drill-down-sequence\">Drill-Down Sequence\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#drill-down-sequence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill-Down Sequence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Filter 1: Batch = 3\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Batch: 3 ▼ 45%]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Batch: 3 ▼ 45%]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Remaining factors:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Factor\u003C/th>\u003Cth>η²\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Operator\u003C/td>\u003Ctd>32%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Time\u003C/td>\u003Ctd>8%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Batch 3 was different—now Operator is more prominent.\u003C/p>\n\u003Cp>\u003Cstrong>Filter 2: Operator = New\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Batch: 3 ▼ 45%] [Operator: New ▼ 32%]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Batch: 3 ▼ 45%] [Operator: New ▼ 32%]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Remaining factors:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Factor\u003C/th>\u003Cth>η²\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Time\u003C/td>\u003Ctd>15%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Cumulative: 77% isolated\u003C/p>\n\u003Cp>\u003Cstrong>Result\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>New operator on Batch 3 explains most variation\u003C/li>\n\u003Cli>Training opportunity identified\u003C/li>\n\u003Cli>Time effect (15%) is shift-related—secondary factor\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"when-to-use-multi-select\">When to Use Multi-Select\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-use-multi-select\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Use Multi-Select”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"comparing-groups\">Comparing Groups\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#comparing-groups\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Comparing Groups”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Select multiple “good” values to establish baseline:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Operator: A, C, D ▼ 8%] ← Combined good operators\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Operator: A, C, D ▼ 8%] ← Combined good operators\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Then compare against the excluded “problem” level.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"excluding-outliers\">Excluding Outliers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#excluding-outliers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Excluding Outliers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Select “normal” values to see process without anomalies:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Shift: Day, Evening ▼ 52%] ← Excluding Night shift\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Shift: Day, Evening ▼ 52%] ← Excluding Night shift\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"investigating-interactions\">Investigating Interactions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#investigating-interactions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigating Interactions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Select combinations to test interaction effects:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Shift: Night ▼] [Operator: New ▼]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Shift: Night ▼] [Operator: New ▼]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>vs\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Shift: Day ▼] [Operator: New ▼]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Shift: Day ▼] [Operator: New ▼]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Does new operator perform differently by shift?\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"best-practices\">Best Practices\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#best-practices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Best Practices”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"do\">Do\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#do\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Do”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Start with the highest η² factor\u003C/li>\n\u003Cli>Note the cumulative variation as you drill\u003C/li>\n\u003Cli>Check Cpk at each level\u003C/li>\n\u003Cli>Verify sample size remains adequate\u003C/li>\n\u003Cli>Document your filter path\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"dont\">Don’t\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#dont\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Don’t”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Don’t drill too deep (sparse data)\u003C/li>\n\u003Cli>Don’t ignore factors with moderate η²\u003C/li>\n\u003Cli>Don’t forget to check stability at each level\u003C/li>\n\u003Cli>Don’t over-interpret small samples\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"reading-chart-updates\">Reading Chart Updates\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#reading-chart-updates\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reading Chart Updates”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"boxplot-after-filtering\">Boxplot After Filtering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#boxplot-after-filtering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Boxplot After Filtering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Shows remaining factors for filtered subset\u003C/li>\n\u003Cli>η² values recalculated\u003C/li>\n\u003Cli>May reveal hidden factors\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"i-chart-after-filtering\">I-Chart After Filtering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#i-chart-after-filtering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “I-Chart After Filtering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Shows only filtered time series\u003C/li>\n\u003Cli>Control limits recalculated\u003C/li>\n\u003Cli>May reveal pattern previously masked\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"capability-after-filtering\">Capability After Filtering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#capability-after-filtering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability After Filtering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Shows Cpk for filtered subset\u003C/li>\n\u003Cli>Compare to overall Cpk\u003C/li>\n\u003Cli>Helps quantify factor impact\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pareto-after-filtering\">Pareto After Filtering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pareto-after-filtering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pareto After Filtering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Shows defect types for filtered subset\u003C/li>\n\u003Cli>May reveal concentrated failure modes\u003C/li>\n\u003Cli>Connects variation to specific problems\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"navigating-back\">Navigating Back\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#navigating-back\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Navigating Back”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"remove-single-filter\">Remove Single Filter\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#remove-single-filter\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Remove Single Filter”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click the ▼ on any filter chip to remove it.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"clear-all-filters\">Clear All Filters\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#clear-all-filters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Clear All Filters”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click “Clear all” to return to full dataset.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"breadcrumb-navigation\">Breadcrumb Navigation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#breadcrumb-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Breadcrumb Navigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use breadcrumbs to jump to any point in drill path:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">All Data > Shift: Night > Operator: B\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"All Data > Shift: Night > Operator: B\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Click “Shift: Night” to remove Operator filter but keep Shift.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"four-lenses-workflow.md\">Four Lenses Workflow\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../navigation/linked-filtering.md\">Linked Filtering\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../navigation/breadcrumbs.md\">Breadcrumbs\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../analysis/boxplot.md\">Boxplot Feature\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7389, + "localImagePaths": 7492, + "remoteImagePaths": 7493, + "frontmatter": 7494, + "imagePaths": 7495 + }, + [ + 7390, 7392, 7393, 7396, 7399, 7402, 7405, 7408, 7411, 7414, 7417, 7420, 7423, 7426, 7429, 7432, + 7435, 7438, 7441, 7444, 7447, 7450, 7453, 7456, 7459, 7462, 7463, 7464, 7467, 7470, 7473, 7476, + 7479, 7482, 7485, 7488, 7491 + ], + { "depth": 30, "slug": 7391, "text": 7379 }, + "drill-down-analysis-workflow", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 7394, "text": 7395 }, + "the-drill-down-pattern", + "The Drill-Down Pattern", + { "depth": 33, "slug": 7397, "text": 7398 }, + "filter-chips", + "Filter Chips", + { "depth": 79, "slug": 7400, "text": 7401 }, + "what-they-show", + "What They Show", + { "depth": 79, "slug": 7403, "text": 7404 }, + "contribution-percentage", + "Contribution Percentage", + { "depth": 33, "slug": 7406, "text": 7407 }, + "tracking-your-investigation", + "Tracking Your Investigation", + { "depth": 79, "slug": 7409, "text": 7410 }, + "interpreting-cumulative-progress", + "Interpreting Cumulative Progress", + { "depth": 33, "slug": 7412, "text": 7413 }, + "single-select-vs-multi-select", + "Single-Select vs Multi-Select", + { "depth": 79, "slug": 7415, "text": 7416 }, + "single-select-default", + "Single-Select (Default)", + { "depth": 79, "slug": 7418, "text": 7419 }, + "multi-select", + "Multi-Select", + { "depth": 33, "slug": 7421, "text": 7422 }, + "the-drill-down-process", + "The Drill-Down Process", + { "depth": 79, "slug": 7424, "text": 7425 }, + "step-1-start-with-full-data", + "Step 1: Start with Full Data", + { "depth": 79, "slug": 7427, "text": 7428 }, + "step-2-click-to-filter", + "Step 2: Click to Filter", + { "depth": 79, "slug": 7430, "text": 7431 }, + "step-3-observe-changes", + "Step 3: Observe Changes", + { "depth": 79, "slug": 7433, "text": 7434 }, + "step-4-continue-or-stop", + "Step 4: Continue or Stop", + { "depth": 79, "slug": 7436, "text": 7437 }, + "step-5-document-path", + "Step 5: Document Path", + { "depth": 33, "slug": 7439, "text": 7440 }, + "example-coffee-case-study", + "Example: Coffee Case Study", + { "depth": 79, "slug": 7442, "text": 7443 }, + "starting-point", + "Starting Point", + { "depth": 79, "slug": 7445, "text": 7446 }, + "drill-down-sequence", + "Drill-Down Sequence", + { "depth": 33, "slug": 7448, "text": 7449 }, + "when-to-use-multi-select", + "When to Use Multi-Select", + { "depth": 79, "slug": 7451, "text": 7452 }, + "comparing-groups", + "Comparing Groups", + { "depth": 79, "slug": 7454, "text": 7455 }, + "excluding-outliers", + "Excluding Outliers", + { "depth": 79, "slug": 7457, "text": 7458 }, + "investigating-interactions", + "Investigating Interactions", + { "depth": 33, "slug": 7460, "text": 7461 }, + "best-practices", + "Best Practices", + { "depth": 79, "slug": 5433, "text": 5434 }, + { "depth": 79, "slug": 5436, "text": 5437 }, + { "depth": 33, "slug": 7465, "text": 7466 }, + "reading-chart-updates", + "Reading Chart Updates", + { "depth": 79, "slug": 7468, "text": 7469 }, + "boxplot-after-filtering", + "Boxplot After Filtering", + { "depth": 79, "slug": 7471, "text": 7472 }, + "i-chart-after-filtering", + "I-Chart After Filtering", + { "depth": 79, "slug": 7474, "text": 7475 }, + "capability-after-filtering", + "Capability After Filtering", + { "depth": 79, "slug": 7477, "text": 7478 }, + "pareto-after-filtering", + "Pareto After Filtering", + { "depth": 33, "slug": 7480, "text": 7481 }, + "navigating-back", + "Navigating Back", + { "depth": 79, "slug": 7483, "text": 7484 }, + "remove-single-filter", + "Remove Single Filter", + { "depth": 79, "slug": 7486, "text": 7487 }, + "clear-all-filters", + "Clear All Filters", + { "depth": 79, "slug": 7489, "text": 7490 }, + "breadcrumb-navigation", + "Breadcrumb Navigation", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 7379 }, + [], + "03-features/workflows/four-lenses-workflow", + { "id": 7496, "data": 7498, "body": 7503, "filePath": 7504, "digest": 7505, "rendered": 7506 }, + { + "title": 7499, + "editUrl": 16, + "head": 7500, + "template": 18, + "sidebar": 7501, + "pagefind": 16, + "draft": 20 + }, + "Four Lenses Analysis Workflow", + [], + { "hidden": 20, "attrs": 7502 }, + {}, + "# Four Lenses Analysis Workflow\n\n\u003C!-- journey-phase: scout -->\n\nThe core VariScout methodology: **CHANGE → FLOW → FAILURE → VALUE**\n\n## Overview\n\nThe Four Lenses represent a systematic progression through variation analysis:\n\n1. **CHANGE** (I-Chart) - Is the process stable over time?\n2. **FLOW** (Boxplot) - Which factors drive variation?\n3. **FAILURE** (Pareto) - Where do problems concentrate?\n4. **VALUE** (Capability) - Do we meet specifications?\n\nEach lens answers a specific question, and together they form a complete investigation.\n\n## The Analysis Flow\n\n```mermaid\nflowchart TD\n subgraph CHANGE[\"1. CHANGE (I-Chart)\"]\n A[Upload data] --> B[View I-Chart]\n B --> C{Stable?}\n C -->|No| D[Investigate special causes]\n C -->|Yes| E[Process is in control]\n end\n\n subgraph FLOW[\"2. FLOW (Boxplot)\"]\n E --> F[Compare factors in Boxplot]\n D --> F\n F --> G{High η²?}\n G -->|\">50%\"| H[Primary driver found!]\n G -->|\"30-50%\"| I[Significant contributor]\n G -->|\"\u003C30%\"| J[Check interactions]\n end\n\n subgraph FAILURE[\"3. FAILURE (Pareto)\"]\n H --> K[Rank in Pareto]\n I --> K\n K --> L[Identify vital few]\n end\n\n subgraph VALUE[\"4. VALUE (Capability)\"]\n L --> M[Check Cpk for filtered subset]\n M --> N{Capable?}\n N -->|\"Cpk > 1.33\"| O[Process OK]\n N -->|\"Cpk \u003C 1.0\"| P[Improvement needed]\n end\n```\n\n## Lens 1: CHANGE (I-Chart)\n\n**Question:** Is the process stable over time?\n\n### What to Look For\n\n| Pattern | Indicates | Next Step |\n| --------------------------------- | --------------- | -------------------------- |\n| Points within limits | Stable process | Proceed to Boxplot |\n| Point outside UCL/LCL | Special cause | Investigate that point |\n| 9+ consecutive points on one side | Process shift | Find when/why it shifted |\n| Trending up/down | Drift | Check for degradation |\n| Cycling pattern | Periodic factor | Look for time-based causes |\n\n### Actions\n\n- **Stable:** Process variation is common cause only. Proceed to understand what factors explain that variation.\n- **Unstable:** Special causes present. These must be investigated—they often point directly to assignable causes.\n\n:::tip[Start Here]\nAlways check stability first. Analyzing an unstable process as if it were stable leads to wrong conclusions.\n:::\n\n## Lens 2: FLOW (Boxplot)\n\n**Question:** Which factors explain the variation?\n\n### Reading η² (Eta-Squared)\n\nThe η² value shows what percentage of total variation is explained by a factor:\n\n| η² Value | Interpretation | Action |\n| -------- | -------------- | ------------------------- |\n| > 50% | Primary driver | Focus improvement here |\n| 30-50% | Significant | Worth investigating |\n| 10-30% | Moderate | May contribute to problem |\n| \u003C 10% | Minimal | Likely not the issue |\n\n### Distribution Shape\n\nEnable **Show distribution shape** in Settings to overlay density curves (violin plots) on boxplots. This reveals bimodal distributions, skewness, or clustering that standard box elements alone cannot show.\n\n### The Drill-Down\n\n1. **Identify highest η² factor** - Click on it\n2. **Filter applied** - All charts update to show that subset\n3. **Check remaining variation** - Look at next factor in hierarchy\n4. **Repeat** - Until you've isolated enough variation\n\n### Example\n\n```\nShift explains 45% → Filter to \"Night Shift\"\n └─ Operator explains 32% → Filter to \"Operator B\"\n └─ Machine explains 18% → Filter to \"Machine 3\"\n └─ 95% of variation now isolated\n```\n\n## Lens 3: FAILURE (Pareto)\n\n**Question:** Where do problems concentrate?\n\n### The 80/20 Rule\n\nPareto charts rank categories by frequency or impact. Typically:\n\n- 20% of causes create 80% of problems\n- Focus on the \"vital few\" not the \"trivial many\"\n\n### Reading the Pareto\n\n1. **Bars** show individual category counts/costs\n2. **Line** shows cumulative percentage\n3. **Look for the knee** - where cumulative line bends\n\n### Using Pareto with Filters\n\nAfter drilling down in Boxplot:\n\n1. Pareto updates to show filtered data\n2. See which defect types dominate in that subset\n3. Combine insights: \"Operator B on Machine 3 primarily has alignment defects\"\n\n## Lens 4: VALUE (Capability)\n\n**Question:** Do we meet specifications?\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Enter Specs\u003C/div>\n \u003Cdiv class=\"process-step__detail\">+ Specs, USL, LSL, Apply\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">6 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Cp/Cpk\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Capability indices in stats panel\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">View Histogram\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Histogram\" tab\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Distribution\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Shape vs spec lines\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">7 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~1 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\n_See [full Capability Check flow](process-maps.md#flow-3-capability-check) including data entry steps._\n\n### Key Metrics\n\n| Metric | What It Measures | Target |\n| ------ | -------------------------------------- | ------ |\n| Cp | Potential capability (spread vs specs) | > 1.33 |\n| Cpk | Actual capability (includes centering) | > 1.33 |\n| Pp/Ppk | Long-term performance | > 1.33 |\n\n### Interpretation\n\n| Cpk | Status | Meaning |\n| --------- | --------- | ------------------------------- |\n| > 1.67 | Excellent | Very capable |\n| 1.33-1.67 | Good | Capable |\n| 1.00-1.33 | Marginal | Barely meeting specs |\n| \u003C 1.00 | Poor | Not capable—improvements needed |\n\n### After Drilling Down\n\nCheck Cpk for the filtered subset:\n\n- **Cpk improved?** That factor was hurting capability\n- **Cpk unchanged?** Variation source doesn't affect specs\n- **Cpk worse?** Filtered to a problem area\n\n## Putting It Together: Bottleneck Case Study\n\n### Scenario\n\nBottling line with fill weight variation affecting customer complaints.\n\n### Workflow\n\n**Step 1: CHANGE**\n\n```\nI-Chart shows several points outside limits around 10am each day\n→ Special cause: Something happens mid-morning\n```\n\n**Step 2: FLOW**\n\n```\nBoxplot shows Shift explains 52% (η² = 0.52)\nFilter to \"Day Shift\" (where problems occur)\n └─ Fill Head explains 38%\n └─ Filter to \"Fill Head 3\"\n```\n\n**Step 3: FAILURE**\n\n```\nPareto (filtered): 78% of low-weight fills come from Fill Head 3\n→ Clear target for investigation\n```\n\n**Step 4: VALUE**\n\n```\nCapability (filtered to Fill Head 3):\n Cpk = 0.67 (Poor)\nCapability (excluding Fill Head 3):\n Cpk = 1.45 (Good)\n→ Fix Fill Head 3 to solve the problem\n```\n\n### Result\n\nFill Head 3 had worn seals causing inconsistent fills. After repair:\n\n- Cpk improved from 0.89 (overall) to 1.52\n- Customer complaints dropped 85%\n\n## When to Use Each Lens\n\n| Situation | Primary Lens |\n| ------------------------- | ------------------ |\n| \"Something changed\" | CHANGE (I-Chart) |\n| \"Why is there variation?\" | FLOW (Boxplot) |\n| \"What types of defects?\" | FAILURE (Pareto) |\n| \"Are we meeting specs?\" | VALUE (Capability) |\n\n## Common Mistakes\n\n### Skipping CHANGE\n\nAnalyzing an unstable process as if it were stable. Always check I-Chart first.\n\n### Ignoring Low η²\n\nA factor with 15% η² might still be important if:\n\n- It's easy to fix\n- It interacts with other factors\n- It affects capability more than variation\n\n### Stopping Too Early\n\nFinding one significant factor doesn't mean you've found all of them. Continue drilling until you've isolated actionable causes.\n\n### Over-Filtering\n\nToo many filters leave too little data for reliable statistics. Balance detail with sample size.\n\n## Related Documentation\n\n- [I-Chart Feature](../analysis/i-chart.md)\n- [Boxplot Feature](../analysis/boxplot.md)\n- [Pareto Feature](../analysis/pareto.md)\n- [Capability Feature](../analysis/capability.md)\n- [Four Lenses Philosophy](../../01-vision/four-lenses/index.md)\n- [Drill-Down Workflow](drill-down-workflow.md)", + "src/content/docs/03-features/workflows/four-lenses-workflow.md", + "004fd92f002b1ecd", + { "html": 7507, "metadata": 7508 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"four-lenses-analysis-workflow\">Four Lenses Analysis Workflow\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#four-lenses-analysis-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Four Lenses Analysis Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003C!-- journey-phase: scout -->\n\u003Cp>The core VariScout methodology: \u003Cstrong>CHANGE → FLOW → FAILURE → VALUE\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Four Lenses represent a systematic progression through variation analysis:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>CHANGE\u003C/strong> (I-Chart) - Is the process stable over time?\u003C/li>\n\u003Cli>\u003Cstrong>FLOW\u003C/strong> (Boxplot) - Which factors drive variation?\u003C/li>\n\u003Cli>\u003Cstrong>FAILURE\u003C/strong> (Pareto) - Where do problems concentrate?\u003C/li>\n\u003Cli>\u003Cstrong>VALUE\u003C/strong> (Capability) - Do we meet specifications?\u003C/li>\n\u003C/ol>\n\u003Cp>Each lens answers a specific question, and together they form a complete investigation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-analysis-flow\">The Analysis Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-analysis-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Analysis Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n subgraph CHANGE[\"1. CHANGE (I-Chart)\"]\n A[Upload data] --> B[View I-Chart]\n B --> C{Stable?}\n C -->|No| D[Investigate special causes]\n C -->|Yes| E[Process is in control]\n end\n\n subgraph FLOW[\"2. FLOW (Boxplot)\"]\n E --> F[Compare factors in Boxplot]\n D --> F\n F --> G{High η²?}\n G -->|\">50%\"| H[Primary driver found!]\n G -->|\"30-50%\"| I[Significant contributor]\n G -->|\"<30%\"| J[Check interactions]\n end\n\n subgraph FAILURE[\"3. FAILURE (Pareto)\"]\n H --> K[Rank in Pareto]\n I --> K\n K --> L[Identify vital few]\n end\n\n subgraph VALUE[\"4. VALUE (Capability)\"]\n L --> M[Check Cpk for filtered subset]\n M --> N{Capable?}\n N -->|\"Cpk > 1.33\"| O[Process OK]\n N -->|\"Cpk < 1.0\"| P[Improvement needed]\n end\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"lens-1-change-i-chart\">Lens 1: CHANGE (I-Chart)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#lens-1-change-i-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Lens 1: CHANGE (I-Chart)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Question:\u003C/strong> Is the process stable over time?\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-to-look-for\">What to Look For\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-to-look-for\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What to Look For”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>Indicates\u003C/th>\u003Cth>Next Step\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Points within limits\u003C/td>\u003Ctd>Stable process\u003C/td>\u003Ctd>Proceed to Boxplot\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Point outside UCL/LCL\u003C/td>\u003Ctd>Special cause\u003C/td>\u003Ctd>Investigate that point\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9+ consecutive points on one side\u003C/td>\u003Ctd>Process shift\u003C/td>\u003Ctd>Find when/why it shifted\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trending up/down\u003C/td>\u003Ctd>Drift\u003C/td>\u003Ctd>Check for degradation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cycling pattern\u003C/td>\u003Ctd>Periodic factor\u003C/td>\u003Ctd>Look for time-based causes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"actions\">Actions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#actions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Actions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Stable:\u003C/strong> Process variation is common cause only. Proceed to understand what factors explain that variation.\u003C/li>\n\u003Cli>\u003Cstrong>Unstable:\u003C/strong> Special causes present. These must be investigated—they often point directly to assignable causes.\u003C/li>\n\u003C/ul>\n\u003Caside aria-label=\"Start Here\" class=\"starlight-aside starlight-aside--tip\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.43909 8.85483L1.44039 8.85354L4.96668 5.33815C5.30653 4.99386 5.7685 4.79662 6.2524 4.78972L6.26553 4.78963L12.9014 4.78962L13.8479 3.84308C16.9187 0.772319 20.0546 0.770617 21.4678 0.975145C21.8617 1.02914 22.2271 1.21053 22.5083 1.4917C22.7894 1.77284 22.9708 2.13821 23.0248 2.53199C23.2294 3.94517 23.2278 7.08119 20.1569 10.1521L19.2107 11.0983V17.7338L19.2106 17.7469C19.2037 18.2308 19.0067 18.6933 18.6624 19.0331L15.1456 22.5608C14.9095 22.7966 14.6137 22.964 14.29 23.0449C13.9663 23.1259 13.6267 23.1174 13.3074 23.0204C12.9881 22.9235 12.7011 22.7417 12.4771 22.4944C12.2533 22.2473 12.1006 21.9441 12.0355 21.6171L11.1783 17.3417L6.65869 12.822L4.34847 12.3589L2.38351 11.965C2.05664 11.8998 1.75272 11.747 1.50564 11.5232C1.25835 11.2992 1.07653 11.0122 0.979561 10.6929C0.882595 10.3736 0.874125 10.034 0.955057 9.7103C1.03599 9.38659 1.20328 9.09092 1.43909 8.85483ZM6.8186 10.8724L2.94619 10.096L6.32006 6.73268H10.9583L6.8186 10.8724ZM15.2219 5.21703C17.681 2.75787 20.0783 2.75376 21.1124 2.8876C21.2462 3.92172 21.2421 6.31895 18.783 8.77812L12.0728 15.4883L8.51172 11.9272L15.2219 5.21703ZM13.9042 21.0538L13.1279 17.1811L17.2676 13.0414V17.68L13.9042 21.0538Z\">\u003C/path>\u003Cpath d=\"M9.31827 18.3446C9.45046 17.8529 9.17864 17.3369 8.68945 17.1724C8.56178 17.1294 8.43145 17.1145 8.30512 17.1243C8.10513 17.1398 7.91519 17.2172 7.76181 17.3434C7.62613 17.455 7.51905 17.6048 7.45893 17.7835C6.97634 19.2186 5.77062 19.9878 4.52406 20.4029C4.08525 20.549 3.6605 20.644 3.29471 20.7053C3.35607 20.3395 3.45098 19.9148 3.59711 19.476C4.01221 18.2294 4.78141 17.0237 6.21648 16.5411C6.39528 16.481 6.54504 16.3739 6.65665 16.2382C6.85126 16.0016 6.92988 15.678 6.84417 15.3647C6.83922 15.3466 6.83373 15.3286 6.82767 15.3106C6.74106 15.053 6.55701 14.8557 6.33037 14.7459C6.10949 14.6389 5.84816 14.615 5.59715 14.6994C5.47743 14.7397 5.36103 14.7831 5.24786 14.8294C3.22626 15.6569 2.2347 17.4173 1.75357 18.8621C1.49662 19.6337 1.36993 20.3554 1.30679 20.8818C1.27505 21.1464 1.25893 21.3654 1.25072 21.5213C1.24662 21.5993 1.24448 21.6618 1.24337 21.7066L1.243 21.7226L1.24235 21.7605L1.2422 21.7771L1.24217 21.7827L1.24217 21.7856C1.24217 22.3221 1.67703 22.7579 2.2137 22.7579L2.2155 22.7579L2.22337 22.7578L2.23956 22.7577C2.25293 22.7575 2.27096 22.7572 2.29338 22.7567C2.33821 22.7555 2.40073 22.7534 2.47876 22.7493C2.63466 22.7411 2.85361 22.725 3.11822 22.6932C3.64462 22.6301 4.36636 22.5034 5.13797 22.2464C6.58274 21.7653 8.3431 20.7738 9.17063 18.7522C9.21696 18.639 9.26037 18.5226 9.30064 18.4029C9.30716 18.3835 9.31304 18.364 9.31827 18.3446Z\">\u003C/path>\u003C/svg>Start Here\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>Always check stability first. Analyzing an unstable process as if it were stable leads to wrong conclusions.\u003C/p>\u003C/div>\u003C/aside>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"lens-2-flow-boxplot\">Lens 2: FLOW (Boxplot)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#lens-2-flow-boxplot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Lens 2: FLOW (Boxplot)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Question:\u003C/strong> Which factors explain the variation?\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"reading-η-eta-squared\">Reading η² (Eta-Squared)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#reading-η-eta-squared\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reading η² (Eta-Squared)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The η² value shows what percentage of total variation is explained by a factor:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>η² Value\u003C/th>\u003Cth>Interpretation\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>> 50%\u003C/td>\u003Ctd>Primary driver\u003C/td>\u003Ctd>Focus improvement here\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>30-50%\u003C/td>\u003Ctd>Significant\u003C/td>\u003Ctd>Worth investigating\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10-30%\u003C/td>\u003Ctd>Moderate\u003C/td>\u003Ctd>May contribute to problem\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>< 10%\u003C/td>\u003Ctd>Minimal\u003C/td>\u003Ctd>Likely not the issue\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"distribution-shape\">Distribution Shape\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#distribution-shape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Distribution Shape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Enable \u003Cstrong>Show distribution shape\u003C/strong> in Settings to overlay density curves (violin plots) on boxplots. This reveals bimodal distributions, skewness, or clustering that standard box elements alone cannot show.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-drill-down\">The Drill-Down\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-drill-down\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Drill-Down”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Identify highest η² factor\u003C/strong> - Click on it\u003C/li>\n\u003Cli>\u003Cstrong>Filter applied\u003C/strong> - All charts update to show that subset\u003C/li>\n\u003Cli>\u003Cstrong>Check remaining variation\u003C/strong> - Look at next factor in hierarchy\u003C/li>\n\u003Cli>\u003Cstrong>Repeat\u003C/strong> - Until you’ve isolated enough variation\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Shift explains 45% → Filter to \"Night Shift\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ Operator explains 32% → Filter to \"Operator B\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ Machine explains 18% → Filter to \"Machine 3\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ 95% of variation now isolated\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Shift explains 45% → Filter to "Night Shift" └─ Operator explains 32% → Filter to "Operator B" └─ Machine explains 18% → Filter to "Machine 3" └─ 95% of variation now isolated\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"lens-3-failure-pareto\">Lens 3: FAILURE (Pareto)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#lens-3-failure-pareto\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Lens 3: FAILURE (Pareto)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Question:\u003C/strong> Where do problems concentrate?\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-8020-rule\">The 80/20 Rule\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-8020-rule\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The 80/20 Rule”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pareto charts rank categories by frequency or impact. Typically:\u003C/p>\n\u003Cul>\n\u003Cli>20% of causes create 80% of problems\u003C/li>\n\u003Cli>Focus on the “vital few” not the “trivial many”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"reading-the-pareto\">Reading the Pareto\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#reading-the-pareto\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reading the Pareto”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Bars\u003C/strong> show individual category counts/costs\u003C/li>\n\u003Cli>\u003Cstrong>Line\u003C/strong> shows cumulative percentage\u003C/li>\n\u003Cli>\u003Cstrong>Look for the knee\u003C/strong> - where cumulative line bends\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"using-pareto-with-filters\">Using Pareto with Filters\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#using-pareto-with-filters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Using Pareto with Filters”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After drilling down in Boxplot:\u003C/p>\n\u003Col>\n\u003Cli>Pareto updates to show filtered data\u003C/li>\n\u003Cli>See which defect types dominate in that subset\u003C/li>\n\u003Cli>Combine insights: “Operator B on Machine 3 primarily has alignment defects”\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"lens-4-value-capability\">Lens 4: VALUE (Capability)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#lens-4-value-capability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Lens 4: VALUE (Capability)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Question:\u003C/strong> Do we meet specifications?\u003C/p>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Enter Specs\u003C/div>\n \u003Cdiv class=\"process-step__detail\">+ Specs, USL, LSL, Apply\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">6 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Cp/Cpk\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Capability indices in stats panel\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">View Histogram\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Histogram\" tab\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Distribution\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Shape vs spec lines\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">7 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~1 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>\u003Cem>See \u003Ca href=\"process-maps.md#flow-3-capability-check\">full Capability Check flow\u003C/a> including data entry steps.\u003C/em>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-metrics\">Key Metrics\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-metrics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Metrics”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>What It Measures\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Cp\u003C/td>\u003Ctd>Potential capability (spread vs specs)\u003C/td>\u003Ctd>> 1.33\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cpk\u003C/td>\u003Ctd>Actual capability (includes centering)\u003C/td>\u003Ctd>> 1.33\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pp/Ppk\u003C/td>\u003Ctd>Long-term performance\u003C/td>\u003Ctd>> 1.33\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interpretation\">Interpretation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interpretation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpretation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Cpk\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>> 1.67\u003C/td>\u003Ctd>Excellent\u003C/td>\u003Ctd>Very capable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.33-1.67\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Capable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.00-1.33\u003C/td>\u003Ctd>Marginal\u003C/td>\u003Ctd>Barely meeting specs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>< 1.00\u003C/td>\u003Ctd>Poor\u003C/td>\u003Ctd>Not capable—improvements needed\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"after-drilling-down\">After Drilling Down\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#after-drilling-down\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “After Drilling Down”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Check Cpk for the filtered subset:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Cpk improved?\u003C/strong> That factor was hurting capability\u003C/li>\n\u003Cli>\u003Cstrong>Cpk unchanged?\u003C/strong> Variation source doesn’t affect specs\u003C/li>\n\u003Cli>\u003Cstrong>Cpk worse?\u003C/strong> Filtered to a problem area\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"putting-it-together-bottleneck-case-study\">Putting It Together: Bottleneck Case Study\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#putting-it-together-bottleneck-case-study\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Putting It Together: Bottleneck Case Study”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"scenario\">Scenario\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#scenario\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Bottling line with fill weight variation affecting customer complaints.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"workflow\">Workflow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Step 1: CHANGE\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">I-Chart shows several points outside limits around 10am each day\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">→ Special cause: Something happens mid-morning\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"I-Chart shows several points outside limits around 10am each day→ Special cause: Something happens mid-morning\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Step 2: FLOW\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Boxplot shows Shift explains 52% (η² = 0.52)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Filter to \"Day Shift\" (where problems occur)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ Fill Head explains 38%\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ Filter to \"Fill Head 3\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Boxplot shows Shift explains 52% (η² = 0.52)Filter to "Day Shift" (where problems occur) └─ Fill Head explains 38% └─ Filter to "Fill Head 3"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Step 3: FAILURE\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Pareto (filtered): 78% of low-weight fills come from Fill Head 3\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">→ Clear target for investigation\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Pareto (filtered): 78% of low-weight fills come from Fill Head 3→ Clear target for investigation\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Step 4: VALUE\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Capability (filtered to Fill Head 3):\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cpk = 0.67 (Poor)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Capability (excluding Fill Head 3):\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cpk = 1.45 (Good)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">→ Fix Fill Head 3 to solve the problem\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Capability (filtered to Fill Head 3): Cpk = 0.67 (Poor)Capability (excluding Fill Head 3): Cpk = 1.45 (Good)→ Fix Fill Head 3 to solve the problem\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"result\">Result\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#result\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Result”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Fill Head 3 had worn seals causing inconsistent fills. After repair:\u003C/p>\n\u003Cul>\n\u003Cli>Cpk improved from 0.89 (overall) to 1.52\u003C/li>\n\u003Cli>Customer complaints dropped 85%\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"when-to-use-each-lens\">When to Use Each Lens\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-use-each-lens\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Use Each Lens”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Situation\u003C/th>\u003Cth>Primary Lens\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Something changed”\u003C/td>\u003Ctd>CHANGE (I-Chart)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>“Why is there variation?”\u003C/td>\u003Ctd>FLOW (Boxplot)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>“What types of defects?”\u003C/td>\u003Ctd>FAILURE (Pareto)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>“Are we meeting specs?”\u003C/td>\u003Ctd>VALUE (Capability)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"common-mistakes\">Common Mistakes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#common-mistakes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Mistakes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"skipping-change\">Skipping CHANGE\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#skipping-change\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Skipping CHANGE”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Analyzing an unstable process as if it were stable. Always check I-Chart first.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ignoring-low-η\">Ignoring Low η²\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ignoring-low-η\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Ignoring Low η²”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A factor with 15% η² might still be important if:\u003C/p>\n\u003Cul>\n\u003Cli>It’s easy to fix\u003C/li>\n\u003Cli>It interacts with other factors\u003C/li>\n\u003Cli>It affects capability more than variation\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"stopping-too-early\">Stopping Too Early\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#stopping-too-early\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Stopping Too Early”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Finding one significant factor doesn’t mean you’ve found all of them. Continue drilling until you’ve isolated actionable causes.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"over-filtering\">Over-Filtering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#over-filtering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Over-Filtering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Too many filters leave too little data for reliable statistics. Balance detail with sample size.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../analysis/i-chart.md\">I-Chart Feature\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../analysis/boxplot.md\">Boxplot Feature\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../analysis/pareto.md\">Pareto Feature\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../analysis/capability.md\">Capability Feature\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/index.md\">Four Lenses Philosophy\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"drill-down-workflow.md\">Drill-Down Workflow\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7509, + "localImagePaths": 7585, + "remoteImagePaths": 7586, + "frontmatter": 7587, + "imagePaths": 7588 + }, + [ + 7510, 7512, 7513, 7516, 7519, 7522, 7523, 7526, 7529, 7532, 7535, 7538, 7541, 7544, 7547, 7550, + 7553, 7554, 7555, 7558, 7561, 7564, 7565, 7568, 7571, 7572, 7575, 7578, 7581, 7584 + ], + { "depth": 30, "slug": 7511, "text": 7499 }, + "four-lenses-analysis-workflow", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 7514, "text": 7515 }, + "the-analysis-flow", + "The Analysis Flow", + { "depth": 33, "slug": 7517, "text": 7518 }, + "lens-1-change-i-chart", + "Lens 1: CHANGE (I-Chart)", + { "depth": 79, "slug": 7520, "text": 7521 }, + "what-to-look-for", + "What to Look For", + { "depth": 79, "slug": 7304, "text": 7305 }, + { "depth": 33, "slug": 7524, "text": 7525 }, + "lens-2-flow-boxplot", + "Lens 2: FLOW (Boxplot)", + { "depth": 79, "slug": 7527, "text": 7528 }, + "reading-η-eta-squared", + "Reading η² (Eta-Squared)", + { "depth": 79, "slug": 7530, "text": 7531 }, + "distribution-shape", + "Distribution Shape", + { "depth": 79, "slug": 7533, "text": 7534 }, + "the-drill-down", + "The Drill-Down", + { "depth": 79, "slug": 7536, "text": 7537 }, + "example", + "Example", + { "depth": 33, "slug": 7539, "text": 7540 }, + "lens-3-failure-pareto", + "Lens 3: FAILURE (Pareto)", + { "depth": 79, "slug": 7542, "text": 7543 }, + "the-8020-rule", + "The 80/20 Rule", + { "depth": 79, "slug": 7545, "text": 7546 }, + "reading-the-pareto", + "Reading the Pareto", + { "depth": 79, "slug": 7548, "text": 7549 }, + "using-pareto-with-filters", + "Using Pareto with Filters", + { "depth": 33, "slug": 7551, "text": 7552 }, + "lens-4-value-capability", + "Lens 4: VALUE (Capability)", + { "depth": 79, "slug": 3914, "text": 3915 }, + { "depth": 79, "slug": 6346, "text": 6347 }, + { "depth": 79, "slug": 7556, "text": 7557 }, + "after-drilling-down", + "After Drilling Down", + { "depth": 33, "slug": 7559, "text": 7560 }, + "putting-it-together-bottleneck-case-study", + "Putting It Together: Bottleneck Case Study", + { "depth": 79, "slug": 7562, "text": 7563 }, + "scenario", + "Scenario", + { "depth": 79, "slug": 6589, "text": 6590 }, + { "depth": 79, "slug": 7566, "text": 7567 }, + "result", + "Result", + { "depth": 33, "slug": 7569, "text": 7570 }, + "when-to-use-each-lens", + "When to Use Each Lens", + { "depth": 33, "slug": 5984, "text": 5985 }, + { "depth": 79, "slug": 7573, "text": 7574 }, + "skipping-change", + "Skipping CHANGE", + { "depth": 79, "slug": 7576, "text": 7577 }, + "ignoring-low-η", + "Ignoring Low η²", + { "depth": 79, "slug": 7579, "text": 7580 }, + "stopping-too-early", + "Stopping Too Early", + { "depth": 79, "slug": 7582, "text": 7583 }, + "over-filtering", + "Over-Filtering", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 7499 }, + [], + "03-features/workflows", + { "id": 7589, "data": 7591, "body": 7595, "filePath": 7596, "digest": 7597, "rendered": 7598 }, + { + "title": 1097, + "editUrl": 16, + "head": 7592, + "template": 18, + "sidebar": 7593, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 7594 }, + {}, + "# Analyst Workflows\n\nHow analysts use VariScout to solve real problems.\n\n## What Are Workflows?\n\nWorkflows describe **what analysts actually DO** inside VariScout—the sequence of charts, filters, and decisions that lead to actionable insights. While feature documentation explains what each tool does, workflows show how to combine them effectively.\n\n## Visual Process Maps\n\n**[Process Maps](process-maps.md)** — Step-by-step visual maps showing exactly how many user actions each workflow requires. Start here for a quick overview of all analysis flows with PWA and Azure variants.\n\n| Flow | Actions | Time | Question |\n| --------------------- | ------- | ------- | ------------------------ |\n| Stability Check | 5-6 | ~2 min | Is it stable? |\n| Root Cause | 6-8 | ~5 min | What causes variation? |\n| Capability Check | 12-13 | ~3 min | Do we meet specs? |\n| Process Investigation | ~15 | ~10 min | Why is quality dropping? |\n| Predict Improvement | ~12 | ~8 min | Can we fix it? |\n\n## Analysis Journey\n\n### [Analysis Journey Map](analysis-journey-map.md)\n\nThe unified 4-phase model: **FRAME → SCOUT → INVESTIGATE → IMPROVE** with CoScout companion across all phases and PDCA loop for re-entry. Start here for the big picture.\n\n### [Investigation Lifecycle Map](investigation-lifecycle-map.md)\n\nIDEOI state diagram for the Investigate phase — hypothesis diamond, finding status lifecycle, and CoScout behavior at each state.\n\n---\n\n## Core Workflows\n\n### [Four Lenses Analysis](four-lenses-workflow.md)\n\nThe foundational methodology: **CHANGE → FLOW → FAILURE → VALUE**\n\n```\nI-Chart → Boxplot → Pareto → Capability\n```\n\nUse this progression for systematic root cause analysis.\n\n### [Drill-Down Analysis](drill-down-workflow.md)\n\nVariScout's signature interaction pattern—progressive stratification using filter chips to isolate variation sources.\n\n- Filter chips show contribution percentage\n- Cumulative tracking via VariationBar and Investigation Mindmap\n- Multi-select for combined effects\n\n### [Performance Mode](performance-mode-workflow.md)\n\nMulti-channel analysis for production equipment:\n\n- Fill heads\n- Cavities\n- Nozzles\n- Zones\n\nCompare all channels at once, then drill into the worst performer.\n\n## Specialized Workflows\n\n### [Decision Trees](decision-trees.md)\n\n\"Which chart should I use?\"\n\nFlowcharts for common analyst questions:\n\n- Data stability assessment\n- Factor comparison\n- Defect concentration\n- Specification compliance\n\n### [Investigation to Action](investigation-to-action.md)\n\nThe two-phase analyst workflow: **Investigate → Project**\n\n1. Findings — drill into factors, pin observations, track investigation status\n2. What-If — scenario modeling for projected improvement\n\n## Time-Boxed Scenarios\n\n### [Quick Check (5 Minutes)](quick-check.md)\n\nDaily/shift-level monitoring pattern:\n\n1. I-Chart stability scan\n2. Capability check\n3. Boxplot factor review\n4. Document any issues\n\n### [Deep Dive (30 Minutes)](deep-dive.md)\n\nSystematic investigation for problem-solving:\n\n| Phase | Time | Focus |\n| -------------- | ------ | --------------------- |\n| Baseline | 5 min | Full dataset overview |\n| Stability | 5 min | I-Chart analysis |\n| Stratification | 10 min | Drill-down workflow |\n| Capability | 5 min | Filtered Cpk |\n| Documentation | 5 min | Export findings |\n\n## Workflow Selection Guide\n\n| Your Question | Start Here |\n| ---------------------------- | ----------------------------------------------------- |\n| \"Is my process stable?\" | [Four Lenses](four-lenses-workflow.md) |\n| \"What's causing variation?\" | [Drill-Down](drill-down-workflow.md) |\n| \"Which channel is worst?\" | [Performance Mode](performance-mode-workflow.md) |\n| \"Quick shift check needed\" | [Quick Check](quick-check.md) |\n| \"Need to solve this problem\" | [Deep Dive](deep-dive.md) |\n| \"Full root cause to action\" | [Investigation to Action](investigation-to-action.md) |\n\n## Related Documentation\n\n- [Feature Documentation](../index.md) — What each chart does\n- [Case Studies](../../04-cases/index.md) — Teaching examples\n- [Four Lenses Philosophy](../../01-vision/four-lenses/index.md) — Why this methodology\n- [System Map](../../05-technical/architecture/system-map.md) — Package topology\n- [Data Pipeline Map](../../05-technical/architecture/data-pipeline-map.md) — End-to-end data flow", + "src/content/docs/03-features/workflows/index.md", + "775cb17977410295", + { "html": 7599, "metadata": 7600 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"analyst-workflows\">Analyst Workflows\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#analyst-workflows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analyst Workflows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How analysts use VariScout to solve real problems.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-are-workflows\">What Are Workflows?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-are-workflows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Are Workflows?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Workflows describe \u003Cstrong>what analysts actually DO\u003C/strong> inside VariScout—the sequence of charts, filters, and decisions that lead to actionable insights. While feature documentation explains what each tool does, workflows show how to combine them effectively.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visual-process-maps\">Visual Process Maps\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visual-process-maps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Process Maps”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>\u003Ca href=\"process-maps.md\">Process Maps\u003C/a>\u003C/strong> — Step-by-step visual maps showing exactly how many user actions each workflow requires. Start here for a quick overview of all analysis flows with PWA and Azure variants.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Flow\u003C/th>\u003Cth>Actions\u003C/th>\u003Cth>Time\u003C/th>\u003Cth>Question\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Stability Check\u003C/td>\u003Ctd>5-6\u003C/td>\u003Ctd>~2 min\u003C/td>\u003Ctd>Is it stable?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Root Cause\u003C/td>\u003Ctd>6-8\u003C/td>\u003Ctd>~5 min\u003C/td>\u003Ctd>What causes variation?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability Check\u003C/td>\u003Ctd>12-13\u003C/td>\u003Ctd>~3 min\u003C/td>\u003Ctd>Do we meet specs?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Process Investigation\u003C/td>\u003Ctd>~15\u003C/td>\u003Ctd>~10 min\u003C/td>\u003Ctd>Why is quality dropping?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Predict Improvement\u003C/td>\u003Ctd>~12\u003C/td>\u003Ctd>~8 min\u003C/td>\u003Ctd>Can we fix it?\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysis-journey\">Analysis Journey\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"analysis-journey-map\">\u003Ca href=\"analysis-journey-map.md\">Analysis Journey Map\u003C/a>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-journey-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis Journey Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The unified 4-phase model: \u003Cstrong>FRAME → SCOUT → INVESTIGATE → IMPROVE\u003C/strong> with CoScout companion across all phases and PDCA loop for re-entry. Start here for the big picture.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"investigation-lifecycle-map\">\u003Ca href=\"investigation-lifecycle-map.md\">Investigation Lifecycle Map\u003C/a>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-lifecycle-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation Lifecycle Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>IDEOI state diagram for the Investigate phase — hypothesis diamond, finding status lifecycle, and CoScout behavior at each state.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-workflows\">Core Workflows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-workflows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Workflows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"four-lenses-analysis\">\u003Ca href=\"four-lenses-workflow.md\">Four Lenses Analysis\u003C/a>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#four-lenses-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Four Lenses Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The foundational methodology: \u003Cstrong>CHANGE → FLOW → FAILURE → VALUE\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">I-Chart → Boxplot → Pareto → Capability\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"I-Chart → Boxplot → Pareto → Capability\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Use this progression for systematic root cause analysis.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"drill-down-analysis\">\u003Ca href=\"drill-down-workflow.md\">Drill-Down Analysis\u003C/a>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#drill-down-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill-Down Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s signature interaction pattern—progressive stratification using filter chips to isolate variation sources.\u003C/p>\n\u003Cul>\n\u003Cli>Filter chips show contribution percentage\u003C/li>\n\u003Cli>Cumulative tracking via VariationBar and Investigation Mindmap\u003C/li>\n\u003Cli>Multi-select for combined effects\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance-mode\">\u003Ca href=\"performance-mode-workflow.md\">Performance Mode\u003C/a>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Multi-channel analysis for production equipment:\u003C/p>\n\u003Cul>\n\u003Cli>Fill heads\u003C/li>\n\u003Cli>Cavities\u003C/li>\n\u003Cli>Nozzles\u003C/li>\n\u003Cli>Zones\u003C/li>\n\u003C/ul>\n\u003Cp>Compare all channels at once, then drill into the worst performer.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"specialized-workflows\">Specialized Workflows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#specialized-workflows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Specialized Workflows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"decision-trees\">\u003Ca href=\"decision-trees.md\">Decision Trees\u003C/a>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#decision-trees\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision Trees”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>“Which chart should I use?”\u003C/p>\n\u003Cp>Flowcharts for common analyst questions:\u003C/p>\n\u003Cul>\n\u003Cli>Data stability assessment\u003C/li>\n\u003Cli>Factor comparison\u003C/li>\n\u003Cli>Defect concentration\u003C/li>\n\u003Cli>Specification compliance\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"investigation-to-action\">\u003Ca href=\"investigation-to-action.md\">Investigation to Action\u003C/a>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-to-action\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation to Action”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The two-phase analyst workflow: \u003Cstrong>Investigate → Project\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Findings — drill into factors, pin observations, track investigation status\u003C/li>\n\u003Cli>What-If — scenario modeling for projected improvement\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"time-boxed-scenarios\">Time-Boxed Scenarios\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#time-boxed-scenarios\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Time-Boxed Scenarios”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"quick-check-5-minutes\">\u003Ca href=\"quick-check.md\">Quick Check (5 Minutes)\u003C/a>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#quick-check-5-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Check (5 Minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Daily/shift-level monitoring pattern:\u003C/p>\n\u003Col>\n\u003Cli>I-Chart stability scan\u003C/li>\n\u003Cli>Capability check\u003C/li>\n\u003Cli>Boxplot factor review\u003C/li>\n\u003Cli>Document any issues\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deep-dive-30-minutes\">\u003Ca href=\"deep-dive.md\">Deep Dive (30 Minutes)\u003C/a>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deep-dive-30-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deep Dive (30 Minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Systematic investigation for problem-solving:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Phase\u003C/th>\u003Cth>Time\u003C/th>\u003Cth>Focus\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Baseline\u003C/td>\u003Ctd>5 min\u003C/td>\u003Ctd>Full dataset overview\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Stability\u003C/td>\u003Ctd>5 min\u003C/td>\u003Ctd>I-Chart analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Stratification\u003C/td>\u003Ctd>10 min\u003C/td>\u003Ctd>Drill-down workflow\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability\u003C/td>\u003Ctd>5 min\u003C/td>\u003Ctd>Filtered Cpk\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Documentation\u003C/td>\u003Ctd>5 min\u003C/td>\u003Ctd>Export findings\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"workflow-selection-guide\">Workflow Selection Guide\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#workflow-selection-guide\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow Selection Guide”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Your Question\u003C/th>\u003Cth>Start Here\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”Is my process stable?”\u003C/td>\u003Ctd>\u003Ca href=\"four-lenses-workflow.md\">Four Lenses\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”What’s causing variation?”\u003C/td>\u003Ctd>\u003Ca href=\"drill-down-workflow.md\">Drill-Down\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Which channel is worst?”\u003C/td>\u003Ctd>\u003Ca href=\"performance-mode-workflow.md\">Performance Mode\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Quick shift check needed”\u003C/td>\u003Ctd>\u003Ca href=\"quick-check.md\">Quick Check\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Need to solve this problem”\u003C/td>\u003Ctd>\u003Ca href=\"deep-dive.md\">Deep Dive\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Full root cause to action”\u003C/td>\u003Ctd>\u003Ca href=\"investigation-to-action.md\">Investigation to Action\u003C/a>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../index.md\">Feature Documentation\u003C/a> — What each chart does\u003C/li>\n\u003Cli>\u003Ca href=\"../../04-cases/index.md\">Case Studies\u003C/a> — Teaching examples\u003C/li>\n\u003Cli>\u003Ca href=\"../../01-vision/four-lenses/index.md\">Four Lenses Philosophy\u003C/a> — Why this methodology\u003C/li>\n\u003Cli>\u003Ca href=\"../../05-technical/architecture/system-map.md\">System Map\u003C/a> — Package topology\u003C/li>\n\u003Cli>\u003Ca href=\"../../05-technical/architecture/data-pipeline-map.md\">Data Pipeline Map\u003C/a> — End-to-end data flow\u003C/li>\n\u003C/ul>", + { + "headings": 7601, + "localImagePaths": 7642, + "remoteImagePaths": 7643, + "frontmatter": 7644, + "imagePaths": 7645 + }, + [ + 7602, 7603, 7606, 7609, 7610, 7611, 7612, 7615, 7618, 7621, 7622, 7625, 7626, 7629, 7632, 7635, + 7638, 7641 + ], + { "depth": 30, "slug": 1096, "text": 1097 }, + { "depth": 33, "slug": 7604, "text": 7605 }, + "what-are-workflows", + "What Are Workflows?", + { "depth": 33, "slug": 7607, "text": 7608 }, + "visual-process-maps", + "Visual Process Maps", + { "depth": 33, "slug": 1093, "text": 1094 }, + { "depth": 79, "slug": 340, "text": 327 }, + { "depth": 79, "slug": 445, "text": 432 }, + { "depth": 33, "slug": 7613, "text": 7614 }, + "core-workflows", + "Core Workflows", + { "depth": 79, "slug": 7616, "text": 7617 }, + "four-lenses-analysis", + "Four Lenses Analysis", + { "depth": 79, "slug": 7619, "text": 7620 }, + "drill-down-analysis", + "Drill-Down Analysis", + { "depth": 79, "slug": 6582, "text": 6570 }, + { "depth": 33, "slug": 7623, "text": 7624 }, + "specialized-workflows", + "Specialized Workflows", + { "depth": 79, "slug": 7237, "text": 7225 }, + { "depth": 79, "slug": 7627, "text": 7628 }, + "investigation-to-action", + "Investigation to Action", + { "depth": 33, "slug": 7630, "text": 7631 }, + "time-boxed-scenarios", + "Time-Boxed Scenarios", + { "depth": 79, "slug": 7633, "text": 7634 }, + "quick-check-5-minutes", + "Quick Check (5 Minutes)", + { "depth": 79, "slug": 7636, "text": 7637 }, + "deep-dive-30-minutes", + "Deep Dive (30 Minutes)", + { "depth": 33, "slug": 7639, "text": 7640 }, + "workflow-selection-guide", + "Workflow Selection Guide", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 1097 }, + [], + "03-features/workflows/investigation-to-action", + { "id": 7646, "data": 7648, "body": 7653, "filePath": 7654, "digest": 7655, "rendered": 7656 }, + { + "title": 7649, + "editUrl": 16, + "head": 7650, + "template": 18, + "sidebar": 7651, + "pagefind": 16, + "draft": 20 + }, + "Investigation to Action Workflow", + [], + { "hidden": 20, "attrs": 7652 }, + {}, + "# Investigation to Action Workflow\n\n\u003C!-- journey-phase: investigate, improve -->\n\nFrom variation discovery to projected improvement — the analyst workflow.\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Load Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Paste or upload\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2-3 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Start Analysis\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Map columns, Start\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">3-4 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Scan I-Chart\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Red dots, runs?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--decision\">\n \u003Cdiv class=\"process-step__title\">Stable?\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Blue → skip. Red → investigate\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Drill Factors\u003C/div>\n \u003Cdiv class=\"process-step__detail\">ANOVA → filter top eta\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1-2 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Enter Specs\u003C/div>\n \u003Cdiv class=\"process-step__detail\">USL, LSL, Apply\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">6 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Export / Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Copy chart or save\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">~15 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~10 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\n_See [full process map](process-maps.md#analyst-flow-a-process-investigation) with all decision points._\n\n## Overview\n\nA quality analyst uses two complementary tools:\n\n| Tool | Question | Output |\n| ----------------- | -------------------------------- | ---------------------- |\n| Findings panel | \"What is driving the variation?\" | Key factors identified |\n| What-If Simulator | \"What if we improved it?\" | Projected Cpk/yield |\n\nThese tools are independent — use either one alone, or combine them for a full investigation-to-projection workflow.\n\n## Why Two Tools?\n\nAn earlier design (the now-removed Variation Funnel) conflated investigation and projection into a single dense panel. The problem: analysts were simultaneously trying to explore data and imagine improvements. This led to:\n\n- **Premature conclusions** — jumping to projections before understanding the full picture\n- **Cognitive overload** — too many decisions in one place\n\nSeparating investigation (Findings) from projection (What-If) mirrors how experienced quality engineers think. But they are peers, not sequential phases — the What-If Simulator is equally useful for general target-setting without any investigation.\n\n## Findings — Investigate Variation\n\n**Goal:** Identify the factors driving variation.\n\nUse the dashboard's drill-down workflow to progressively filter the data by factors. As you discover interesting patterns, pin them as findings:\n\n1. **Drill into factors** — Click Boxplot/Pareto categories to filter. Each factor's ANOVA η² shows its contribution to total variation. Follow the highest contribution path.\n\n2. **Pin findings** — Click the pin button in the breadcrumb bar to instantly capture the current filter state as a finding. Add a note later if desired — the filter chips and statistics are captured automatically.\n\n3. **Add chart observations** — Right-click a Boxplot category or Pareto bar and select \"Add observation\" to create a finding anchored to that specific chart element. The observation text appears as a floating annotation on the chart and is stored as a Finding with source metadata.\n\n4. **Review findings** — Open the Findings panel to see all bookmarked states. Click a finding card to restore its filter combination on the dashboard. Edit or delete findings as your understanding evolves.\n\nThe Findings panel can be popped out to a separate window for dual-monitor setups — keep findings visible on one screen while drilling on the other.\n\n### Chart Observations\n\nThere are two ways to create findings:\n\n| Method | How | What is captured |\n| --------------------- | ---------------------------------------------- | ------------------------------------------------------------ |\n| **Breadcrumb pin** | Click pin button in filter breadcrumb bar | Current filter state, statistics, variation % |\n| **Chart observation** | Right-click chart category → \"Add observation\" | Category name, chart type, observation text, source metadata |\n\nChart-sourced findings carry a `source` chip on the FindingCard (e.g., \"Boxplot: Machine C\") so analysts can distinguish observations made on a specific chart element from drill-down filter pins.\n\nThe floating text box on the chart is a visual projection of the underlying Finding. Editing the text in the annotation box updates the Finding; editing the Finding text in the panel updates the annotation. The annotation box displays a small status dot matching the finding's investigation status color (amber/blue/purple).\n\nColor highlights (red/amber/green) remain as separate lightweight visual markers on Boxplot and Pareto categories. They are stored in DisplayOptions and do not create findings.\n\nIn Board view, chart observations appear alongside drill-down findings, grouped by the same status columns (Observed / Investigating / Analyzed). The source chip helps identify which findings came from chart annotations versus breadcrumb pins.\n\n### Exit criterion\n\nStop investigating when:\n\n- Cumulative contribution reaches 70% or more\n- All meaningful factors have been explored\n- Remaining variation is common cause (no factor has significant contribution)\n\n### Investigation Status Tracking\n\nAs findings accumulate, track their investigation progress:\n\n| Status | Badge | Meaning |\n| ----------------- | ------ | ------------------------------------- |\n| **Observed** | Amber | Pattern spotted, not yet investigated |\n| **Investigating** | Blue | Actively drilling into this finding |\n| **Analyzed** | Purple | Analysis completed |\n\nClick a finding's status badge to change its status. Add timestamped comments\nto record what you checked and what you learned.\n\n### Classification Tags\n\nWhen a finding reaches \"Analyzed\" status, classify it by contribution magnitude:\n\n| Tag | Color | Meaning |\n| -------------- | ----- | ---------------------------------------------- |\n| **Key Driver** | Green | Significant variation contributor — actionable |\n| **Low Impact** | Gray | Minor or negligible contribution |\n| _(none)_ | — | Not yet classified |\n\nTags reflect _contribution magnitude_, not causal certainty. VariScout quantifies\ncontribution, not causation — we measure how much variation a factor accounts for,\nnot whether it's the \"root cause.\"\n\n### Board View\n\nToggle the Findings panel to Board view for a grouped layout:\n\n- **Panel**: Collapsible accordion sections per status (3 columns)\n- **Popout window**: Horizontal columns with native drag-and-drop\n\nThe Board view helps organize findings during complex investigations with\nmany observations. Key Driver findings become a natural shortlist for action.\n\n### Why keep Low Impact findings?\n\nLow Impact findings document what was ruled out. This is valuable for:\n\n- Audit trails (\"we checked Machine C — minor contribution\")\n- Team handoffs (\"don't repeat this investigation path\")\n- Returning to an analysis after weeks away\n\n### Output\n\nA list of pinned findings, each with filter context, variation %, tags, and analyst notes.\n\nSee [Drill-Down Workflow](drill-down-workflow.md) for detailed drill-down mechanics.\n\n## What-If Simulator — Project Improvement\n\n**Goal:** Estimate what happens if you improve the process.\n\nThe What-If Simulator is a standalone tool accessible from the header toolbar. It takes the current process statistics and lets you explore improvements through direct adjustments. Use it for:\n\n- **Improvement modeling** — After investigation, project the impact of fixing a key driver\n- **Project target-setting** — Set Cpk targets and see what mean/variation changes are needed\n- **Prioritizing actions** — Compare different improvement scenarios\n\n### Standard Simulator\n\nThe `WhatIfSimulator` offers two direct adjustments:\n\n1. **Mean adjustment** — Shift the process center toward the target. Use this when the process is off-center (e.g., wrong machine setting).\n\n2. **Variation reduction** — Reduce process spread. Use this when there's excessive scatter (e.g., inconsistent operator technique).\n\n### What you see\n\n- **Current vs. projected statistics** — Mean, standard deviation, Cpk side by side\n- **Yield improvement** — Percentage of in-spec production, current vs. projected\n- **Color-coded Cpk** — Green (capable), amber (marginal), red (not capable)\n\n### Interpreting projections\n\nProjections assume normal distribution and apply the adjustments to the current filtered data. They answer: \"If we shifted the mean by X and reduced variation by Y%, what would our capability look like?\"\n\nThese are estimates, not guarantees. Use them for:\n\n- Justifying improvement projects (\"shifting mean by 2 units would improve Cpk from 0.8 to 1.4\")\n- Prioritizing actions (\"mean shift alone gets us to 1.2, but we need variation reduction too\")\n- Setting realistic targets\n\n## Workflow Combinations\n\n| Your situation | Use |\n| --------------------------------------- | ----------------------------- |\n| \"I don't know what's causing variation\" | Findings (investigate) |\n| \"I want to set a Cpk target\" | What-If (project) |\n| \"I have findings, want to project\" | Findings then What-If |\n| \"Full investigation from scratch\" | Findings → classify → What-If |\n\n## Example: Pizza Delivery Dataset\n\n### Investigate\n\nDrill into delivery time variation and pin findings:\n\n1. **Store** has the highest contribution: Store C accounts for 35% of variation\n2. Within Store C, **Day** matters: Weekend deliveries are 8 minutes slower\n3. **Driver** has a moderate effect (12%): Driver 3 is consistently slow\n\nCumulative: ~72% of variation explained. Tag Store C + Weekend as \"Key Driver\", Driver 3 as \"Low Impact\" (small contribution alone).\n\n### Project\n\nFilter to Store C + Weekend, then use What-If:\n\n- Shifting mean by -5 minutes (better routing) -> Cpk improves from 0.6 to 1.1\n- Adding 20% variation reduction (standardized process) -> Cpk reaches 1.4\n- Combined projection supports the business case for process improvement at Store C\n\n## Related Documentation\n\n- [Drill-Down Workflow](drill-down-workflow.md) — Investigation mechanics\n- [Deep Dive](deep-dive.md) — 30-minute investigation pattern\n- [Decision Trees](decision-trees.md) — Which analysis to use when\n- [Four Lenses Workflow](four-lenses-workflow.md) — Foundational methodology", + "src/content/docs/03-features/workflows/investigation-to-action.md", + "ce3dbe2eab6a204a", + { "html": 7657, "metadata": 7658 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"investigation-to-action-workflow\">Investigation to Action Workflow\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-to-action-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation to Action Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003C!-- journey-phase: investigate, improve -->\n\u003Cp>From variation discovery to projected improvement — the analyst workflow.\u003C/p>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Load Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Paste or upload\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2-3 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Start Analysis\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Map columns, Start\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">3-4 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Scan I-Chart\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Red dots, runs?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--decision\">\n \u003Cdiv class=\"process-step__title\">Stable?\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Blue → skip. Red → investigate\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Drill Factors\u003C/div>\n \u003Cdiv class=\"process-step__detail\">ANOVA → filter top eta\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1-2 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Enter Specs\u003C/div>\n \u003Cdiv class=\"process-step__detail\">USL, LSL, Apply\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">6 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Export / Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Copy chart or save\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">~15 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~10 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>\u003Cem>See \u003Ca href=\"process-maps.md#analyst-flow-a-process-investigation\">full process map\u003C/a> with all decision points.\u003C/em>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A quality analyst uses two complementary tools:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tool\u003C/th>\u003Cth>Question\u003C/th>\u003Cth>Output\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Findings panel\u003C/td>\u003Ctd>”What is driving the variation?”\u003C/td>\u003Ctd>Key factors identified\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>What-If Simulator\u003C/td>\u003Ctd>”What if we improved it?”\u003C/td>\u003Ctd>Projected Cpk/yield\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>These tools are independent — use either one alone, or combine them for a full investigation-to-projection workflow.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-two-tools\">Why Two Tools?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-two-tools\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Two Tools?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>An earlier design (the now-removed Variation Funnel) conflated investigation and projection into a single dense panel. The problem: analysts were simultaneously trying to explore data and imagine improvements. This led to:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Premature conclusions\u003C/strong> — jumping to projections before understanding the full picture\u003C/li>\n\u003Cli>\u003Cstrong>Cognitive overload\u003C/strong> — too many decisions in one place\u003C/li>\n\u003C/ul>\n\u003Cp>Separating investigation (Findings) from projection (What-If) mirrors how experienced quality engineers think. But they are peers, not sequential phases — the What-If Simulator is equally useful for general target-setting without any investigation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"findings--investigate-variation\">Findings — Investigate Variation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#findings--investigate-variation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Findings — Investigate Variation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Identify the factors driving variation.\u003C/p>\n\u003Cp>Use the dashboard’s drill-down workflow to progressively filter the data by factors. As you discover interesting patterns, pin them as findings:\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Drill into factors\u003C/strong> — Click Boxplot/Pareto categories to filter. Each factor’s ANOVA η² shows its contribution to total variation. Follow the highest contribution path.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Pin findings\u003C/strong> — Click the pin button in the breadcrumb bar to instantly capture the current filter state as a finding. Add a note later if desired — the filter chips and statistics are captured automatically.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Add chart observations\u003C/strong> — Right-click a Boxplot category or Pareto bar and select “Add observation” to create a finding anchored to that specific chart element. The observation text appears as a floating annotation on the chart and is stored as a Finding with source metadata.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Review findings\u003C/strong> — Open the Findings panel to see all bookmarked states. Click a finding card to restore its filter combination on the dashboard. Edit or delete findings as your understanding evolves.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cp>The Findings panel can be popped out to a separate window for dual-monitor setups — keep findings visible on one screen while drilling on the other.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"chart-observations\">Chart Observations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#chart-observations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Observations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>There are two ways to create findings:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Method\u003C/th>\u003Cth>How\u003C/th>\u003Cth>What is captured\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Breadcrumb pin\u003C/strong>\u003C/td>\u003Ctd>Click pin button in filter breadcrumb bar\u003C/td>\u003Ctd>Current filter state, statistics, variation %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Chart observation\u003C/strong>\u003C/td>\u003Ctd>Right-click chart category → “Add observation”\u003C/td>\u003Ctd>Category name, chart type, observation text, source metadata\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Chart-sourced findings carry a \u003Ccode dir=\"auto\">source\u003C/code> chip on the FindingCard (e.g., “Boxplot: Machine C”) so analysts can distinguish observations made on a specific chart element from drill-down filter pins.\u003C/p>\n\u003Cp>The floating text box on the chart is a visual projection of the underlying Finding. Editing the text in the annotation box updates the Finding; editing the Finding text in the panel updates the annotation. The annotation box displays a small status dot matching the finding’s investigation status color (amber/blue/purple).\u003C/p>\n\u003Cp>Color highlights (red/amber/green) remain as separate lightweight visual markers on Boxplot and Pareto categories. They are stored in DisplayOptions and do not create findings.\u003C/p>\n\u003Cp>In Board view, chart observations appear alongside drill-down findings, grouped by the same status columns (Observed / Investigating / Analyzed). The source chip helps identify which findings came from chart annotations versus breadcrumb pins.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"exit-criterion\">Exit criterion\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#exit-criterion\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Exit criterion”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Stop investigating when:\u003C/p>\n\u003Cul>\n\u003Cli>Cumulative contribution reaches 70% or more\u003C/li>\n\u003Cli>All meaningful factors have been explored\u003C/li>\n\u003Cli>Remaining variation is common cause (no factor has significant contribution)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"investigation-status-tracking\">Investigation Status Tracking\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-status-tracking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation Status Tracking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>As findings accumulate, track their investigation progress:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Status\u003C/th>\u003Cth>Badge\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Observed\u003C/strong>\u003C/td>\u003Ctd>Amber\u003C/td>\u003Ctd>Pattern spotted, not yet investigated\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Investigating\u003C/strong>\u003C/td>\u003Ctd>Blue\u003C/td>\u003Ctd>Actively drilling into this finding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Analyzed\u003C/strong>\u003C/td>\u003Ctd>Purple\u003C/td>\u003Ctd>Analysis completed\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Click a finding’s status badge to change its status. Add timestamped comments\nto record what you checked and what you learned.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"classification-tags\">Classification Tags\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#classification-tags\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Classification Tags”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When a finding reaches “Analyzed” status, classify it by contribution magnitude:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tag\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Key Driver\u003C/strong>\u003C/td>\u003Ctd>Green\u003C/td>\u003Ctd>Significant variation contributor — actionable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Low Impact\u003C/strong>\u003C/td>\u003Ctd>Gray\u003C/td>\u003Ctd>Minor or negligible contribution\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cem>(none)\u003C/em>\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Not yet classified\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Tags reflect \u003Cem>contribution magnitude\u003C/em>, not causal certainty. VariScout quantifies\ncontribution, not causation — we measure how much variation a factor accounts for,\nnot whether it’s the “root cause.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"board-view\">Board View\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#board-view\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Board View”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Toggle the Findings panel to Board view for a grouped layout:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Panel\u003C/strong>: Collapsible accordion sections per status (3 columns)\u003C/li>\n\u003Cli>\u003Cstrong>Popout window\u003C/strong>: Horizontal columns with native drag-and-drop\u003C/li>\n\u003C/ul>\n\u003Cp>The Board view helps organize findings during complex investigations with\nmany observations. Key Driver findings become a natural shortlist for action.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-keep-low-impact-findings\">Why keep Low Impact findings?\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-keep-low-impact-findings\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why keep Low Impact findings?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Low Impact findings document what was ruled out. This is valuable for:\u003C/p>\n\u003Cul>\n\u003Cli>Audit trails (“we checked Machine C — minor contribution”)\u003C/li>\n\u003Cli>Team handoffs (“don’t repeat this investigation path”)\u003C/li>\n\u003Cli>Returning to an analysis after weeks away\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"output\">Output\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#output\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Output”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A list of pinned findings, each with filter context, variation %, tags, and analyst notes.\u003C/p>\n\u003Cp>See \u003Ca href=\"drill-down-workflow.md\">Drill-Down Workflow\u003C/a> for detailed drill-down mechanics.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-if-simulator--project-improvement\">What-If Simulator — Project Improvement\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-if-simulator--project-improvement\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What-If Simulator — Project Improvement”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Estimate what happens if you improve the process.\u003C/p>\n\u003Cp>The What-If Simulator is a standalone tool accessible from the header toolbar. It takes the current process statistics and lets you explore improvements through direct adjustments. Use it for:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Improvement modeling\u003C/strong> — After investigation, project the impact of fixing a key driver\u003C/li>\n\u003Cli>\u003Cstrong>Project target-setting\u003C/strong> — Set Cpk targets and see what mean/variation changes are needed\u003C/li>\n\u003Cli>\u003Cstrong>Prioritizing actions\u003C/strong> — Compare different improvement scenarios\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-simulator\">Standard Simulator\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-simulator\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Simulator”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">WhatIfSimulator\u003C/code> offers two direct adjustments:\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Mean adjustment\u003C/strong> — Shift the process center toward the target. Use this when the process is off-center (e.g., wrong machine setting).\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Variation reduction\u003C/strong> — Reduce process spread. Use this when there’s excessive scatter (e.g., inconsistent operator technique).\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-you-see\">What you see\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-you-see\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What you see”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Current vs. projected statistics\u003C/strong> — Mean, standard deviation, Cpk side by side\u003C/li>\n\u003Cli>\u003Cstrong>Yield improvement\u003C/strong> — Percentage of in-spec production, current vs. projected\u003C/li>\n\u003Cli>\u003Cstrong>Color-coded Cpk\u003C/strong> — Green (capable), amber (marginal), red (not capable)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interpreting-projections\">Interpreting projections\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interpreting-projections\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpreting projections”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Projections assume normal distribution and apply the adjustments to the current filtered data. They answer: “If we shifted the mean by X and reduced variation by Y%, what would our capability look like?”\u003C/p>\n\u003Cp>These are estimates, not guarantees. Use them for:\u003C/p>\n\u003Cul>\n\u003Cli>Justifying improvement projects (“shifting mean by 2 units would improve Cpk from 0.8 to 1.4”)\u003C/li>\n\u003Cli>Prioritizing actions (“mean shift alone gets us to 1.2, but we need variation reduction too”)\u003C/li>\n\u003Cli>Setting realistic targets\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"workflow-combinations\">Workflow Combinations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#workflow-combinations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow Combinations”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Your situation\u003C/th>\u003Cth>Use\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”I don’t know what’s causing variation”\u003C/td>\u003Ctd>Findings (investigate)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>“I want to set a Cpk target”\u003C/td>\u003Ctd>What-If (project)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>“I have findings, want to project”\u003C/td>\u003Ctd>Findings then What-If\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Full investigation from scratch”\u003C/td>\u003Ctd>Findings → classify → What-If\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"example-pizza-delivery-dataset\">Example: Pizza Delivery Dataset\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#example-pizza-delivery-dataset\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example: Pizza Delivery Dataset”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"investigate\">Investigate\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#investigate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigate”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Drill into delivery time variation and pin findings:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Store\u003C/strong> has the highest contribution: Store C accounts for 35% of variation\u003C/li>\n\u003Cli>Within Store C, \u003Cstrong>Day\u003C/strong> matters: Weekend deliveries are 8 minutes slower\u003C/li>\n\u003Cli>\u003Cstrong>Driver\u003C/strong> has a moderate effect (12%): Driver 3 is consistently slow\u003C/li>\n\u003C/ol>\n\u003Cp>Cumulative: ~72% of variation explained. Tag Store C + Weekend as “Key Driver”, Driver 3 as “Low Impact” (small contribution alone).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"project\">Project\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#project\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Project”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Filter to Store C + Weekend, then use What-If:\u003C/p>\n\u003Cul>\n\u003Cli>Shifting mean by -5 minutes (better routing) -> Cpk improves from 0.6 to 1.1\u003C/li>\n\u003Cli>Adding 20% variation reduction (standardized process) -> Cpk reaches 1.4\u003C/li>\n\u003Cli>Combined projection supports the business case for process improvement at Store C\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"drill-down-workflow.md\">Drill-Down Workflow\u003C/a> — Investigation mechanics\u003C/li>\n\u003Cli>\u003Ca href=\"deep-dive.md\">Deep Dive\u003C/a> — 30-minute investigation pattern\u003C/li>\n\u003Cli>\u003Ca href=\"decision-trees.md\">Decision Trees\u003C/a> — Which analysis to use when\u003C/li>\n\u003Cli>\u003Ca href=\"four-lenses-workflow.md\">Four Lenses Workflow\u003C/a> — Foundational methodology\u003C/li>\n\u003C/ul>", + { + "headings": 7659, + "localImagePaths": 7712, + "remoteImagePaths": 7713, + "frontmatter": 7714, + "imagePaths": 7715 + }, + [ + 7660, 7662, 7663, 7666, 7669, 7672, 7675, 7678, 7681, 7682, 7685, 7688, 7691, 7694, 7697, 7700, + 7703, 7706, 7708, 7711 + ], + { "depth": 30, "slug": 7661, "text": 7649 }, + "investigation-to-action-workflow", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 7664, "text": 7665 }, + "why-two-tools", + "Why Two Tools?", + { "depth": 33, "slug": 7667, "text": 7668 }, + "findings--investigate-variation", + "Findings — Investigate Variation", + { "depth": 79, "slug": 7670, "text": 7671 }, + "chart-observations", + "Chart Observations", + { "depth": 79, "slug": 7673, "text": 7674 }, + "exit-criterion", + "Exit criterion", + { "depth": 79, "slug": 7676, "text": 7677 }, + "investigation-status-tracking", + "Investigation Status Tracking", + { "depth": 79, "slug": 7679, "text": 7680 }, + "classification-tags", + "Classification Tags", + { "depth": 79, "slug": 2719, "text": 2720 }, + { "depth": 79, "slug": 7683, "text": 7684 }, + "why-keep-low-impact-findings", + "Why keep Low Impact findings?", + { "depth": 79, "slug": 7686, "text": 7687 }, + "output", + "Output", + { "depth": 33, "slug": 7689, "text": 7690 }, + "what-if-simulator--project-improvement", + "What-If Simulator — Project Improvement", + { "depth": 79, "slug": 7692, "text": 7693 }, + "standard-simulator", + "Standard Simulator", + { "depth": 79, "slug": 7695, "text": 7696 }, + "what-you-see", + "What you see", + { "depth": 79, "slug": 7698, "text": 7699 }, + "interpreting-projections", + "Interpreting projections", + { "depth": 33, "slug": 7701, "text": 7702 }, + "workflow-combinations", + "Workflow Combinations", + { "depth": 33, "slug": 7704, "text": 7705 }, + "example-pizza-delivery-dataset", + "Example: Pizza Delivery Dataset", + { "depth": 79, "slug": 471, "text": 7707 }, + "Investigate", + { "depth": 79, "slug": 7709, "text": 7710 }, + "project", + "Project", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 7649 }, + [], + "03-features/workflows/performance-mode-workflow", + { "id": 7716, "data": 7718, "body": 7723, "filePath": 7724, "digest": 7725, "rendered": 7726 }, + { + "title": 7719, + "editUrl": 16, + "head": 7720, + "template": 18, + "sidebar": 7721, + "pagefind": 16, + "draft": 20 + }, + "Performance Mode Workflow", + [], + { "hidden": 20, "attrs": 7722 }, + {}, + "# Performance Mode Workflow\n\nMulti-channel analysis for production equipment with multiple measurement points.\n\n## Overview\n\nPerformance Mode is designed for analyzing equipment with multiple parallel measurement channels:\n\n- **Fill heads** on a bottling line\n- **Cavities** in injection molding\n- **Nozzles** in dispensing equipment\n- **Zones** in ovens or furnaces\n- **Spindles** on multi-spindle machines\n\nInstead of analyzing one measurement at a time, Performance Mode shows all channels together for comparison.\n\n## When to Use Performance Mode\n\n| Scenario | Use Performance Mode? |\n| ------------------------------------------ | --------------------- |\n| 8 fill heads, need to find worst performer | Yes |\n| Single measurement, multiple factors | No (Standard) |\n| Comparing cavity-to-cavity variation | Yes |\n| Tracking one metric over time | No (Standard) |\n| Equipment qualification | Yes |\n\n## The Performance Mode Flow\n\n```mermaid\nflowchart TD\n A[Upload wide-format data] --> B{Auto-detect: Performance Mode?}\n B -->|\"Yes\"| C[Confirm measure columns]\n B -->|\"No\"| D[Select columns manually]\n C --> E[Performance Pareto shows all channels]\n D --> E\n E --> F[Review Cpk ranking]\n F --> G{All channels OK?}\n G -->|\"Yes\"| H[Done - Equipment qualified]\n G -->|\"No\"| I[Click worst Cpk channel]\n I --> J[Drill to Standard Dashboard]\n J --> K[Analyze with Four Lenses]\n K --> L[Fix channel-specific issue]\n L --> M[Return to Performance overview]\n M --> F\n```\n\n## Data Format\n\n### Wide Format (Performance Mode)\n\nEach row is one sample, columns are channels:\n\n| Sample | Head_1 | Head_2 | Head_3 | Head_4 |\n| ------ | ------ | ------ | ------ | ------ |\n| 1 | 100.2 | 99.8 | 101.5 | 100.1 |\n| 2 | 99.9 | 100.1 | 102.1 | 99.7 |\n| 3 | 100.3 | 99.6 | 101.8 | 100.4 |\n\n### Long Format (Standard Mode)\n\nEach row is one measurement:\n\n| Sample | Head | Value |\n| ------ | ---- | ----- |\n| 1 | 1 | 100.2 |\n| 1 | 2 | 99.8 |\n| 1 | 3 | 101.5 |\n\nPerformance Mode expects **wide format**.\n\n## Performance Charts\n\n### Performance Pareto\n\nRanks all channels by Cpk (worst first):\n\n```\nHead_3 ████████████████ Cpk: 0.67 (Poor)\nHead_1 ██████████████████████ Cpk: 1.12 (Marginal)\nHead_4 ████████████████████████ Cpk: 1.35 (Good)\nHead_2 █████████████████████████ Cpk: 1.48 (Good)\n```\n\n**What to look for:**\n\n- Clear worst performer (fix this first)\n- Cluster of poor performers (systematic issue?)\n- Gap between good and bad (isolated problem)\n\n### Performance I-Chart (Scatter)\n\nShows Cpk over time or sample sequence:\n\n- Each point is a channel at a time period\n- Color indicates health status\n- Helps identify when a channel degraded\n\n### Performance Boxplot\n\nDistribution comparison across channels:\n\n- Shows spread and centering\n- Highlights outlier channels\n- Limited to 5 channels at once (select worst)\n\n### Performance Capability\n\nSingle-channel histogram after drilling down:\n\n- Full capability analysis for selected channel\n- Compare to specs\n- Detailed distribution view\n\n## Cpk vs Cp Toggle\n\n| Metric | Shows | Use When |\n| ------ | -------------------------------------- | ----------------------------------- |\n| Cpk | Actual capability (includes centering) | Production monitoring |\n| Cp | Potential capability (spread only) | Identifying centering opportunities |\n\n**Toggle in Performance Mode:**\n\n- Default: Cpk (overall assessment)\n- Switch to Cp: See if centering could help\n\n:::tip[Interpreting the Difference]\nIf Cp >> Cpk, the process can meet specs if centered. If Cp ≈ Cpk, the process is centered but variation is the issue.\n:::\n\n## Health Classification\n\nPerformance Mode uses color-coded health status:\n\n| Status | Cpk Range | Color | Action |\n| --------- | --------- | ------ | --------------- |\n| Excellent | ≥ 1.67 | Green | None needed |\n| Good | 1.33–1.67 | Blue | Monitor |\n| Marginal | 1.00–1.33 | Yellow | Investigate |\n| Poor | \u003C 1.00 | Red | Fix immediately |\n\n## Workflow Example: Bottling Line\n\n### Setup\n\n8-head bottling line, fill weight specification: 500 ± 5g\n\n### Step 1: Upload Data\n\nWide format with Head_1 through Head_8 columns.\n\nVariScout auto-detects: \"Performance Mode detected. Confirm measure columns?\"\n\n### Step 2: Review Performance Pareto\n\n```\nHead_3 Cpk: 0.67 [Poor] ← Focus here\nHead_7 Cpk: 0.89 [Poor]\nHead_1 Cpk: 1.15 [Marginal]\nHead_5 Cpk: 1.28 [Marginal]\nHead_2 Cpk: 1.42 [Good]\nHead_4 Cpk: 1.51 [Good]\nHead_6 Cpk: 1.58 [Good]\nHead_8 Cpk: 1.72 [Excellent]\n```\n\n### Step 3: Drill into Head_3\n\nClick Head_3 bar → Transitions to Standard Dashboard\n\nNow viewing only Head_3 data with full Four Lenses analysis.\n\n### Step 4: Analyze with Four Lenses\n\n**I-Chart:** Shows instability around 10am each day\n\n**Boxplot:** Time of day explains 42% (η² = 0.42)\n\n**Finding:** Head_3 heats up mid-morning, causing underfill\n\n### Step 5: Return to Performance View\n\nAfter identifying root cause, click \"Back to Performance\"\n\nPlan: Add cooling to Head_3 or adjust fill timing\n\n### Step 6: Verify Fix\n\nAfter implementing fix, re-run Performance analysis:\n\n```\nHead_3 Cpk: 1.38 [Good] ← Improved!\n```\n\n## Navigating Between Views\n\n### Performance → Standard\n\n- Click any channel in Performance charts\n- Selected channel becomes the focus\n- Standard Dashboard shows that channel's data\n- Filter chip shows: `Channel: Head_3`\n\n### Standard → Performance\n\n- Click \"Back to Performance\" button\n- Returns to multi-channel overview\n- Any non-channel filters preserved\n\n### Combining Filters\n\nYou can apply filters in Standard view, then return to Performance:\n\n```\nPerformance → Head_3 → Filter Shift=Day → Back to Performance\n```\n\nNow Performance view shows all channels, but only Day shift data.\n\n## Channel Limits\n\n| Tier | Max Channels |\n| ------------ | ------------ |\n| Demo | 3 |\n| Starter | 10 |\n| Professional | 50 |\n| Enterprise | Unlimited |\n\n## Common Patterns\n\n### One Bad Channel\n\n```\nHead_3 is Poor, others are Good/Excellent\n```\n\n**Interpretation:** Isolated equipment issue\n\n**Action:** Focus on that specific channel (wear, calibration, damage)\n\n### All Channels Similar\n\n```\nAll channels: Cpk 1.0-1.2 (Marginal)\n```\n\n**Interpretation:** Systematic issue affecting all channels\n\n**Action:** Look at common causes (material, settings, environment)\n\n### Degradation Over Time\n\n```\nEarly samples: All Good\nRecent samples: Several Poor\n```\n\n**Interpretation:** Process drift or wear\n\n**Action:** Check maintenance records, calibration schedule\n\n### Position-Based Pattern\n\n```\nHead_1, Head_2: Poor\nHead_7, Head_8: Good\n```\n\n**Interpretation:** Position on machine matters\n\n**Action:** Check mechanical alignment, temperature gradients\n\n## Best Practices\n\n### Do\n\n- Review all channels before drilling down\n- Check if poor performers cluster (position, time)\n- Compare Cp vs Cpk to understand centering\n- Document findings per channel\n- Re-verify after fixes\n\n### Don't\n\n- Don't ignore marginally poor channels\n- Don't assume all channels are independent\n- Don't forget to check for time-based patterns\n- Don't skip back to Performance view after fixing\n\n## Related Documentation\n\n- [Performance Mode Feature](../analysis/performance-mode.md)\n- [Four Lenses Workflow](four-lenses-workflow.md)\n- [Capability Analysis](../analysis/capability.md)\n- [Oven Zones Case Study](../../04-cases/oven-zones/index.md)", + "src/content/docs/03-features/workflows/performance-mode-workflow.md", + "46a53ecf55f1ab18", + { "html": 7727, "metadata": 7728 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"performance-mode-workflow\">Performance Mode Workflow\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#performance-mode-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Mode Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Multi-channel analysis for production equipment with multiple measurement points.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Performance Mode is designed for analyzing equipment with multiple parallel measurement channels:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Fill heads\u003C/strong> on a bottling line\u003C/li>\n\u003Cli>\u003Cstrong>Cavities\u003C/strong> in injection molding\u003C/li>\n\u003Cli>\u003Cstrong>Nozzles\u003C/strong> in dispensing equipment\u003C/li>\n\u003Cli>\u003Cstrong>Zones\u003C/strong> in ovens or furnaces\u003C/li>\n\u003Cli>\u003Cstrong>Spindles\u003C/strong> on multi-spindle machines\u003C/li>\n\u003C/ul>\n\u003Cp>Instead of analyzing one measurement at a time, Performance Mode shows all channels together for comparison.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"when-to-use-performance-mode\">When to Use Performance Mode\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-use-performance-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Use Performance Mode”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Scenario\u003C/th>\u003Cth>Use Performance Mode?\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>8 fill heads, need to find worst performer\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Single measurement, multiple factors\u003C/td>\u003Ctd>No (Standard)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Comparing cavity-to-cavity variation\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tracking one metric over time\u003C/td>\u003Ctd>No (Standard)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Equipment qualification\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-performance-mode-flow\">The Performance Mode Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-performance-mode-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Performance Mode Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Upload wide-format data] --> B{Auto-detect: Performance Mode?}\n B -->|\"Yes\"| C[Confirm measure columns]\n B -->|\"No\"| D[Select columns manually]\n C --> E[Performance Pareto shows all channels]\n D --> E\n E --> F[Review Cpk ranking]\n F --> G{All channels OK?}\n G -->|\"Yes\"| H[Done - Equipment qualified]\n G -->|\"No\"| I[Click worst Cpk channel]\n I --> J[Drill to Standard Dashboard]\n J --> K[Analyze with Four Lenses]\n K --> L[Fix channel-specific issue]\n L --> M[Return to Performance overview]\n M --> F\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-format\">Data Format\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-format\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Format”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"wide-format-performance-mode\">Wide Format (Performance Mode)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#wide-format-performance-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Wide Format (Performance Mode)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each row is one sample, columns are channels:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Sample\u003C/th>\u003Cth>Head_1\u003C/th>\u003Cth>Head_2\u003C/th>\u003Cth>Head_3\u003C/th>\u003Cth>Head_4\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>100.2\u003C/td>\u003Ctd>99.8\u003C/td>\u003Ctd>101.5\u003C/td>\u003Ctd>100.1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>99.9\u003C/td>\u003Ctd>100.1\u003C/td>\u003Ctd>102.1\u003C/td>\u003Ctd>99.7\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>100.3\u003C/td>\u003Ctd>99.6\u003C/td>\u003Ctd>101.8\u003C/td>\u003Ctd>100.4\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"long-format-standard-mode\">Long Format (Standard Mode)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#long-format-standard-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Long Format (Standard Mode)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each row is one measurement:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Sample\u003C/th>\u003Cth>Head\u003C/th>\u003Cth>Value\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>100.2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>99.8\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>101.5\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Performance Mode expects \u003Cstrong>wide format\u003C/strong>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performance-charts\">Performance Charts\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performance-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance-pareto\">Performance Pareto\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance-pareto\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Pareto”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Ranks all channels by Cpk (worst first):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_3 ████████████████ Cpk: 0.67 (Poor)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_1 ██████████████████████ Cpk: 1.12 (Marginal)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_4 ████████████████████████ Cpk: 1.35 (Good)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_2 █████████████████████████ Cpk: 1.48 (Good)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Head_3 ████████████████ Cpk: 0.67 (Poor)Head_1 ██████████████████████ Cpk: 1.12 (Marginal)Head_4 ████████████████████████ Cpk: 1.35 (Good)Head_2 █████████████████████████ Cpk: 1.48 (Good)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>What to look for:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Clear worst performer (fix this first)\u003C/li>\n\u003Cli>Cluster of poor performers (systematic issue?)\u003C/li>\n\u003Cli>Gap between good and bad (isolated problem)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance-i-chart-scatter\">Performance I-Chart (Scatter)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance-i-chart-scatter\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance I-Chart (Scatter)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shows Cpk over time or sample sequence:\u003C/p>\n\u003Cul>\n\u003Cli>Each point is a channel at a time period\u003C/li>\n\u003Cli>Color indicates health status\u003C/li>\n\u003Cli>Helps identify when a channel degraded\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance-boxplot\">Performance Boxplot\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance-boxplot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Boxplot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Distribution comparison across channels:\u003C/p>\n\u003Cul>\n\u003Cli>Shows spread and centering\u003C/li>\n\u003Cli>Highlights outlier channels\u003C/li>\n\u003Cli>Limited to 5 channels at once (select worst)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance-capability\">Performance Capability\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance-capability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Capability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Single-channel histogram after drilling down:\u003C/p>\n\u003Cul>\n\u003Cli>Full capability analysis for selected channel\u003C/li>\n\u003Cli>Compare to specs\u003C/li>\n\u003Cli>Detailed distribution view\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cpk-vs-cp-toggle\">Cpk vs Cp Toggle\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cpk-vs-cp-toggle\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cpk vs Cp Toggle”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Shows\u003C/th>\u003Cth>Use When\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Cpk\u003C/td>\u003Ctd>Actual capability (includes centering)\u003C/td>\u003Ctd>Production monitoring\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cp\u003C/td>\u003Ctd>Potential capability (spread only)\u003C/td>\u003Ctd>Identifying centering opportunities\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Toggle in Performance Mode:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Default: Cpk (overall assessment)\u003C/li>\n\u003Cli>Switch to Cp: See if centering could help\u003C/li>\n\u003C/ul>\n\u003Caside aria-label=\"Interpreting the Difference\" class=\"starlight-aside starlight-aside--tip\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.43909 8.85483L1.44039 8.85354L4.96668 5.33815C5.30653 4.99386 5.7685 4.79662 6.2524 4.78972L6.26553 4.78963L12.9014 4.78962L13.8479 3.84308C16.9187 0.772319 20.0546 0.770617 21.4678 0.975145C21.8617 1.02914 22.2271 1.21053 22.5083 1.4917C22.7894 1.77284 22.9708 2.13821 23.0248 2.53199C23.2294 3.94517 23.2278 7.08119 20.1569 10.1521L19.2107 11.0983V17.7338L19.2106 17.7469C19.2037 18.2308 19.0067 18.6933 18.6624 19.0331L15.1456 22.5608C14.9095 22.7966 14.6137 22.964 14.29 23.0449C13.9663 23.1259 13.6267 23.1174 13.3074 23.0204C12.9881 22.9235 12.7011 22.7417 12.4771 22.4944C12.2533 22.2473 12.1006 21.9441 12.0355 21.6171L11.1783 17.3417L6.65869 12.822L4.34847 12.3589L2.38351 11.965C2.05664 11.8998 1.75272 11.747 1.50564 11.5232C1.25835 11.2992 1.07653 11.0122 0.979561 10.6929C0.882595 10.3736 0.874125 10.034 0.955057 9.7103C1.03599 9.38659 1.20328 9.09092 1.43909 8.85483ZM6.8186 10.8724L2.94619 10.096L6.32006 6.73268H10.9583L6.8186 10.8724ZM15.2219 5.21703C17.681 2.75787 20.0783 2.75376 21.1124 2.8876C21.2462 3.92172 21.2421 6.31895 18.783 8.77812L12.0728 15.4883L8.51172 11.9272L15.2219 5.21703ZM13.9042 21.0538L13.1279 17.1811L17.2676 13.0414V17.68L13.9042 21.0538Z\">\u003C/path>\u003Cpath d=\"M9.31827 18.3446C9.45046 17.8529 9.17864 17.3369 8.68945 17.1724C8.56178 17.1294 8.43145 17.1145 8.30512 17.1243C8.10513 17.1398 7.91519 17.2172 7.76181 17.3434C7.62613 17.455 7.51905 17.6048 7.45893 17.7835C6.97634 19.2186 5.77062 19.9878 4.52406 20.4029C4.08525 20.549 3.6605 20.644 3.29471 20.7053C3.35607 20.3395 3.45098 19.9148 3.59711 19.476C4.01221 18.2294 4.78141 17.0237 6.21648 16.5411C6.39528 16.481 6.54504 16.3739 6.65665 16.2382C6.85126 16.0016 6.92988 15.678 6.84417 15.3647C6.83922 15.3466 6.83373 15.3286 6.82767 15.3106C6.74106 15.053 6.55701 14.8557 6.33037 14.7459C6.10949 14.6389 5.84816 14.615 5.59715 14.6994C5.47743 14.7397 5.36103 14.7831 5.24786 14.8294C3.22626 15.6569 2.2347 17.4173 1.75357 18.8621C1.49662 19.6337 1.36993 20.3554 1.30679 20.8818C1.27505 21.1464 1.25893 21.3654 1.25072 21.5213C1.24662 21.5993 1.24448 21.6618 1.24337 21.7066L1.243 21.7226L1.24235 21.7605L1.2422 21.7771L1.24217 21.7827L1.24217 21.7856C1.24217 22.3221 1.67703 22.7579 2.2137 22.7579L2.2155 22.7579L2.22337 22.7578L2.23956 22.7577C2.25293 22.7575 2.27096 22.7572 2.29338 22.7567C2.33821 22.7555 2.40073 22.7534 2.47876 22.7493C2.63466 22.7411 2.85361 22.725 3.11822 22.6932C3.64462 22.6301 4.36636 22.5034 5.13797 22.2464C6.58274 21.7653 8.3431 20.7738 9.17063 18.7522C9.21696 18.639 9.26037 18.5226 9.30064 18.4029C9.30716 18.3835 9.31304 18.364 9.31827 18.3446Z\">\u003C/path>\u003C/svg>Interpreting the Difference\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>If Cp >> Cpk, the process can meet specs if centered. If Cp ≈ Cpk, the process is centered but variation is the issue.\u003C/p>\u003C/div>\u003C/aside>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"health-classification\">Health Classification\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#health-classification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Health Classification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Performance Mode uses color-coded health status:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Status\u003C/th>\u003Cth>Cpk Range\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Excellent\u003C/td>\u003Ctd>≥ 1.67\u003C/td>\u003Ctd>Green\u003C/td>\u003Ctd>None needed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Good\u003C/td>\u003Ctd>1.33–1.67\u003C/td>\u003Ctd>Blue\u003C/td>\u003Ctd>Monitor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Marginal\u003C/td>\u003Ctd>1.00–1.33\u003C/td>\u003Ctd>Yellow\u003C/td>\u003Ctd>Investigate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Poor\u003C/td>\u003Ctd>< 1.00\u003C/td>\u003Ctd>Red\u003C/td>\u003Ctd>Fix immediately\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"workflow-example-bottling-line\">Workflow Example: Bottling Line\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#workflow-example-bottling-line\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Workflow Example: Bottling Line”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"setup\">Setup\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>8-head bottling line, fill weight specification: 500 ± 5g\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-1-upload-data\">Step 1: Upload Data\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-upload-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Upload Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Wide format with Head_1 through Head_8 columns.\u003C/p>\n\u003Cp>VariScout auto-detects: “Performance Mode detected. Confirm measure columns?”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-2-review-performance-pareto\">Step 2: Review Performance Pareto\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-review-performance-pareto\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Review Performance Pareto”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_3 Cpk: 0.67 [Poor] ← Focus here\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_7 Cpk: 0.89 [Poor]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_1 Cpk: 1.15 [Marginal]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_5 Cpk: 1.28 [Marginal]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_2 Cpk: 1.42 [Good]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_4 Cpk: 1.51 [Good]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_6 Cpk: 1.58 [Good]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_8 Cpk: 1.72 [Excellent]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Head_3 Cpk: 0.67 [Poor] ← Focus hereHead_7 Cpk: 0.89 [Poor]Head_1 Cpk: 1.15 [Marginal]Head_5 Cpk: 1.28 [Marginal]Head_2 Cpk: 1.42 [Good]Head_4 Cpk: 1.51 [Good]Head_6 Cpk: 1.58 [Good]Head_8 Cpk: 1.72 [Excellent]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-3-drill-into-head_3\">Step 3: Drill into Head_3\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-drill-into-head_3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Drill into Head_3”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click Head_3 bar → Transitions to Standard Dashboard\u003C/p>\n\u003Cp>Now viewing only Head_3 data with full Four Lenses analysis.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-4-analyze-with-four-lenses\">Step 4: Analyze with Four Lenses\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-analyze-with-four-lenses\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Analyze with Four Lenses”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>I-Chart:\u003C/strong> Shows instability around 10am each day\u003C/p>\n\u003Cp>\u003Cstrong>Boxplot:\u003C/strong> Time of day explains 42% (η² = 0.42)\u003C/p>\n\u003Cp>\u003Cstrong>Finding:\u003C/strong> Head_3 heats up mid-morning, causing underfill\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-5-return-to-performance-view\">Step 5: Return to Performance View\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-return-to-performance-view\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Return to Performance View”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After identifying root cause, click “Back to Performance”\u003C/p>\n\u003Cp>Plan: Add cooling to Head_3 or adjust fill timing\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-6-verify-fix\">Step 6: Verify Fix\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-6-verify-fix\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 6: Verify Fix”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After implementing fix, re-run Performance analysis:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_3 Cpk: 1.38 [Good] ← Improved!\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Head_3 Cpk: 1.38 [Good] ← Improved!\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"navigating-between-views\">Navigating Between Views\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#navigating-between-views\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Navigating Between Views”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance--standard\">Performance → Standard\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance--standard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance → Standard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Click any channel in Performance charts\u003C/li>\n\u003Cli>Selected channel becomes the focus\u003C/li>\n\u003Cli>Standard Dashboard shows that channel’s data\u003C/li>\n\u003Cli>Filter chip shows: \u003Ccode dir=\"auto\">Channel: Head_3\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard--performance\">Standard → Performance\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard--performance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard → Performance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Click “Back to Performance” button\u003C/li>\n\u003Cli>Returns to multi-channel overview\u003C/li>\n\u003Cli>Any non-channel filters preserved\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"combining-filters\">Combining Filters\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#combining-filters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Combining Filters”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You can apply filters in Standard view, then return to Performance:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Performance → Head_3 → Filter Shift=Day → Back to Performance\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Performance → Head_3 → Filter Shift=Day → Back to Performance\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Now Performance view shows all channels, but only Day shift data.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"channel-limits\">Channel Limits\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#channel-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Channel Limits”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tier\u003C/th>\u003Cth>Max Channels\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Demo\u003C/td>\u003Ctd>3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Starter\u003C/td>\u003Ctd>10\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Professional\u003C/td>\u003Ctd>50\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Enterprise\u003C/td>\u003Ctd>Unlimited\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"common-patterns\">Common Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#common-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"one-bad-channel\">One Bad Channel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#one-bad-channel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “One Bad Channel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_3 is Poor, others are Good/Excellent\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Head_3 is Poor, others are Good/Excellent\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Interpretation:\u003C/strong> Isolated equipment issue\u003C/p>\n\u003Cp>\u003Cstrong>Action:\u003C/strong> Focus on that specific channel (wear, calibration, damage)\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"all-channels-similar\">All Channels Similar\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#all-channels-similar\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “All Channels Similar”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">All channels: Cpk 1.0-1.2 (Marginal)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"All channels: Cpk 1.0-1.2 (Marginal)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Interpretation:\u003C/strong> Systematic issue affecting all channels\u003C/p>\n\u003Cp>\u003Cstrong>Action:\u003C/strong> Look at common causes (material, settings, environment)\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"degradation-over-time\">Degradation Over Time\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#degradation-over-time\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Degradation Over Time”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Early samples: All Good\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Recent samples: Several Poor\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Early samples: All GoodRecent samples: Several Poor\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Interpretation:\u003C/strong> Process drift or wear\u003C/p>\n\u003Cp>\u003Cstrong>Action:\u003C/strong> Check maintenance records, calibration schedule\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"position-based-pattern\">Position-Based Pattern\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#position-based-pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Position-Based Pattern”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_1, Head_2: Poor\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_7, Head_8: Good\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Head_1, Head_2: PoorHead_7, Head_8: Good\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Interpretation:\u003C/strong> Position on machine matters\u003C/p>\n\u003Cp>\u003Cstrong>Action:\u003C/strong> Check mechanical alignment, temperature gradients\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"best-practices\">Best Practices\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#best-practices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Best Practices”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"do\">Do\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#do\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Do”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Review all channels before drilling down\u003C/li>\n\u003Cli>Check if poor performers cluster (position, time)\u003C/li>\n\u003Cli>Compare Cp vs Cpk to understand centering\u003C/li>\n\u003Cli>Document findings per channel\u003C/li>\n\u003Cli>Re-verify after fixes\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"dont\">Don’t\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#dont\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Don’t”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Don’t ignore marginally poor channels\u003C/li>\n\u003Cli>Don’t assume all channels are independent\u003C/li>\n\u003Cli>Don’t forget to check for time-based patterns\u003C/li>\n\u003Cli>Don’t skip back to Performance view after fixing\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../analysis/performance-mode.md\">Performance Mode Feature\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"four-lenses-workflow.md\">Four Lenses Workflow\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../analysis/capability.md\">Capability Analysis\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../04-cases/oven-zones/index.md\">Oven Zones Case Study\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7729, + "localImagePaths": 7823, + "remoteImagePaths": 7824, + "frontmatter": 7825, + "imagePaths": 7826 + }, + [ + 7730, 7732, 7733, 7736, 7739, 7740, 7743, 7746, 7747, 7750, 7753, 7756, 7759, 7762, 7765, 7768, + 7771, 7774, 7777, 7780, 7783, 7786, 7789, 7792, 7795, 7798, 7801, 7804, 7807, 7810, 7813, 7816, + 7819, 7820, 7821, 7822 + ], + { "depth": 30, "slug": 7731, "text": 7719 }, + "performance-mode-workflow", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 7734, "text": 7735 }, + "when-to-use-performance-mode", + "When to Use Performance Mode", + { "depth": 33, "slug": 7737, "text": 7738 }, + "the-performance-mode-flow", + "The Performance Mode Flow", + { "depth": 33, "slug": 6592, "text": 6593 }, + { "depth": 79, "slug": 7741, "text": 7742 }, + "wide-format-performance-mode", + "Wide Format (Performance Mode)", + { "depth": 79, "slug": 7744, "text": 7745 }, + "long-format-standard-mode", + "Long Format (Standard Mode)", + { "depth": 33, "slug": 6586, "text": 6587 }, + { "depth": 79, "slug": 7748, "text": 7749 }, + "performance-pareto", + "Performance Pareto", + { "depth": 79, "slug": 7751, "text": 7752 }, + "performance-i-chart-scatter", + "Performance I-Chart (Scatter)", + { "depth": 79, "slug": 7754, "text": 7755 }, + "performance-boxplot", + "Performance Boxplot", + { "depth": 79, "slug": 7757, "text": 7758 }, + "performance-capability", + "Performance Capability", + { "depth": 33, "slug": 7760, "text": 7761 }, + "cpk-vs-cp-toggle", + "Cpk vs Cp Toggle", + { "depth": 33, "slug": 7763, "text": 7764 }, + "health-classification", + "Health Classification", + { "depth": 33, "slug": 7766, "text": 7767 }, + "workflow-example-bottling-line", + "Workflow Example: Bottling Line", + { "depth": 79, "slug": 7769, "text": 7770 }, + "setup", + "Setup", + { "depth": 79, "slug": 7772, "text": 7773 }, + "step-1-upload-data", + "Step 1: Upload Data", + { "depth": 79, "slug": 7775, "text": 7776 }, + "step-2-review-performance-pareto", + "Step 2: Review Performance Pareto", + { "depth": 79, "slug": 7778, "text": 7779 }, + "step-3-drill-into-head_3", + "Step 3: Drill into Head_3", + { "depth": 79, "slug": 7781, "text": 7782 }, + "step-4-analyze-with-four-lenses", + "Step 4: Analyze with Four Lenses", + { "depth": 79, "slug": 7784, "text": 7785 }, + "step-5-return-to-performance-view", + "Step 5: Return to Performance View", + { "depth": 79, "slug": 7787, "text": 7788 }, + "step-6-verify-fix", + "Step 6: Verify Fix", + { "depth": 33, "slug": 7790, "text": 7791 }, + "navigating-between-views", + "Navigating Between Views", + { "depth": 79, "slug": 7793, "text": 7794 }, + "performance--standard", + "Performance → Standard", + { "depth": 79, "slug": 7796, "text": 7797 }, + "standard--performance", + "Standard → Performance", + { "depth": 79, "slug": 7799, "text": 7800 }, + "combining-filters", + "Combining Filters", + { "depth": 33, "slug": 7802, "text": 7803 }, + "channel-limits", + "Channel Limits", + { "depth": 33, "slug": 7805, "text": 7806 }, + "common-patterns", + "Common Patterns", + { "depth": 79, "slug": 7808, "text": 7809 }, + "one-bad-channel", + "One Bad Channel", + { "depth": 79, "slug": 7811, "text": 7812 }, + "all-channels-similar", + "All Channels Similar", + { "depth": 79, "slug": 7814, "text": 7815 }, + "degradation-over-time", + "Degradation Over Time", + { "depth": 79, "slug": 7817, "text": 7818 }, + "position-based-pattern", + "Position-Based Pattern", + { "depth": 33, "slug": 7460, "text": 7461 }, + { "depth": 79, "slug": 5433, "text": 5434 }, + { "depth": 79, "slug": 5436, "text": 5437 }, + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 7719 }, + [], + "03-features/workflows/quick-check", + { "id": 7827, "data": 7829, "body": 7834, "filePath": 7835, "digest": 7836, "rendered": 7837 }, + { + "title": 7830, + "editUrl": 16, + "head": 7831, + "template": 18, + "sidebar": 7832, + "pagefind": 16, + "draft": 20 + }, + "Quick Check Workflow", + [], + { "hidden": 20, "attrs": 7833 }, + {}, + "# Quick Check Workflow\n\n\u003C!-- journey-phase: scout -->\n\nA 5-minute analysis pattern for daily/shift-level monitoring.\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Ctrl+V in paste area\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Analyze Data\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Map Columns\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Outcome + factor + \"Start\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">3 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read I-Chart\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Red dots = unstable\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Check Stats\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Mean, sigma, UCL, LCL\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">6 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~2 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\n_See [all process maps](process-maps.md) for PWA and Azure variants._\n\n## Overview\n\nThe Quick Check is a rapid assessment pattern for routine monitoring. Use it to catch problems early before they become major issues.\n\n## When to Use\n\n- Start of shift\n- After process changeover\n- Daily quality check\n- Before shipment approval\n- After maintenance\n\n## The 5-Minute Pattern\n\n| Step | Focus | What to Look For |\n| ---- | ---------- | -------------------------- |\n| 1 | I-Chart | Points outside limits? |\n| 2 | Capability | Cpk dropped? |\n| 3 | Boxplot | Any factor suddenly worse? |\n| 4 | Pareto | New defect type appearing? |\n| 5 | Document | Note issues found |\n\n## Step-by-Step\n\n### Step 1: I-Chart Scan (30 seconds)\n\n**Look for:**\n\n- [ ] Any points outside UCL or LCL\n- [ ] Runs of 9+ points on one side\n- [ ] Obvious trends up or down\n- [ ] Unusual patterns\n\n**If issues found:** Note the time/sample where problem appears.\n\n**Quick interpretation:**\n\n| Pattern | Likely Cause |\n| --------------- | ----------------------------------- |\n| Point above UCL | Something went wrong at that moment |\n| Point below LCL | Different type of special cause |\n| Run on one side | Process shifted |\n| Trend | Gradual drift (wear, temperature) |\n\n### Step 2: Capability Check (30 seconds)\n\n**Look at:**\n\n- Current Cpk value\n- Comparison to target (usually 1.33)\n- Change from last check\n\n**Quick interpretation:**\n\n| Cpk | Status |\n| -------- | ------------------------- |\n| ≥ 1.33 | Good - proceed |\n| 1.0-1.33 | Warning - monitor closely |\n| \u003C 1.0 | Alert - investigate now |\n\n:::tip[Baseline Comparison]\nKnow your typical Cpk. A drop from 1.5 to 1.2 is significant even though 1.2 is \"OK.\"\n:::\n\n### Step 3: Boxplot Scan (1 minute)\n\n**Quick scan for:**\n\n- Any factor showing unexpectedly high η²\n- Any box that looks different from usual\n- Outliers appearing in one factor level\n\n**If something stands out:**\n\n- Click to drill down\n- Check if it's a data issue or real effect\n- Note the factor and level\n\n### Step 4: Pareto Review (1 minute)\n\n**Look for:**\n\n- New defect category appearing\n- Existing category getting worse\n- Change in the \"vital few\"\n\n**Quick comparison:**\n\n- Is the top defect still the top?\n- Any new entries in top 3?\n- Overall defect count trending?\n\n### Step 5: Document (2 minutes)\n\n**If no issues:**\n\n```\nShift check: [Date/Time]\nStatus: OK\nCpk: [value]\nNotes: Process running normally\n```\n\n**If issues found:**\n\n```\nShift check: [Date/Time]\nStatus: ALERT\nIssue: [Description]\nChart: [Which chart showed it]\nFilter: [If you drilled down]\nAction: [What you'll do]\n```\n\n## Quick Check Checklist\n\nPrint or keep handy:\n\n```\nQUICK CHECK - [Date] [Shift]\n\n[ ] I-Chart\n [ ] All points within limits\n [ ] No runs or trends\n Noted: _______________\n\n[ ] Capability\n Cpk: _______\n [ ] ≥1.33 [ ] 1.0-1.33 [ ] \u003C1.0\n\n[ ] Boxplot\n [ ] No unexpected high η²\n [ ] No unusual outliers\n Noted: _______________\n\n[ ] Pareto\n [ ] Top defects unchanged\n [ ] No new categories\n Noted: _______________\n\nOverall: [ ] OK [ ] Monitor [ ] Alert\nSignature: _____________\n```\n\n## Escalation Guide\n\n### Green: All Clear\n\n- Continue normal operations\n- Log the check\n- No immediate action needed\n\n### Yellow: Monitor\n\nAt least one of:\n\n- Cpk between 1.0-1.33\n- Point near but not outside limits\n- New factor showing moderate effect\n\n**Action:**\n\n- Continue monitoring\n- Check more frequently\n- Alert supervisor\n\n### Red: Alert\n\nAt least one of:\n\n- Point outside control limits\n- Cpk below 1.0\n- Major shift in Pareto\n\n**Action:**\n\n- Stop and investigate\n- Document findings\n- Escalate to engineering\n- Consider holding product\n\n## Shortcuts for Speed\n\n### Keyboard Navigation\n\n| Key | Action |\n| ------------ | --------------------- |\n| `Tab` | Move between charts |\n| `Arrow keys` | Navigate within chart |\n| `Enter` | Select/drill down |\n| `Esc` | Clear filter |\n\n### Pre-Set Views\n\nSave a \"Quick Check\" view with:\n\n- I-Chart prominent\n- Capability visible\n- Boxplot showing top factor\n- Pareto showing defects\n\n## Common Quick Check Findings\n\n### \"Point Outside Limits\"\n\n**Immediate actions:**\n\n1. Check if data entry error\n2. Identify the specific sample\n3. Look at surrounding samples\n4. Check process logs for that time\n\n### \"Cpk Dropped\"\n\n**Immediate actions:**\n\n1. Check both Cp and Cpk\n2. Look at histogram shape\n3. Is it centering or spread?\n4. Check recent samples vs historical\n\n### \"New Defect Category\"\n\n**Immediate actions:**\n\n1. Verify categorization is correct\n2. Check when it started\n3. Look for pattern (shift, machine, etc.)\n4. Investigate root cause\n\n## Frequency Recommendations\n\n| Process Risk | Check Frequency |\n| ------------------------ | --------------- |\n| High (safety critical) | Every hour |\n| Medium (customer impact) | Every shift |\n| Low (internal) | Daily |\n| Stable, proven | Weekly |\n\n## Integration with Deep Dive\n\nQuick Check finds the problem. [Deep Dive](deep-dive.md) solves it.\n\n```\nQuick Check → Alert → Deep Dive\n ↓\n OK → Log and continue\n```\n\n## Related Documentation\n\n- [Deep Dive Workflow](deep-dive.md)\n- [I-Chart Feature](../analysis/i-chart.md)\n- [Capability Feature](../analysis/capability.md)\n- [Nelson Rules](../analysis/nelson-rules.md)", + "src/content/docs/03-features/workflows/quick-check.md", + "d7a8aa96c312e352", + { "html": 7838, "metadata": 7839 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"quick-check-workflow\">Quick Check Workflow\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#quick-check-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Check Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003C!-- journey-phase: scout -->\n\u003Cp>A 5-minute analysis pattern for daily/shift-level monitoring.\u003C/p>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Ctrl+V in paste area\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Analyze Data\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Map Columns\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Outcome + factor + \"Start\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">3 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read I-Chart\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Red dots = unstable\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Check Stats\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Mean, sigma, UCL, LCL\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">6 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~2 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>\u003Cem>See \u003Ca href=\"process-maps.md\">all process maps\u003C/a> for PWA and Azure variants.\u003C/em>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Quick Check is a rapid assessment pattern for routine monitoring. Use it to catch problems early before they become major issues.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"when-to-use\">When to Use\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-use\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Use”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Start of shift\u003C/li>\n\u003Cli>After process changeover\u003C/li>\n\u003Cli>Daily quality check\u003C/li>\n\u003Cli>Before shipment approval\u003C/li>\n\u003Cli>After maintenance\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-5-minute-pattern\">The 5-Minute Pattern\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-5-minute-pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The 5-Minute Pattern”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Step\u003C/th>\u003Cth>Focus\u003C/th>\u003Cth>What to Look For\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>I-Chart\u003C/td>\u003Ctd>Points outside limits?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Capability\u003C/td>\u003Ctd>Cpk dropped?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Any factor suddenly worse?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Pareto\u003C/td>\u003Ctd>New defect type appearing?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Document\u003C/td>\u003Ctd>Note issues found\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"step-by-step\">Step-by-Step\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#step-by-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step-by-Step”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-1-i-chart-scan-30-seconds\">Step 1: I-Chart Scan (30 seconds)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-i-chart-scan-30-seconds\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: I-Chart Scan (30 seconds)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Look for:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Any points outside UCL or LCL\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Runs of 9+ points on one side\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Obvious trends up or down\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Unusual patterns\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>If issues found:\u003C/strong> Note the time/sample where problem appears.\u003C/p>\n\u003Cp>\u003Cstrong>Quick interpretation:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>Likely Cause\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Point above UCL\u003C/td>\u003Ctd>Something went wrong at that moment\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Point below LCL\u003C/td>\u003Ctd>Different type of special cause\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Run on one side\u003C/td>\u003Ctd>Process shifted\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trend\u003C/td>\u003Ctd>Gradual drift (wear, temperature)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-2-capability-check-30-seconds\">Step 2: Capability Check (30 seconds)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-capability-check-30-seconds\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Capability Check (30 seconds)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Look at:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Current Cpk value\u003C/li>\n\u003Cli>Comparison to target (usually 1.33)\u003C/li>\n\u003Cli>Change from last check\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Quick interpretation:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Cpk\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>≥ 1.33\u003C/td>\u003Ctd>Good - proceed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.0-1.33\u003C/td>\u003Ctd>Warning - monitor closely\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>< 1.0\u003C/td>\u003Ctd>Alert - investigate now\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Caside aria-label=\"Baseline Comparison\" class=\"starlight-aside starlight-aside--tip\">\u003Cp class=\"starlight-aside__title\" aria-hidden=\"true\">\u003Csvg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"starlight-aside__icon\">\u003Cpath fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M1.43909 8.85483L1.44039 8.85354L4.96668 5.33815C5.30653 4.99386 5.7685 4.79662 6.2524 4.78972L6.26553 4.78963L12.9014 4.78962L13.8479 3.84308C16.9187 0.772319 20.0546 0.770617 21.4678 0.975145C21.8617 1.02914 22.2271 1.21053 22.5083 1.4917C22.7894 1.77284 22.9708 2.13821 23.0248 2.53199C23.2294 3.94517 23.2278 7.08119 20.1569 10.1521L19.2107 11.0983V17.7338L19.2106 17.7469C19.2037 18.2308 19.0067 18.6933 18.6624 19.0331L15.1456 22.5608C14.9095 22.7966 14.6137 22.964 14.29 23.0449C13.9663 23.1259 13.6267 23.1174 13.3074 23.0204C12.9881 22.9235 12.7011 22.7417 12.4771 22.4944C12.2533 22.2473 12.1006 21.9441 12.0355 21.6171L11.1783 17.3417L6.65869 12.822L4.34847 12.3589L2.38351 11.965C2.05664 11.8998 1.75272 11.747 1.50564 11.5232C1.25835 11.2992 1.07653 11.0122 0.979561 10.6929C0.882595 10.3736 0.874125 10.034 0.955057 9.7103C1.03599 9.38659 1.20328 9.09092 1.43909 8.85483ZM6.8186 10.8724L2.94619 10.096L6.32006 6.73268H10.9583L6.8186 10.8724ZM15.2219 5.21703C17.681 2.75787 20.0783 2.75376 21.1124 2.8876C21.2462 3.92172 21.2421 6.31895 18.783 8.77812L12.0728 15.4883L8.51172 11.9272L15.2219 5.21703ZM13.9042 21.0538L13.1279 17.1811L17.2676 13.0414V17.68L13.9042 21.0538Z\">\u003C/path>\u003Cpath d=\"M9.31827 18.3446C9.45046 17.8529 9.17864 17.3369 8.68945 17.1724C8.56178 17.1294 8.43145 17.1145 8.30512 17.1243C8.10513 17.1398 7.91519 17.2172 7.76181 17.3434C7.62613 17.455 7.51905 17.6048 7.45893 17.7835C6.97634 19.2186 5.77062 19.9878 4.52406 20.4029C4.08525 20.549 3.6605 20.644 3.29471 20.7053C3.35607 20.3395 3.45098 19.9148 3.59711 19.476C4.01221 18.2294 4.78141 17.0237 6.21648 16.5411C6.39528 16.481 6.54504 16.3739 6.65665 16.2382C6.85126 16.0016 6.92988 15.678 6.84417 15.3647C6.83922 15.3466 6.83373 15.3286 6.82767 15.3106C6.74106 15.053 6.55701 14.8557 6.33037 14.7459C6.10949 14.6389 5.84816 14.615 5.59715 14.6994C5.47743 14.7397 5.36103 14.7831 5.24786 14.8294C3.22626 15.6569 2.2347 17.4173 1.75357 18.8621C1.49662 19.6337 1.36993 20.3554 1.30679 20.8818C1.27505 21.1464 1.25893 21.3654 1.25072 21.5213C1.24662 21.5993 1.24448 21.6618 1.24337 21.7066L1.243 21.7226L1.24235 21.7605L1.2422 21.7771L1.24217 21.7827L1.24217 21.7856C1.24217 22.3221 1.67703 22.7579 2.2137 22.7579L2.2155 22.7579L2.22337 22.7578L2.23956 22.7577C2.25293 22.7575 2.27096 22.7572 2.29338 22.7567C2.33821 22.7555 2.40073 22.7534 2.47876 22.7493C2.63466 22.7411 2.85361 22.725 3.11822 22.6932C3.64462 22.6301 4.36636 22.5034 5.13797 22.2464C6.58274 21.7653 8.3431 20.7738 9.17063 18.7522C9.21696 18.639 9.26037 18.5226 9.30064 18.4029C9.30716 18.3835 9.31304 18.364 9.31827 18.3446Z\">\u003C/path>\u003C/svg>Baseline Comparison\u003C/p>\u003Cdiv class=\"starlight-aside__content\">\u003Cp>Know your typical Cpk. A drop from 1.5 to 1.2 is significant even though 1.2 is “OK.”\u003C/p>\u003C/div>\u003C/aside>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-3-boxplot-scan-1-minute\">Step 3: Boxplot Scan (1 minute)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-boxplot-scan-1-minute\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Boxplot Scan (1 minute)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Quick scan for:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Any factor showing unexpectedly high η²\u003C/li>\n\u003Cli>Any box that looks different from usual\u003C/li>\n\u003Cli>Outliers appearing in one factor level\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>If something stands out:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Click to drill down\u003C/li>\n\u003Cli>Check if it’s a data issue or real effect\u003C/li>\n\u003Cli>Note the factor and level\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-4-pareto-review-1-minute\">Step 4: Pareto Review (1 minute)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-pareto-review-1-minute\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Pareto Review (1 minute)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Look for:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>New defect category appearing\u003C/li>\n\u003Cli>Existing category getting worse\u003C/li>\n\u003Cli>Change in the “vital few”\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Quick comparison:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Is the top defect still the top?\u003C/li>\n\u003Cli>Any new entries in top 3?\u003C/li>\n\u003Cli>Overall defect count trending?\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-5-document-2-minutes\">Step 5: Document (2 minutes)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-document-2-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Document (2 minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>If no issues:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Shift check: [Date/Time]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Status: OK\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cpk: [value]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Notes: Process running normally\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Shift check: [Date/Time]Status: OKCpk: [value]Notes: Process running normally\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>If issues found:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Shift check: [Date/Time]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Status: ALERT\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Issue: [Description]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Chart: [Which chart showed it]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Filter: [If you drilled down]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Action: [What you'll do]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Shift check: [Date/Time]Status: ALERTIssue: [Description]Chart: [Which chart showed it]Filter: [If you drilled down]Action: [What you'll do]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"quick-check-checklist\">Quick Check Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#quick-check-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Check Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Print or keep handy:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">QUICK CHECK - [Date] [Shift]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] I-Chart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] All points within limits\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] No runs or trends\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Noted: _______________\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Capability\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cpk: _______\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] ≥1.33 [ ] 1.0-1.33 [ ] <1.0\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Boxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] No unexpected high η²\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] No unusual outliers\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Noted: _______________\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Pareto\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] Top defects unchanged\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[ ] No new categories\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Noted: _______________\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Overall: [ ] OK [ ] Monitor [ ] Alert\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Signature: _____________\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"QUICK CHECK - [Date] [Shift][ ] I-Chart [ ] All points within limits [ ] No runs or trends Noted: _______________[ ] Capability Cpk: _______ [ ] ≥1.33 [ ] 1.0-1.33 [ ] \u003C1.0[ ] Boxplot [ ] No unexpected high η² [ ] No unusual outliers Noted: _______________[ ] Pareto [ ] Top defects unchanged [ ] No new categories Noted: _______________Overall: [ ] OK [ ] Monitor [ ] AlertSignature: _____________\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"escalation-guide\">Escalation Guide\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#escalation-guide\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Escalation Guide”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"green-all-clear\">Green: All Clear\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#green-all-clear\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Green: All Clear”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Continue normal operations\u003C/li>\n\u003Cli>Log the check\u003C/li>\n\u003Cli>No immediate action needed\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"yellow-monitor\">Yellow: Monitor\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#yellow-monitor\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Yellow: Monitor”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>At least one of:\u003C/p>\n\u003Cul>\n\u003Cli>Cpk between 1.0-1.33\u003C/li>\n\u003Cli>Point near but not outside limits\u003C/li>\n\u003Cli>New factor showing moderate effect\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Action:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Continue monitoring\u003C/li>\n\u003Cli>Check more frequently\u003C/li>\n\u003Cli>Alert supervisor\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"red-alert\">Red: Alert\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#red-alert\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Red: Alert”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>At least one of:\u003C/p>\n\u003Cul>\n\u003Cli>Point outside control limits\u003C/li>\n\u003Cli>Cpk below 1.0\u003C/li>\n\u003Cli>Major shift in Pareto\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Action:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Stop and investigate\u003C/li>\n\u003Cli>Document findings\u003C/li>\n\u003Cli>Escalate to engineering\u003C/li>\n\u003Cli>Consider holding product\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"shortcuts-for-speed\">Shortcuts for Speed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#shortcuts-for-speed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Shortcuts for Speed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"keyboard-navigation\">Keyboard Navigation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#keyboard-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyboard Navigation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Key\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Tab\u003C/code>\u003C/td>\u003Ctd>Move between charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Arrow keys\u003C/code>\u003C/td>\u003Ctd>Navigate within chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Enter\u003C/code>\u003C/td>\u003Ctd>Select/drill down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Esc\u003C/code>\u003C/td>\u003Ctd>Clear filter\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pre-set-views\">Pre-Set Views\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pre-set-views\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pre-Set Views”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Save a “Quick Check” view with:\u003C/p>\n\u003Cul>\n\u003Cli>I-Chart prominent\u003C/li>\n\u003Cli>Capability visible\u003C/li>\n\u003Cli>Boxplot showing top factor\u003C/li>\n\u003Cli>Pareto showing defects\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"common-quick-check-findings\">Common Quick Check Findings\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#common-quick-check-findings\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Quick Check Findings”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"point-outside-limits\">”Point Outside Limits”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#point-outside-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “”Point Outside Limits””\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Immediate actions:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Check if data entry error\u003C/li>\n\u003Cli>Identify the specific sample\u003C/li>\n\u003Cli>Look at surrounding samples\u003C/li>\n\u003Cli>Check process logs for that time\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cpk-dropped\">”Cpk Dropped”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cpk-dropped\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “”Cpk Dropped””\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Immediate actions:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Check both Cp and Cpk\u003C/li>\n\u003Cli>Look at histogram shape\u003C/li>\n\u003Cli>Is it centering or spread?\u003C/li>\n\u003Cli>Check recent samples vs historical\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"new-defect-category\">”New Defect Category”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#new-defect-category\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “”New Defect Category””\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Immediate actions:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Verify categorization is correct\u003C/li>\n\u003Cli>Check when it started\u003C/li>\n\u003Cli>Look for pattern (shift, machine, etc.)\u003C/li>\n\u003Cli>Investigate root cause\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"frequency-recommendations\">Frequency Recommendations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#frequency-recommendations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Frequency Recommendations”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Process Risk\u003C/th>\u003Cth>Check Frequency\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>High (safety critical)\u003C/td>\u003Ctd>Every hour\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Medium (customer impact)\u003C/td>\u003Ctd>Every shift\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Low (internal)\u003C/td>\u003Ctd>Daily\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Stable, proven\u003C/td>\u003Ctd>Weekly\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"integration-with-deep-dive\">Integration with Deep Dive\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#integration-with-deep-dive\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integration with Deep Dive”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Quick Check finds the problem. \u003Ca href=\"deep-dive.md\">Deep Dive\u003C/a> solves it.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Quick Check → Alert → Deep Dive\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">OK → Log and continue\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Quick Check → Alert → Deep Dive ↓ OK → Log and continue\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"deep-dive.md\">Deep Dive Workflow\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../analysis/i-chart.md\">I-Chart Feature\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../analysis/capability.md\">Capability Feature\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../analysis/nelson-rules.md\">Nelson Rules\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7840, + "localImagePaths": 7905, + "remoteImagePaths": 7906, + "frontmatter": 7907, + "imagePaths": 7908 + }, + [ + 7841, 7843, 7844, 7845, 7848, 7849, 7852, 7855, 7858, 7861, 7864, 7867, 7870, 7873, 7876, 7879, + 7882, 7883, 7886, 7889, 7892, 7895, 7898, 7901, 7904 + ], + { "depth": 30, "slug": 7842, "text": 7830 }, + "quick-check-workflow", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 6509, "text": 6510 }, + { "depth": 33, "slug": 7846, "text": 7847 }, + "the-5-minute-pattern", + "The 5-Minute Pattern", + { "depth": 33, "slug": 4137, "text": 4138 }, + { "depth": 79, "slug": 7850, "text": 7851 }, + "step-1-i-chart-scan-30-seconds", + "Step 1: I-Chart Scan (30 seconds)", + { "depth": 79, "slug": 7853, "text": 7854 }, + "step-2-capability-check-30-seconds", + "Step 2: Capability Check (30 seconds)", + { "depth": 79, "slug": 7856, "text": 7857 }, + "step-3-boxplot-scan-1-minute", + "Step 3: Boxplot Scan (1 minute)", + { "depth": 79, "slug": 7859, "text": 7860 }, + "step-4-pareto-review-1-minute", + "Step 4: Pareto Review (1 minute)", + { "depth": 79, "slug": 7862, "text": 7863 }, + "step-5-document-2-minutes", + "Step 5: Document (2 minutes)", + { "depth": 33, "slug": 7865, "text": 7866 }, + "quick-check-checklist", + "Quick Check Checklist", + { "depth": 33, "slug": 7868, "text": 7869 }, + "escalation-guide", + "Escalation Guide", + { "depth": 79, "slug": 7871, "text": 7872 }, + "green-all-clear", + "Green: All Clear", + { "depth": 79, "slug": 7874, "text": 7875 }, + "yellow-monitor", + "Yellow: Monitor", + { "depth": 79, "slug": 7877, "text": 7878 }, + "red-alert", + "Red: Alert", + { "depth": 33, "slug": 7880, "text": 7881 }, + "shortcuts-for-speed", + "Shortcuts for Speed", + { "depth": 79, "slug": 1194, "text": 1195 }, + { "depth": 79, "slug": 7884, "text": 7885 }, + "pre-set-views", + "Pre-Set Views", + { "depth": 33, "slug": 7887, "text": 7888 }, + "common-quick-check-findings", + "Common Quick Check Findings", + { "depth": 79, "slug": 7890, "text": 7891 }, + "point-outside-limits", + "”Point Outside Limits”", + { "depth": 79, "slug": 7893, "text": 7894 }, + "cpk-dropped", + "”Cpk Dropped”", + { "depth": 79, "slug": 7896, "text": 7897 }, + "new-defect-category", + "”New Defect Category”", + { "depth": 33, "slug": 7899, "text": 7900 }, + "frequency-recommendations", + "Frequency Recommendations", + { "depth": 33, "slug": 7902, "text": 7903 }, + "integration-with-deep-dive", + "Integration with Deep Dive", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 7830 }, + [], + "03-features/workflows/process-maps", + { "id": 7909, "data": 7911, "body": 7915, "filePath": 7916, "digest": 7917, "rendered": 7918 }, + { + "title": 7608, + "editUrl": 16, + "head": 7912, + "template": 18, + "sidebar": 7913, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 7914 }, + {}, + "# Visual Process Maps\n\nScannable, step-by-step maps showing exactly how many user actions each analysis workflow requires.\n\n## How to Read These Maps\n\nEach map is a horizontal flow of step boxes connected by arrows. Every box shows:\n\n- **Bold label** — what the user does (\"Paste Data\", \"Click Bar\")\n- **Muted detail** — what appears or what the system does\n- **Badge below** — number of user actions for that step\n\nThe summary strip at the end shows **total actions** and **approximate time**.\n\n### Step Types\n\n| Color | Type | Meaning |\n| ------------------- | ------------ | ------------------------------------------ |\n| Gray border | **Input** | User provides data (paste, type, upload) |\n| Blue border | **Navigate** | User clicks to move through UI |\n| Amber border | **Analyze** | User triggers analysis or filters data |\n| Green dashed border | **Read** | User reads result — 0 clicks |\n| Purple border | **Decision** | Analyst reads result and chooses next step |\n\n### Counting Rules\n\n**Counts as 1 action:** a click, a keyboard shortcut (Ctrl+V, Enter), or typing a value into a field.\n\n**Does NOT count:** scrolling, reading, system processing, auto-detection, or hovering for tooltips.\n\n---\n\n## Flow 1: Stability Check\n\n_\"Is my process stable?\"_\n\n### PWA\n\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Paste from Excel\", Ctrl+V\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Analyze Data\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Map Columns\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Outcome + factor + \"Start\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">3 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read I-Chart\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Red dots = unstable\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Check Stats\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Mean, sigma, UCL, LCL\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">6 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~2 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\n**Decision:** All blue dots → stable. Any red dots → investigate with [Root Cause Analysis](#flow-2-root-cause-analysis).\n\n### PWA\n\n### Azure\n\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">New Analysis\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click in project list\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste or Upload\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Ctrl+V or select file\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Auto-detects columns\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read I-Chart\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Red dots = unstable\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Check Stats\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Mean, sigma, UCL, LCL\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Persists to OneDrive\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">5 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~2 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\nAzure skips column mapping when auto-detection succeeds, saving 1 action. The Save step persists to OneDrive.\n\n\n---\n\n## Flow 2: Root Cause Analysis\n\n_\"What's causing variation?\"_\n\n### PWA\n\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Paste from Excel\", Ctrl+V\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Analyze Data\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Map Columns\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Outcome + 2 factors + \"Start\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">4 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read ANOVA\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Check eta-squared under Boxplot\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Filter Top Factor\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click highest-eta bar\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Filtered\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Variation explained? Cpk improved?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">8 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~5 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\n**Decision:** eta-squared > 50% → primary driver found. Filter isolates the cause.\n\n### PWA\n\n### Azure\n\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">New Analysis\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click in project list\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Upload File\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Select CSV from dialog\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Auto-detects columns\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read ANOVA\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Check eta-squared under Boxplot\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Filter Top Factor\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click bar or mindmap node\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Filtered\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Variation explained? Cpk improved?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Persists to OneDrive\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">6 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~5 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\nAzure's mindmap provides an alternative drill-down path alongside the Boxplot.\n\n\n---\n\n## Flow 3: Capability Check\n\n_\"Do we meet specs?\"_\n\n### PWA\n\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Paste from Excel\", Ctrl+V\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Analyze Data\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Map Columns\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Outcome + factor + \"Start\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">3 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Enter Specs\u003C/div>\n \u003Cdiv class=\"process-step__detail\">+ Specs, USL, LSL, Apply\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">6 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Cp/Cpk\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Capability indices in stats panel\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">View Histogram\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Histogram\" tab\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Distribution\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Shape vs spec lines\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">13 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~3 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\n**Decision:** Cpk > 1.33 → capable. Cpk \u003C 1.0 → improvement needed.\n\n### PWA\n\n### Azure\n\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">New Analysis\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click in project list\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Upload File\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Select CSV from dialog\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Auto-detects columns\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Enter Specs\u003C/div>\n \u003Cdiv class=\"process-step__detail\">+ Specs, USL, LSL, Apply\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">6 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Cp/Cpk\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Capability indices in stats panel\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">View Histogram\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Histogram\" tab\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Distribution\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Shape vs spec lines\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Persists to OneDrive\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">12 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~3 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\nAzure saves 1 action via auto-detection, but adds 1 for the Save step.\n\n\n---\n\n## Comparison: Basic Flows\n\n| Flow | PWA | Azure | Core Question |\n| ---------------- | ---------- | ---------- | ---------------------- |\n| Stability Check | 6 actions | 5 actions | Is it stable? |\n| Root Cause | 8 actions | 6 actions | What causes variation? |\n| Capability Check | 13 actions | 12 actions | Do we meet specs? |\n\nAzure is slightly fewer actions because file upload with auto-detection skips column mapping. The Save step adds 1 action but provides OneDrive persistence.\n\n---\n\n## Analyst Flow A: Process Investigation\n\n_Quality is dropping — find out why._\n\n**Trigger:** Customer complaint or Cpk alert. The analyst needs to find the root cause and quantify its impact.\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Load Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Paste or upload process data\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2-3 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Start Analysis\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Map columns, click Start\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">3-4 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Scan I-Chart\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Red dots, runs, trends?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--decision\">\n \u003Cdiv class=\"process-step__title\">Stable?\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Blue only → skip ahead. Red → step 5\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Investigate Point\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click red point, check timestamp\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read ANOVA\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Check eta-squared under Boxplot\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Drill Top Factor\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click highest-eta bar\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Filtered Cpk\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Did capability improve?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--decision\">\n \u003Cdiv class=\"process-step__title\">Enough?\u003C/div>\n \u003Cdiv class=\"process-step__detail\">>50% explained → continue. Otherwise repeat drill\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Enter Specs\u003C/div>\n \u003Cdiv class=\"process-step__detail\">+ Specs, USL, LSL, Apply\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">6 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Capability\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Filtered vs overall Cpk\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Histogram\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Distribution shape\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Export / Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Copy chart or save project\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">~15 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~10 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\n**Outcome:** \"Factor X on Level Y causes Z% of variation. Cpk improves from A to B when filtered.\"\n\nSee [Investigation to Action](investigation-to-action.md) for the full three-phase methodology.\n\n---\n\n## Analyst Flow B: Predict Improvement\n\n_Root cause is known — can we fix it? What would change?_\n\n**Trigger:** Root cause identified (from Flow A). The analyst wants to model \"what if we fix this?\" before investing in a change.\n\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Load Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Same data or saved project\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1-3 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Apply Filter\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Re-apply known filter path\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1-2 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Confirm Baseline\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Current Cpk with filter\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Regression\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Regression\" tab\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Model\u003C/div>\n \u003Cdiv class=\"process-step__detail\">R-squared, significant predictors\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--decision\">\n \u003Cdiv class=\"process-step__title\">Good Model?\u003C/div>\n \u003Cdiv class=\"process-step__detail\">R² > 0.5 → continue. R² \u003C 0.3 → need more data\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Open What-If\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"What-If Simulator\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Set Targets\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Adjust predictor sliders\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2-4 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Prediction\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Predicted value + CI\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--decision\">\n \u003Cdiv class=\"process-step__title\">Meets Spec?\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Cpk > 1.33 → proceed. Otherwise adjust\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Return & Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Back + save project\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">~12 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~8 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\n**Outcome:** \"If we set Factor X to Level Y, predicted Cpk improves to Z with 95% confidence.\"\n\n---\n\n## All Flows at a Glance\n\n| Flow | Actions | Time | Core Question | Difficulty |\n| -------------------------------------------------------------- | ------- | ------- | ------------------------ | ---------- |\n| [Stability Check](#flow-1-stability-check) | 5-6 | ~2 min | Is it stable? | Beginner |\n| [Root Cause](#flow-2-root-cause-analysis) | 6-8 | ~5 min | What causes variation? | Beginner |\n| [Capability Check](#flow-3-capability-check) | 12-13 | ~3 min | Do we meet specs? | Beginner |\n| [Process Investigation](#analyst-flow-a-process-investigation) | ~15 | ~10 min | Why is quality dropping? | Analyst |\n| [Predict Improvement](#analyst-flow-b-predict-improvement) | ~12 | ~8 min | Can we fix it? | Analyst |\n\n## Related Documentation\n\n- [Four Lenses Workflow](four-lenses-workflow.md) — The foundational methodology\n- [Drill-Down Workflow](drill-down-workflow.md) — Progressive stratification mechanics\n- [Investigation to Action](investigation-to-action.md) — Three-phase analyst workflow\n- [Quick Check](quick-check.md) — 5-minute monitoring pattern\n- [Decision Trees](decision-trees.md) — Which analysis to use when", + "src/content/docs/03-features/workflows/process-maps.md", + "2b888acd12ded83e", + { "html": 7919, "metadata": 7920 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"visual-process-maps\">Visual Process Maps\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#visual-process-maps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Process Maps”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Scannable, step-by-step maps showing exactly how many user actions each analysis workflow requires.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-to-read-these-maps\">How to Read These Maps\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-to-read-these-maps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How to Read These Maps”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each map is a horizontal flow of step boxes connected by arrows. Every box shows:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Bold label\u003C/strong> — what the user does (“Paste Data”, “Click Bar”)\u003C/li>\n\u003Cli>\u003Cstrong>Muted detail\u003C/strong> — what appears or what the system does\u003C/li>\n\u003Cli>\u003Cstrong>Badge below\u003C/strong> — number of user actions for that step\u003C/li>\n\u003C/ul>\n\u003Cp>The summary strip at the end shows \u003Cstrong>total actions\u003C/strong> and \u003Cstrong>approximate time\u003C/strong>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-types\">Step Types\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-types\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step Types”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Color\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Gray border\u003C/td>\u003Ctd>\u003Cstrong>Input\u003C/strong>\u003C/td>\u003Ctd>User provides data (paste, type, upload)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Blue border\u003C/td>\u003Ctd>\u003Cstrong>Navigate\u003C/strong>\u003C/td>\u003Ctd>User clicks to move through UI\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Amber border\u003C/td>\u003Ctd>\u003Cstrong>Analyze\u003C/strong>\u003C/td>\u003Ctd>User triggers analysis or filters data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Green dashed border\u003C/td>\u003Ctd>\u003Cstrong>Read\u003C/strong>\u003C/td>\u003Ctd>User reads result — 0 clicks\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Purple border\u003C/td>\u003Ctd>\u003Cstrong>Decision\u003C/strong>\u003C/td>\u003Ctd>Analyst reads result and chooses next step\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"counting-rules\">Counting Rules\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#counting-rules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Counting Rules”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Counts as 1 action:\u003C/strong> a click, a keyboard shortcut (Ctrl+V, Enter), or typing a value into a field.\u003C/p>\n\u003Cp>\u003Cstrong>Does NOT count:\u003C/strong> scrolling, reading, system processing, auto-detection, or hovering for tooltips.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"flow-1-stability-check\">Flow 1: Stability Check\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#flow-1-stability-check\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 1: Stability Check”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Is my process stable?”\u003C/em>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa\">PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Paste from Excel\", Ctrl+V\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Analyze Data\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Map Columns\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Outcome + factor + \"Start\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">3 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read I-Chart\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Red dots = unstable\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Check Stats\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Mean, sigma, UCL, LCL\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">6 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~2 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>\u003Cstrong>Decision:\u003C/strong> All blue dots → stable. Any red dots → investigate with \u003Ca href=\"#flow-2-root-cause-analysis\">Root Cause Analysis\u003C/a>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-1\">PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure\">Azure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">New Analysis\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click in project list\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste or Upload\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Ctrl+V or select file\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Auto-detects columns\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read I-Chart\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Red dots = unstable\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Check Stats\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Mean, sigma, UCL, LCL\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Persists to OneDrive\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">5 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~2 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>Azure skips column mapping when auto-detection succeeds, saving 1 action. The Save step persists to OneDrive.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"flow-2-root-cause-analysis\">Flow 2: Root Cause Analysis\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#flow-2-root-cause-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 2: Root Cause Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“What’s causing variation?”\u003C/em>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-2\">PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Paste from Excel\", Ctrl+V\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Analyze Data\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Map Columns\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Outcome + 2 factors + \"Start\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">4 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read ANOVA\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Check eta-squared under Boxplot\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Filter Top Factor\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click highest-eta bar\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Filtered\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Variation explained? Cpk improved?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">8 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~5 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>\u003Cstrong>Decision:\u003C/strong> eta-squared > 50% → primary driver found. Filter isolates the cause.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-3\">PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-1\">Azure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">New Analysis\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click in project list\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Upload File\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Select CSV from dialog\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Auto-detects columns\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read ANOVA\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Check eta-squared under Boxplot\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Filter Top Factor\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click bar or mindmap node\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Filtered\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Variation explained? Cpk improved?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Persists to OneDrive\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">6 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~5 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>Azure’s mindmap provides an alternative drill-down path alongside the Boxplot.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"flow-3-capability-check\">Flow 3: Capability Check\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#flow-3-capability-check\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow 3: Capability Check”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Do we meet specs?”\u003C/em>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-4\">PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Paste Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Paste from Excel\", Ctrl+V\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Analyze Data\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Map Columns\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Outcome + factor + \"Start\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">3 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Enter Specs\u003C/div>\n \u003Cdiv class=\"process-step__detail\">+ Specs, USL, LSL, Apply\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">6 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Cp/Cpk\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Capability indices in stats panel\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">View Histogram\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Histogram\" tab\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Distribution\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Shape vs spec lines\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">13 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~3 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>\u003Cstrong>Decision:\u003C/strong> Cpk > 1.33 → capable. Cpk < 1.0 → improvement needed.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-5\">PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-5\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-2\">Azure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">New Analysis\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click in project list\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Upload File\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Select CSV from dialog\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Analyze\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Auto-detects columns\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Enter Specs\u003C/div>\n \u003Cdiv class=\"process-step__detail\">+ Specs, USL, LSL, Apply\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">6 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Cp/Cpk\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Capability indices in stats panel\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">View Histogram\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Histogram\" tab\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Distribution\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Shape vs spec lines\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Persists to OneDrive\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">12 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~3 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>Azure saves 1 action via auto-detection, but adds 1 for the Save step.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"comparison-basic-flows\">Comparison: Basic Flows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#comparison-basic-flows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Comparison: Basic Flows”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Flow\u003C/th>\u003Cth>PWA\u003C/th>\u003Cth>Azure\u003C/th>\u003Cth>Core Question\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Stability Check\u003C/td>\u003Ctd>6 actions\u003C/td>\u003Ctd>5 actions\u003C/td>\u003Ctd>Is it stable?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Root Cause\u003C/td>\u003Ctd>8 actions\u003C/td>\u003Ctd>6 actions\u003C/td>\u003Ctd>What causes variation?\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability Check\u003C/td>\u003Ctd>13 actions\u003C/td>\u003Ctd>12 actions\u003C/td>\u003Ctd>Do we meet specs?\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Azure is slightly fewer actions because file upload with auto-detection skips column mapping. The Save step adds 1 action but provides OneDrive persistence.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analyst-flow-a-process-investigation\">Analyst Flow A: Process Investigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analyst-flow-a-process-investigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analyst Flow A: Process Investigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>Quality is dropping — find out why.\u003C/em>\u003C/p>\n\u003Cp>\u003Cstrong>Trigger:\u003C/strong> Customer complaint or Cpk alert. The analyst needs to find the root cause and quantify its impact.\u003C/p>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Load Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Paste or upload process data\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2-3 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Start Analysis\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Map columns, click Start\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">3-4 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Scan I-Chart\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Red dots, runs, trends?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--decision\">\n \u003Cdiv class=\"process-step__title\">Stable?\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Blue only → skip ahead. Red → step 5\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Investigate Point\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click red point, check timestamp\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read ANOVA\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Check eta-squared under Boxplot\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Drill Top Factor\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click highest-eta bar\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Filtered Cpk\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Did capability improve?\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--decision\">\n \u003Cdiv class=\"process-step__title\">Enough?\u003C/div>\n \u003Cdiv class=\"process-step__detail\">>50% explained → continue. Otherwise repeat drill\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Enter Specs\u003C/div>\n \u003Cdiv class=\"process-step__detail\">+ Specs, USL, LSL, Apply\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">6 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Capability\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Filtered vs overall Cpk\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Histogram\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Distribution shape\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Export / Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Copy chart or save project\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">~15 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~10 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>\u003Cstrong>Outcome:\u003C/strong> “Factor X on Level Y causes Z% of variation. Cpk improves from A to B when filtered.”\u003C/p>\n\u003Cp>See \u003Ca href=\"investigation-to-action.md\">Investigation to Action\u003C/a> for the full three-phase methodology.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analyst-flow-b-predict-improvement\">Analyst Flow B: Predict Improvement\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analyst-flow-b-predict-improvement\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analyst Flow B: Predict Improvement”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>Root cause is known — can we fix it? What would change?\u003C/em>\u003C/p>\n\u003Cp>\u003Cstrong>Trigger:\u003C/strong> Root cause identified (from Flow A). The analyst wants to model “what if we fix this?” before investing in a change.\u003C/p>\n\u003Cdiv class=\"process-map\">\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--input\">\n \u003Cdiv class=\"process-step__title\">Load Data\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Same data or saved project\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1-3 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Apply Filter\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Re-apply known filter path\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1-2 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Confirm Baseline\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Current Cpk with filter\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Regression\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"Regression\" tab\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Model\u003C/div>\n \u003Cdiv class=\"process-step__detail\">R-squared, significant predictors\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--decision\">\n \u003Cdiv class=\"process-step__title\">Good Model?\u003C/div>\n \u003Cdiv class=\"process-step__detail\">R² > 0.5 → continue. R² < 0.3 → need more data\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Open What-If\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Click \"What-If Simulator\"\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">1 click\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--analyze\">\n \u003Cdiv class=\"process-step__title\">Set Targets\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Adjust predictor sliders\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2-4 actions\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--read\">\n \u003Cdiv class=\"process-step__title\">Read Prediction\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Predicted value + CI\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--decision\">\n \u003Cdiv class=\"process-step__title\">Meets Spec?\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Cpk > 1.33 → proceed. Otherwise adjust\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">0 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-arrow\">\u003C/div>\n \u003Cdiv class=\"process-step\">\n \u003Cdiv class=\"process-step__box process-step__box--navigate\">\n \u003Cdiv class=\"process-step__title\">Return & Save\u003C/div>\n \u003Cdiv class=\"process-step__detail\">Back + save project\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-step__clicks\">2 clicks\u003C/div>\n \u003C/div>\n \u003Cdiv class=\"process-summary\">\n \u003Cdiv class=\"process-summary__total\">~12 actions\u003C/div>\n \u003Cdiv class=\"process-summary__time\">~8 min\u003C/div>\n \u003C/div>\n\u003C/div>\n\u003Cp>\u003Cstrong>Outcome:\u003C/strong> “If we set Factor X to Level Y, predicted Cpk improves to Z with 95% confidence.”\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"all-flows-at-a-glance\">All Flows at a Glance\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#all-flows-at-a-glance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “All Flows at a Glance”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Flow\u003C/th>\u003Cth>Actions\u003C/th>\u003Cth>Time\u003C/th>\u003Cth>Core Question\u003C/th>\u003Cth>Difficulty\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ca href=\"#flow-1-stability-check\">Stability Check\u003C/a>\u003C/td>\u003Ctd>5-6\u003C/td>\u003Ctd>~2 min\u003C/td>\u003Ctd>Is it stable?\u003C/td>\u003Ctd>Beginner\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"#flow-2-root-cause-analysis\">Root Cause\u003C/a>\u003C/td>\u003Ctd>6-8\u003C/td>\u003Ctd>~5 min\u003C/td>\u003Ctd>What causes variation?\u003C/td>\u003Ctd>Beginner\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"#flow-3-capability-check\">Capability Check\u003C/a>\u003C/td>\u003Ctd>12-13\u003C/td>\u003Ctd>~3 min\u003C/td>\u003Ctd>Do we meet specs?\u003C/td>\u003Ctd>Beginner\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"#analyst-flow-a-process-investigation\">Process Investigation\u003C/a>\u003C/td>\u003Ctd>~15\u003C/td>\u003Ctd>~10 min\u003C/td>\u003Ctd>Why is quality dropping?\u003C/td>\u003Ctd>Analyst\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ca href=\"#analyst-flow-b-predict-improvement\">Predict Improvement\u003C/a>\u003C/td>\u003Ctd>~12\u003C/td>\u003Ctd>~8 min\u003C/td>\u003Ctd>Can we fix it?\u003C/td>\u003Ctd>Analyst\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"four-lenses-workflow.md\">Four Lenses Workflow\u003C/a> — The foundational methodology\u003C/li>\n\u003Cli>\u003Ca href=\"drill-down-workflow.md\">Drill-Down Workflow\u003C/a> — Progressive stratification mechanics\u003C/li>\n\u003Cli>\u003Ca href=\"investigation-to-action.md\">Investigation to Action\u003C/a> — Three-phase analyst workflow\u003C/li>\n\u003Cli>\u003Ca href=\"quick-check.md\">Quick Check\u003C/a> — 5-minute monitoring pattern\u003C/li>\n\u003Cli>\u003Ca href=\"decision-trees.md\">Decision Trees\u003C/a> — Which analysis to use when\u003C/li>\n\u003C/ul>", + { + "headings": 7921, + "localImagePaths": 7970, + "remoteImagePaths": 7971, + "frontmatter": 7972, + "imagePaths": 7973 + }, + [ + 7922, 7923, 7926, 7929, 7932, 7935, 7936, 7938, 7939, 7942, 7944, 7946, 7948, 7951, 7953, 7955, + 7957, 7960, 7963, 7966, 7969 + ], + { "depth": 30, "slug": 7607, "text": 7608 }, + { "depth": 33, "slug": 7924, "text": 7925 }, + "how-to-read-these-maps", + "How to Read These Maps", + { "depth": 79, "slug": 7927, "text": 7928 }, + "step-types", + "Step Types", + { "depth": 79, "slug": 7930, "text": 7931 }, + "counting-rules", + "Counting Rules", + { "depth": 33, "slug": 7933, "text": 7934 }, + "flow-1-stability-check", + "Flow 1: Stability Check", + { "depth": 79, "slug": 5545, "text": 5546 }, + { "depth": 79, "slug": 7937, "text": 5546 }, + "pwa-1", + { "depth": 79, "slug": 5548, "text": 5549 }, + { "depth": 33, "slug": 7940, "text": 7941 }, + "flow-2-root-cause-analysis", + "Flow 2: Root Cause Analysis", + { "depth": 79, "slug": 7943, "text": 5546 }, + "pwa-2", + { "depth": 79, "slug": 7945, "text": 5546 }, + "pwa-3", + { "depth": 79, "slug": 7947, "text": 5549 }, + "azure-1", + { "depth": 33, "slug": 7949, "text": 7950 }, + "flow-3-capability-check", + "Flow 3: Capability Check", + { "depth": 79, "slug": 7952, "text": 5546 }, + "pwa-4", + { "depth": 79, "slug": 7954, "text": 5546 }, + "pwa-5", + { "depth": 79, "slug": 7956, "text": 5549 }, + "azure-2", + { "depth": 33, "slug": 7958, "text": 7959 }, + "comparison-basic-flows", + "Comparison: Basic Flows", + { "depth": 33, "slug": 7961, "text": 7962 }, + "analyst-flow-a-process-investigation", + "Analyst Flow A: Process Investigation", + { "depth": 33, "slug": 7964, "text": 7965 }, + "analyst-flow-b-predict-improvement", + "Analyst Flow B: Predict Improvement", + { "depth": 33, "slug": 7967, "text": 7968 }, + "all-flows-at-a-glance", + "All Flows at a Glance", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 7608 }, + [], + "05-technical/architecture/component-patterns", + { "id": 7974, "data": 7976, "body": 7981, "filePath": 7982, "digest": 7983, "rendered": 7984 }, + { + "title": 7977, + "editUrl": 16, + "head": 7978, + "template": 18, + "sidebar": 7979, + "pagefind": 16, + "draft": 20 + }, + "Component Patterns", + [], + { "hidden": 20, "attrs": 7980 }, + {}, + "# Component Patterns\n\nHow VariScout's shared hooks work together to enable drill-down, filtering, and analysis.\n\n---\n\n## Hook Architecture Overview\n\n```mermaid\nflowchart TB\n subgraph State[\"State Layer\"]\n DS[useDataState]\n end\n\n subgraph Navigation[\"Navigation Layer\"]\n FN[useFilterNavigation]\n VT[useVariationTracking]\n end\n\n subgraph Presentation[\"Presentation Layer\"]\n CS[useChartScale]\n CT[useChartTheme]\n RM[useResponsiveChartMargins]\n KN[useKeyboardNavigation]\n end\n\n subgraph ChartData[\"Chart Data Layer\"]\n BD[useBoxplotData]\n ID[useIChartData]\n end\n\n subgraph ChartWrapperData[\"Chart Wrapper Data Layer\"]\n BWD[useBoxplotWrapperData]\n IWD[useIChartWrapperData]\n PCD[useParetoChartData]\n DCD[useDashboardComputedData]\n end\n\n DS --> FN\n DS --> VT\n FN --> VT\n DS --> CS\n DS --> BD\n DS --> ID\n BD --> BWD\n ID --> IWD\n```\n\n---\n\n## useDataState\n\n**Central state management for data and specifications.**\n\n### Input\n\n| Parameter | Type | Description |\n| ------------- | -------------------- | --------------------------------- |\n| `persistence` | `PersistenceAdapter` | Platform-specific storage adapter |\n| `initialData` | `DataRow[]` | Optional initial dataset |\n\n### Output (State)\n\n| Property | Type | Description |\n| ------------------------ | ---------------------------- | ----------------------------- |\n| `rawData` | `DataRow[]` | Original unfiltered dataset |\n| `filteredData` | `DataRow[]` | Data after filter application |\n| `specs` | `SpecLimits` | Global USL/LSL/target |\n| `measureSpecs` | `Record\u003Cstring, SpecLimits>` | Per-measure overrides |\n| `getSpecsForMeasure(id)` | `Function` | Get effective specs |\n| `isPerformanceMode` | `boolean` | Multi-measure mode active |\n| `measureColumns` | `string[]` | Selected measure columns |\n| `filters` | `FilterState` | Active filter conditions |\n\n### Output (Actions)\n\n| Action | Parameters | Effect |\n| -------------------- | ---------------- | ------------------------ |\n| `setData` | `DataRow[]` | Replace dataset |\n| `setSpecs` | `SpecLimits` | Update global specs |\n| `setMeasureSpec` | `id, SpecLimits` | Set per-measure override |\n| `setFilters` | `FilterState` | Update active filters |\n| `setPerformanceMode` | `boolean` | Toggle Performance Mode |\n| `reset` | - | Clear all state |\n\n### Usage Example\n\n```tsx\nconst [state, actions] = useDataState({ persistence: indexedDBAdapter });\n\n// Get specs with per-measure override fallback\nconst specs = state.getSpecsForMeasure('FillHead_1');\n\n// Update specs for specific measure\nactions.setMeasureSpec('FillHead_1', { usl: 105, lsl: 95 });\n```\n\n---\n\n## useFilterNavigation\n\n**Manages drill-down navigation with multi-select support.**\n\n### Input\n\n| Parameter | Type | Description |\n| ---------------- | ------------- | --------------------- |\n| `data` | `DataRow[]` | Dataset to filter |\n| `initialFilters` | `FilterState` | Starting filter state |\n\n### Output\n\n| Property | Type | Description |\n| ------------------ | ------------------ | ----------------------- |\n| `filters` | `FilterState` | Current active filters |\n| `breadcrumbs` | `BreadcrumbItem[]` | Navigation path |\n| `drillPath` | `DrillLevel[]` | Complete drill history |\n| `availableFactors` | `string[]` | Factors not yet drilled |\n\n| Method | Parameters | Description |\n| -------------------- | ------------------ | ------------------------ |\n| `addFilter` | `factor, value` | Add single filter |\n| `updateFilterValues` | `factor, values[]` | Set multi-select values |\n| `removeFilter` | `factor` | Remove filter for factor |\n| `clearFilters` | - | Reset to unfiltered |\n| `goToLevel` | `index` | Navigate breadcrumb |\n\n### Filter State Shape\n\n```typescript\ninterface FilterState {\n [factorName: string]: {\n values: string[]; // Selected values (multi-select)\n singleValue?: string; // Legacy single-select\n };\n}\n```\n\n### Usage Example\n\n```tsx\nconst { filters, breadcrumbs, addFilter, updateFilterValues, removeFilter } = useFilterNavigation(\n rawData,\n {}\n);\n\n// Single filter\naddFilter('Shift', 'Night');\n\n// Multi-select filter\nupdateFilterValues('Machine', ['A', 'B', 'C']);\n\n// Navigate breadcrumb\ngoToLevel(1); // Go back to first drill level\n```\n\n---\n\n## useVariationTracking\n\n**Tracks cumulative variation explained through drill-down path.**\n\n### Input\n\n| Parameter | Type | Description |\n| ----------- | -------------- | ------------------- |\n| `data` | `DataRow[]` | Dataset |\n| `outcome` | `string` | Outcome column name |\n| `drillPath` | `DrillLevel[]` | Current drill path |\n\n### Output\n\n| Property | Type | Description |\n| ------------------------ | ------------------ | ----------------------------- |\n| `cumulativeVariationPct` | `number \\| null` | Cumulative Total SS scope (%) |\n| `filterChipData` | `FilterChipData[]` | Per-filter contribution |\n| `impactLevel` | `string \\| null` | high / moderate / low |\n\n### FilterChipData Shape\n\n```typescript\ninterface FilterChipData {\n factor: string; // Factor name\n values: (string | number)[]; // Selected values\n contributionPct: number; // Total SS contribution %\n availableValues: AvailableValue[]; // All values with contribution %\n}\n```\n\n### Usage Example\n\n```tsx\nconst { cumulativeVariationPct, filterChipData, impactLevel } = useVariationTracking(\n rawData,\n filterStack,\n outcome,\n factors\n);\n\n// Display in filter chips\nfilterChipData.map(chip => (\n \u003CFilterChip\n key={chip.factor}\n label={`${chip.factor}: ${chip.values.join(', ')}`}\n contribution={`${(chip.contribution * 100).toFixed(0)}%`}\n />\n));\n```\n\n---\n\n## useChartScale\n\n**Calculates optimal Y-axis scale for charts.**\n\n### Input\n\n| Parameter | Type | Description |\n| --------- | ------------- | ---------------------------- |\n| `data` | `number[]` | Data values |\n| `specs` | `SpecLimits` | Specification limits |\n| `stats` | `StatsResult` | Calculated statistics |\n| `padding` | `number` | Scale padding (default: 0.1) |\n\n### Output\n\n| Property | Type | Description |\n| -------- | ------------------ | -------------------- |\n| `yMin` | `number` | Scale minimum |\n| `yMax` | `number` | Scale maximum |\n| `domain` | `[number, number]` | D3-compatible domain |\n\n### Scale Logic\n\n```mermaid\nflowchart TD\n A[Collect values] --> B[data min/max]\n A --> C[specs: USL/LSL]\n A --> D[stats: UCL/LCL]\n B --> E[Find overall min/max]\n C --> E\n D --> E\n E --> F[Add padding]\n F --> G[yMin, yMax]\n```\n\n---\n\n## useChartTheme\n\n**Provides theme-aware colors for charts.**\n\n### Input\n\nNone (reads from document `data-theme` attribute).\n\n### Output\n\n| Property | Type | Description |\n| ----------- | -------------- | ------------------------------- |\n| `isDark` | `boolean` | Dark theme active |\n| `chrome` | `ChromeColors` | Theme-appropriate chrome colors |\n| `fontScale` | `number` | Font scaling factor |\n\n### Chrome Colors\n\n| Property | Dark | Light | Use |\n| ---------------- | --------- | --------- | ---------------- |\n| `gridLine` | `#1e293b` | `#f1f5f9` | Chart grid |\n| `axisPrimary` | `#94a3b8` | `#64748b` | Axis lines |\n| `axisSecondary` | `#64748b` | `#94a3b8` | Secondary axes |\n| `labelPrimary` | `#cbd5e1` | `#334155` | Primary labels |\n| `labelSecondary` | `#94a3b8` | `#64748b` | Secondary labels |\n\n### Usage Example\n\n```tsx\nconst { isDark, chrome } = useChartTheme();\n\n\u003CAxisLeft\n stroke={chrome.axisPrimary}\n tickStroke={chrome.axisSecondary}\n tickLabelProps={{ fill: chrome.labelPrimary }}\n/>;\n```\n\n---\n\n## useResponsiveChartMargins\n\n**Calculates dynamic margins based on container width.**\n\n### Input\n\n| Parameter | Type | Description |\n| ------------- | -------- | ------------------------ |\n| `width` | `number` | Container width |\n| `chartType` | `string` | Chart type identifier |\n| `extraBottom` | `number` | Additional bottom margin |\n\n### Output\n\n| Property | Type | Description |\n| -------------- | --------- | ------------------------------ |\n| `margins` | `Margins` | `{ top, right, bottom, left }` |\n| `tickFontSize` | `number` | Responsive tick label size |\n| `axisFontSize` | `number` | Responsive axis label size |\n| `statFontSize` | `number` | Responsive stat display size |\n\n### Breakpoints\n\n| Width | Category | Left Margin |\n| --------- | -------- | ----------- |\n| \u003C400px | Mobile | 40px |\n| 400-600px | Tablet | 50px |\n| >600px | Desktop | 60px |\n\n---\n\n## useKeyboardNavigation\n\n**Enables keyboard control for chart interactions.**\n\n### Input\n\n| Parameter | Type | Description |\n| ----------- | ---------------- | ------------------ |\n| `items` | `any[]` | Navigable items |\n| `onSelect` | `(item) => void` | Selection callback |\n| `isEnabled` | `boolean` | Active state |\n\n### Output\n\n| Property | Type | Description |\n| ----------------- | ------------------ | -------------- |\n| `focusedIndex` | `number` | Current focus |\n| `setFocusedIndex` | `Function` | Manual focus |\n| `handlers` | `KeyboardHandlers` | Event handlers |\n\n### Key Bindings\n\n| Key | Action |\n| -------------------------- | -------------- |\n| `ArrowRight` / `ArrowDown` | Next item |\n| `ArrowLeft` / `ArrowUp` | Previous item |\n| `Enter` / `Space` | Select focused |\n| `Escape` | Clear focus |\n| `Home` | First item |\n| `End` | Last item |\n\n---\n\n## Integration Example\n\n**Complete flow from data load to filtered chart:**\n\n```tsx\nfunction Dashboard() {\n // 1. State management\n const [state, actions] = useDataState({ persistence });\n\n // 2. Filter navigation\n const { filters, breadcrumbs, addFilter } = useFilterNavigation(state.rawData, state.filters);\n\n // 3. Variation tracking (Total SS scope)\n const { filterChipData, cumulativeVariationPct } = useVariationTracking(\n state.rawData,\n state.filterStack,\n 'Weight',\n factors\n );\n\n // 4. Chart scale\n const { domain } = useChartScale(\n state.filteredData.map(d => d.Weight),\n state.specs,\n stats\n );\n\n // 5. Theme\n const { chrome, isDark } = useChartTheme();\n\n return (\n \u003C>\n \u003CFilterBreadcrumb\n chips={filterChipData}\n onRemove={removeFilter}\n cumulativeVariationPct={cumulativeVariationPct}\n />\n \u003CIChart\n data={state.filteredData}\n specs={state.specs}\n yDomain={domain}\n theme={chrome}\n onPointClick={point => addFilter(nextFactor, point[nextFactor])}\n />\n \u003C/>\n );\n}\n```\n\n---\n\n## Shared UI Components\n\nComponents extracted to `@variscout/ui` use a **colorScheme prop pattern** for platform-agnostic theming.\n\n### Pattern\n\n```tsx\n// Component defines interface and default preset using semantic tokens\nexport interface MyComponentColorScheme {\n background: string; // Tailwind class (semantic token)\n text: string;\n border: string;\n}\n\nexport const defaultColorScheme: MyComponentColorScheme = {\n background: 'bg-surface-secondary',\n text: 'text-content',\n border: 'border-edge',\n};\n```\n\n### Usage\n\nBoth PWA and Azure use the default color scheme (semantic tokens). No explicit `colorScheme` prop is needed:\n\n```tsx\n// Both apps — default semantic tokens apply automatically\n\u003CFilterBreadcrumb {...props} />\n```\n\n### Available Components\n\n| Component | Base | Color Schemes | Context-Free |\n| ----------------------------- | ---- | --------------------------- | --------------------------------------- |\n| `FilterBreadcrumb` | ✓ | default (semantic tokens) | ✓ |\n| `FilterChipDropdown` | ✓ | default (semantic tokens) | ✓ |\n| `FilterContextBar` | ✓ | default (semantic tokens) | ✓ |\n| `ChartDownloadMenu` | ✓ | default (semantic tokens) | ✓ |\n| `PasteScreenBase` | ✓ | default (semantic tokens) | ✓ |\n| `InvestigationPrompt` | ✓ | default (semantic tokens) | First-drill investigation prompt |\n| `PerformanceSetupPanelBase` | ✓ | default (semantic tokens) | Props + optional tierProps |\n| `StatsPanelBase` | ✓ | default (semantic tokens) | `onEditSpecs` callback opens SpecEditor |\n| `ManualEntryBase` | ✓ | semantic tokens (no scheme) | `enablePerformanceMode` prop |\n| `ManualEntrySetupBase` | ✓ | semantic tokens (no scheme) | ✓ |\n| `SpecsPopover` / `SpecEditor` | ✓ | default (semantic tokens) | ✓ |\n| `CapabilityHistogram` | ✓ | default (semantic tokens) | ✓ |\n| `ProbabilityPlot` | ✓ | default (semantic tokens) | ✓ |\n| `BoxplotDisplayToggle` | ✓ | default (semantic tokens) | Popover with checkboxes + sort controls |\n| `ChartAnnotationLayer` | ✓ | - | HTML overlay for draggable text notes |\n| `AnnotationContextMenu` | ✓ | - | Right-click menu (highlight + add note) |\n| `FocusedViewOverlay` | ✓ | - | Full-screen backdrop for focused charts |\n| `FocusedChartCard` | ✓ | - | Container card for focused chart view |\n| `DashboardChartCard` | ✓ | - | Dashboard chart card with expand button |\n| `DashboardGrid` | ✓ | - | Responsive dashboard chart layout grid |\n\nSee [Colors > Shared Component Color Schemes](../../06-design-system/foundations/colors.md#shared-component-color-schemes) for the complete color mapping.\n\n---\n\n## useAnnotations\n\n**Manages chart annotation state (highlights + text notes) via right-click context menu.**\n\n### Input\n\n| Parameter | Type | Description |\n| ------------------- | -------------------------------- | ------------------------------------------ |\n| `displayOptions` | `DisplayOptions` | Current display options state |\n| `setDisplayOptions` | `(opts: DisplayOptions) => void` | Setter for display options |\n| `dataFingerprint` | `string` | Changes when data changes (resets offsets) |\n\n### Output\n\n| Property | Type | Description |\n| ------------------------ | ---------------------------------------------- | --------------------------------------------------------------- |\n| `contextMenu` | `{ isOpen, position, categoryKey, chartType }` | Context menu state |\n| `handleContextMenu` | `(chartType, key, event) => void` | Opens context menu (Boxplot/Pareto) |\n| `closeContextMenu` | `() => void` | Closes context menu |\n| `setHighlight` | `(chartType, key, color?) => void` | Sets/clears highlight color |\n| `createAnnotation` | `(chartType, key) => void` | Creates text annotation anchored to a category |\n| `createIChartAnnotation` | `(anchorX: number, anchorY: number) => void` | Creates free-floating annotation at % chart position |\n| `setBoxplotAnnotations` | `(annotations: ChartAnnotation[]) => void` | Updates boxplot annotations |\n| `setParetoAnnotations` | `(annotations: ChartAnnotation[]) => void` | Updates pareto annotations |\n| `setIChartAnnotations` | `(annotations: IChartAnnotation[]) => void` | Updates I-Chart annotation list |\n| `ichartAnnotations` | `IChartAnnotation[]` | Current I-Chart annotation array |\n| `clearAnnotations` | `(chartType) => void` | Clears all for chart type (`'boxplot'`, `'pareto'`, `'ichart'`) |\n| `hasAnnotations` | `boolean` | Any annotations or highlights exist |\n\n**Mobile note:** `handleContextMenu` is desktop-only (right-click). On mobile (\u003C640px), `MobileCategorySheet` (from `@variscout/ui`) handles highlight and finding creation for Boxplot and Pareto categories. Text annotations (`ChartAnnotation` boxes) are not created on mobile.\n\n### Usage Example\n\n```tsx\nconst {\n contextMenu,\n handleContextMenu,\n closeContextMenu,\n setHighlight,\n createAnnotation,\n clearAnnotations,\n hasAnnotations,\n} = useAnnotations({ displayOptions, setDisplayOptions, dataFingerprint });\n\n// Wire to chart wrapper\n\u003CBoxplotBase onBoxContextMenu={(key, e) => handleContextMenu('boxplot', key, e)} />;\n\n// Render context menu\n{\n contextMenu.isOpen && (\n \u003CAnnotationContextMenu\n categoryKey={contextMenu.categoryKey}\n position={contextMenu.position}\n onSetHighlight={color => {\n setHighlight(contextMenu.chartType, contextMenu.categoryKey, color);\n closeContextMenu();\n }}\n onAddNote={() => {\n createAnnotation(contextMenu.chartType, contextMenu.categoryKey);\n closeContextMenu();\n }}\n onClose={closeContextMenu}\n />\n );\n}\n```\n\n---\n\n## Settings Architecture\n\nDisplay settings are split into two categories based on scope:\n\n### Global Preferences (SettingsPanel)\n\nAccessible via the Settings gear icon. These apply to all charts and persist across sessions.\n\n| Setting | Type | Default | Effect |\n| ------------------- | ------- | ------- | ----------------------------------- |\n| Lock Y-axis to data | boolean | false | Use full data range for chart scale |\n| Show spec limits | boolean | true | Display USL/LSL lines on charts |\n| Show Cpk | boolean | true | Display Cpk in stats panel |\n| Show filter context | boolean | true | Display active filters on charts |\n| Chart text size | preset | Normal | Compact / Normal / Large |\n\n**PWA** has a slim panel (4 display toggles + chart text size). **Azure** adds theme toggle, company accent color, and font scale.\n\n### Contextual Toggles (Chart Card Headers)\n\nAttached directly to individual chart cards. These are chart-specific display options.\n\n| Toggle | Component | Location |\n| ------------------- | ---------------------- | ------------------- |\n| Violin mode | `BoxplotDisplayToggle` | Boxplot card header |\n| Contribution labels | `BoxplotDisplayToggle` | Boxplot card header |\n| Sort order | `BoxplotDisplayToggle` | Boxplot card header |\n\n`BoxplotDisplayToggle` is a shared popover component from `@variscout/ui` (SlidersHorizontal icon triggering a popover with 2 checkboxes and sort controls). It manages local state that feeds into the Boxplot's `showViolin`, `showContributionLabels`, sort criterion (`boxplotSortBy`), and sort direction (`boxplotSortDirection`) props.\n\n---\n\n## See Also\n\n- [Data Flow](data-flow.md) - How data moves through the system\n- [Shared Packages](shared-packages.md) - Package exports\n- [Colors > Color Schemes](../../06-design-system/foundations/colors.md#shared-component-color-schemes) - ColorScheme prop pattern\n- [Charts Overview](../../06-design-system/charts/overview.md) - Chart components\n- [ADR-005: Props-Based Charts](../../07-decisions/adr-005-props-based-charts.md)", + "src/content/docs/05-technical/architecture/component-patterns.md", + "8ea443cb82730cb9", + { "html": 7985, "metadata": 7986 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"component-patterns\">Component Patterns\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#component-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Component Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How VariScout’s shared hooks work together to enable drill-down, filtering, and analysis.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"hook-architecture-overview\">Hook Architecture Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#hook-architecture-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hook Architecture Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph State[\"State Layer\"]\n DS[useDataState]\n end\n\n subgraph Navigation[\"Navigation Layer\"]\n FN[useFilterNavigation]\n VT[useVariationTracking]\n end\n\n subgraph Presentation[\"Presentation Layer\"]\n CS[useChartScale]\n CT[useChartTheme]\n RM[useResponsiveChartMargins]\n KN[useKeyboardNavigation]\n end\n\n subgraph ChartData[\"Chart Data Layer\"]\n BD[useBoxplotData]\n ID[useIChartData]\n end\n\n subgraph ChartWrapperData[\"Chart Wrapper Data Layer\"]\n BWD[useBoxplotWrapperData]\n IWD[useIChartWrapperData]\n PCD[useParetoChartData]\n DCD[useDashboardComputedData]\n end\n\n DS --> FN\n DS --> VT\n FN --> VT\n DS --> CS\n DS --> BD\n DS --> ID\n BD --> BWD\n ID --> IWD\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usedatastate\">useDataState\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usedatastate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useDataState”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Central state management for data and specifications.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input\">Input\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">persistence\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">PersistenceAdapter\u003C/code>\u003C/td>\u003Ctd>Platform-specific storage adapter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">initialData\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code>\u003C/td>\u003Ctd>Optional initial dataset\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"output-state\">Output (State)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#output-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Output (State)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">rawData\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code>\u003C/td>\u003Ctd>Original unfiltered dataset\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">filteredData\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code>\u003C/td>\u003Ctd>Data after filter application\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">specs\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">SpecLimits\u003C/code>\u003C/td>\u003Ctd>Global USL/LSL/target\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">measureSpecs\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Record<string, SpecLimits>\u003C/code>\u003C/td>\u003Ctd>Per-measure overrides\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">getSpecsForMeasure(id)\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Function\u003C/code>\u003C/td>\u003Ctd>Get effective specs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">isPerformanceMode\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">boolean\u003C/code>\u003C/td>\u003Ctd>Multi-measure mode active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">measureColumns\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string[]\u003C/code>\u003C/td>\u003Ctd>Selected measure columns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">filters\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FilterState\u003C/code>\u003C/td>\u003Ctd>Active filter conditions\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"output-actions\">Output (Actions)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#output-actions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Output (Actions)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>Parameters\u003C/th>\u003Cth>Effect\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setData\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code>\u003C/td>\u003Ctd>Replace dataset\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setSpecs\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">SpecLimits\u003C/code>\u003C/td>\u003Ctd>Update global specs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setMeasureSpec\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">id, SpecLimits\u003C/code>\u003C/td>\u003Ctd>Set per-measure override\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setFilters\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FilterState\u003C/code>\u003C/td>\u003Ctd>Update active filters\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setPerformanceMode\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">boolean\u003C/code>\u003C/td>\u003Ctd>Toggle Performance Mode\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">reset\u003C/code>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Clear all state\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-example\">Usage Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const [\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">actions\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">] = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useDataState\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ persistence: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">indexedDBAdapter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Get specs with per-measure override fallback\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getSpecsForMeasure\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">FillHead_1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Update specs for specific measure\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">actions\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setMeasureSpec\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">FillHead_1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, { usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">105\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">95\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const [state, actions] = useDataState({ persistence: indexedDBAdapter });// Get specs with per-measure override fallbackconst specs = state.getSpecsForMeasure('FillHead_1');// Update specs for specific measureactions.setMeasureSpec('FillHead_1', { usl: 105, lsl: 95 });\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usefilternavigation\">useFilterNavigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usefilternavigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useFilterNavigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Manages drill-down navigation with multi-select support.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input-1\">Input\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">data\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code>\u003C/td>\u003Ctd>Dataset to filter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">initialFilters\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FilterState\u003C/code>\u003C/td>\u003Ctd>Starting filter state\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"output\">Output\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#output\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Output”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">filters\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FilterState\u003C/code>\u003C/td>\u003Ctd>Current active filters\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">breadcrumbs\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">BreadcrumbItem[]\u003C/code>\u003C/td>\u003Ctd>Navigation path\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">drillPath\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DrillLevel[]\u003C/code>\u003C/td>\u003Ctd>Complete drill history\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">availableFactors\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string[]\u003C/code>\u003C/td>\u003Ctd>Factors not yet drilled\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Method\u003C/th>\u003Cth>Parameters\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">addFilter\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">factor, value\u003C/code>\u003C/td>\u003Ctd>Add single filter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">updateFilterValues\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">factor, values[]\u003C/code>\u003C/td>\u003Ctd>Set multi-select values\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">removeFilter\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">factor\u003C/code>\u003C/td>\u003Ctd>Remove filter for factor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">clearFilters\u003C/code>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Reset to unfiltered\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">goToLevel\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">index\u003C/code>\u003C/td>\u003Ctd>Navigate breadcrumb\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filter-state-shape\">Filter State Shape\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filter-state-shape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter State Shape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FilterState {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">factorName\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Selected values (multi-select)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">singleValue\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Legacy single-select\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface FilterState { [factorName: string]: { values: string[]; // Selected values (multi-select) singleValue?: string; // Legacy single-select };}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-example-1\">Usage Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-example-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filters\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">breadcrumbs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addFilter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeFilter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useFilterNavigation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">rawData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Single filter\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addFilter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Night\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Multi-select filter\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Machine\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">A\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">B\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">C\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Navigate breadcrumb\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">goToLevel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Go back to first drill level\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { filters, breadcrumbs, addFilter, updateFilterValues, removeFilter } = useFilterNavigation( rawData, {});// Single filteraddFilter('Shift', 'Night');// Multi-select filterupdateFilterValues('Machine', ['A', 'B', 'C']);// Navigate breadcrumbgoToLevel(1); // Go back to first drill level\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usevariationtracking\">useVariationTracking\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usevariationtracking\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useVariationTracking”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Tracks cumulative variation explained through drill-down path.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input-2\">Input\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">data\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code>\u003C/td>\u003Ctd>Dataset\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">outcome\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string\u003C/code>\u003C/td>\u003Ctd>Outcome column name\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">drillPath\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DrillLevel[]\u003C/code>\u003C/td>\u003Ctd>Current drill path\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"output-1\">Output\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#output-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Output”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">cumulativeVariationPct\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number | null\u003C/code>\u003C/td>\u003Ctd>Cumulative Total SS scope (%)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">filterChipData\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">FilterChipData[]\u003C/code>\u003C/td>\u003Ctd>Per-filter contribution\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">impactLevel\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string | null\u003C/code>\u003C/td>\u003Ctd>high / moderate / low\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filterchipdata-shape\">FilterChipData Shape\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filterchipdata-shape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “FilterChipData Shape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FilterChipData {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Factor name\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Selected values\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contributionPct\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Total SS contribution %\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">availableValues\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">AvailableValue\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// All values with contribution %\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface FilterChipData { factor: string; // Factor name values: (string | number)[]; // Selected values contributionPct: number; // Total SS contribution % availableValues: AvailableValue[]; // All values with contribution %}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-example-2\">Usage Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-example-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cumulativeVariationPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterChipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">impactLevel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useVariationTracking\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">rawData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterStack\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Display in filter chips\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterChipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">chip\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">FilterChip\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">factor\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">label\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">factor\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">values\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">join\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">contribution\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">contribution\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">*\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toFixed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">%\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { cumulativeVariationPct, filterChipData, impactLevel } = useVariationTracking( rawData, filterStack, outcome, factors);// Display in filter chipsfilterChipData.map(chip => ( \u003CFilterChip key={chip.factor} label={`${chip.factor}: ${chip.values.join(', ')}`} contribution={`${(chip.contribution * 100).toFixed(0)}%`} />));\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usechartscale\">useChartScale\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usechartscale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useChartScale”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Calculates optimal Y-axis scale for charts.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input-3\">Input\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">data\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number[]\u003C/code>\u003C/td>\u003Ctd>Data values\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">specs\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">SpecLimits\u003C/code>\u003C/td>\u003Ctd>Specification limits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stats\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">StatsResult\u003C/code>\u003C/td>\u003Ctd>Calculated statistics\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">padding\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>Scale padding (default: 0.1)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"output-2\">Output\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#output-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Output”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">yMin\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>Scale minimum\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">yMax\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>Scale maximum\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">domain\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">[number, number]\u003C/code>\u003C/td>\u003Ctd>D3-compatible domain\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"scale-logic\">Scale Logic\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#scale-logic\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scale Logic”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[Collect values] --> B[data min/max]\n A --> C[specs: USL/LSL]\n A --> D[stats: UCL/LCL]\n B --> E[Find overall min/max]\n C --> E\n D --> E\n E --> F[Add padding]\n F --> G[yMin, yMax]\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usecharttheme\">useChartTheme\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usecharttheme\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useChartTheme”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Provides theme-aware colors for charts.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input-4\">Input\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>None (reads from document \u003Ccode dir=\"auto\">data-theme\u003C/code> attribute).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"output-3\">Output\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#output-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Output”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">isDark\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">boolean\u003C/code>\u003C/td>\u003Ctd>Dark theme active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">chrome\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ChromeColors\u003C/code>\u003C/td>\u003Ctd>Theme-appropriate chrome colors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">fontScale\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>Font scaling factor\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"chrome-colors\">Chrome Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#chrome-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chrome Colors”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Dark\u003C/th>\u003Cth>Light\u003C/th>\u003Cth>Use\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">gridLine\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#1e293b\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f1f5f9\u003C/code>\u003C/td>\u003Ctd>Chart grid\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">axisPrimary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>Axis lines\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">axisSecondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003Ctd>Secondary axes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">labelPrimary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#cbd5e1\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#334155\u003C/code>\u003C/td>\u003Ctd>Primary labels\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">labelSecondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>Secondary labels\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-example-3\">Usage Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-example-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isDark\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">AxisLeft\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">axisPrimary\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">tickStroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">axisSecondary\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">tickLabelProps\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ fill: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">labelPrimary\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { isDark, chrome } = useChartTheme();\u003CAxisLeft stroke={chrome.axisPrimary} tickStroke={chrome.axisSecondary} tickLabelProps={{ fill: chrome.labelPrimary }}/>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"useresponsivechartmargins\">useResponsiveChartMargins\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#useresponsivechartmargins\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useResponsiveChartMargins”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Calculates dynamic margins based on container width.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input-5\">Input\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input-5\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">width\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>Container width\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">chartType\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string\u003C/code>\u003C/td>\u003Ctd>Chart type identifier\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">extraBottom\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>Additional bottom margin\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"output-4\">Output\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#output-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Output”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">margins\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Margins\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{ top, right, bottom, left }\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">tickFontSize\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>Responsive tick label size\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">axisFontSize\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>Responsive axis label size\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">statFontSize\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>Responsive stat display size\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"breakpoints\">Breakpoints\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#breakpoints\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Breakpoints”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Width\u003C/th>\u003Cth>Category\u003C/th>\u003Cth>Left Margin\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd><400px\u003C/td>\u003Ctd>Mobile\u003C/td>\u003Ctd>40px\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>400-600px\u003C/td>\u003Ctd>Tablet\u003C/td>\u003Ctd>50px\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>>600px\u003C/td>\u003Ctd>Desktop\u003C/td>\u003Ctd>60px\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usekeyboardnavigation\">useKeyboardNavigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usekeyboardnavigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useKeyboardNavigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Enables keyboard control for chart interactions.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input-6\">Input\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input-6\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">items\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">any[]\u003C/code>\u003C/td>\u003Ctd>Navigable items\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">onSelect\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(item) => void\u003C/code>\u003C/td>\u003Ctd>Selection callback\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">isEnabled\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">boolean\u003C/code>\u003C/td>\u003Ctd>Active state\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"output-5\">Output\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#output-5\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Output”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">focusedIndex\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number\u003C/code>\u003C/td>\u003Ctd>Current focus\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setFocusedIndex\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Function\u003C/code>\u003C/td>\u003Ctd>Manual focus\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">handlers\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">KeyboardHandlers\u003C/code>\u003C/td>\u003Ctd>Event handlers\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-bindings\">Key Bindings\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-bindings\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Bindings”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Key\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ArrowRight\u003C/code> / \u003Ccode dir=\"auto\">ArrowDown\u003C/code>\u003C/td>\u003Ctd>Next item\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ArrowLeft\u003C/code> / \u003Ccode dir=\"auto\">ArrowUp\u003C/code>\u003C/td>\u003Ctd>Previous item\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Enter\u003C/code> / \u003Ccode dir=\"auto\">Space\u003C/code>\u003C/td>\u003Ctd>Select focused\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Escape\u003C/code>\u003C/td>\u003Ctd>Clear focus\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Home\u003C/code>\u003C/td>\u003Ctd>First item\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">End\u003C/code>\u003C/td>\u003Ctd>Last item\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"integration-example\">Integration Example\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#integration-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integration Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Complete flow from data load to filtered chart:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Dashboard\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. State management\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const [\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">state\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">actions\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">] = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useDataState\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">persistence\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Filter navigation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filters\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">breadcrumbs\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addFilter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useFilterNavigation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">rawData\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">filters\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Variation tracking (Total SS scope)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterChipData\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cumulativeVariationPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useVariationTracking\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">rawData\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">filterStack\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Weight\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 4. Chart scale\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">domain\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartScale\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">filteredData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">d\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">Weight\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">specs\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 5. Theme\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isDark\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">FilterBreadcrumb\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">chips\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterChipData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onRemove\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">removeFilter\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">cumulativeVariationPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cumulativeVariationPct\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">filteredData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">yDomain\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">domain\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">theme\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chrome\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onPointClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">point\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addFilter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(nextFactor\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">point[nextFactor])\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"function Dashboard() { // 1. State management const [state, actions] = useDataState({ persistence }); // 2. Filter navigation const { filters, breadcrumbs, addFilter } = useFilterNavigation(state.rawData, state.filters); // 3. Variation tracking (Total SS scope) const { filterChipData, cumulativeVariationPct } = useVariationTracking( state.rawData, state.filterStack, 'Weight', factors ); // 4. Chart scale const { domain } = useChartScale( state.filteredData.map(d => d.Weight), state.specs, stats ); // 5. Theme const { chrome, isDark } = useChartTheme(); return ( \u003C> \u003CFilterBreadcrumb chips={filterChipData} onRemove={removeFilter} cumulativeVariationPct={cumulativeVariationPct} /> \u003CIChart data={state.filteredData} specs={state.specs} yDomain={domain} theme={chrome} onPointClick={point => addFilter(nextFactor, point[nextFactor])} /> \u003C/> );}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"shared-ui-components\">Shared UI Components\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#shared-ui-components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Shared UI Components”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Components extracted to \u003Ccode dir=\"auto\">@variscout/ui\u003C/code> use a \u003Cstrong>colorScheme prop pattern\u003C/strong> for platform-agnostic theming.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pattern\">Pattern\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pattern”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Component defines interface and default preset using semantic tokens\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> MyComponentColorScheme {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">background\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Tailwind class (semantic token)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">border\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">defaultColorScheme\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">MyComponentColorScheme\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">background: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-surface-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">border: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">border-edge\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Component defines interface and default preset using semantic tokensexport interface MyComponentColorScheme { background: string; // Tailwind class (semantic token) text: string; border: string;}export const defaultColorScheme: MyComponentColorScheme = { background: 'bg-surface-secondary', text: 'text-content', border: 'border-edge',};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage\">Usage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both PWA and Azure use the default color scheme (semantic tokens). No explicit \u003Ccode dir=\"auto\">colorScheme\u003C/code> prop is needed:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Both apps — default semantic tokens apply automatically\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">FilterBreadcrumb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">props\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Both apps — default semantic tokens apply automatically\u003CFilterBreadcrumb {...props} />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"available-components\">Available Components\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#available-components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Available Components”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Base\u003C/th>\u003Cth>Color Schemes\u003C/th>\u003Cth>Context-Free\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FilterBreadcrumb\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FilterChipDropdown\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FilterContextBar\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChartDownloadMenu\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PasteScreenBase\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">InvestigationPrompt\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>First-drill investigation prompt\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceSetupPanelBase\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>Props + optional tierProps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">StatsPanelBase\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">onEditSpecs\u003C/code> callback opens SpecEditor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ManualEntryBase\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>semantic tokens (no scheme)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">enablePerformanceMode\u003C/code> prop\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ManualEntrySetupBase\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>semantic tokens (no scheme)\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">SpecsPopover\u003C/code> / \u003Ccode dir=\"auto\">SpecEditor\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">CapabilityHistogram\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ProbabilityPlot\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">BoxplotDisplayToggle\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>default (semantic tokens)\u003C/td>\u003Ctd>Popover with checkboxes + sort controls\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChartAnnotationLayer\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>HTML overlay for draggable text notes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">AnnotationContextMenu\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Right-click menu (highlight + add note)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FocusedViewOverlay\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Full-screen backdrop for focused charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FocusedChartCard\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Container card for focused chart view\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">DashboardChartCard\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Dashboard chart card with expand button\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">DashboardGrid\u003C/code>\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Responsive dashboard chart layout grid\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"../../06-design-system/foundations/colors.md#shared-component-color-schemes\">Colors > Shared Component Color Schemes\u003C/a> for the complete color mapping.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"useannotations\">useAnnotations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#useannotations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useAnnotations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Manages chart annotation state (highlights + text notes) via right-click context menu.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input-7\">Input\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input-7\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">displayOptions\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DisplayOptions\u003C/code>\u003C/td>\u003Ctd>Current display options state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setDisplayOptions\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(opts: DisplayOptions) => void\u003C/code>\u003C/td>\u003Ctd>Setter for display options\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">dataFingerprint\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string\u003C/code>\u003C/td>\u003Ctd>Changes when data changes (resets offsets)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"output-6\">Output\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#output-6\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Output”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">contextMenu\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{ isOpen, position, categoryKey, chartType }\u003C/code>\u003C/td>\u003Ctd>Context menu state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">handleContextMenu\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(chartType, key, event) => void\u003C/code>\u003C/td>\u003Ctd>Opens context menu (Boxplot/Pareto)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">closeContextMenu\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">() => void\u003C/code>\u003C/td>\u003Ctd>Closes context menu\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setHighlight\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(chartType, key, color?) => void\u003C/code>\u003C/td>\u003Ctd>Sets/clears highlight color\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">createAnnotation\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(chartType, key) => void\u003C/code>\u003C/td>\u003Ctd>Creates text annotation anchored to a category\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">createIChartAnnotation\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(anchorX: number, anchorY: number) => void\u003C/code>\u003C/td>\u003Ctd>Creates free-floating annotation at % chart position\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setBoxplotAnnotations\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(annotations: ChartAnnotation[]) => void\u003C/code>\u003C/td>\u003Ctd>Updates boxplot annotations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setParetoAnnotations\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(annotations: ChartAnnotation[]) => void\u003C/code>\u003C/td>\u003Ctd>Updates pareto annotations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setIChartAnnotations\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(annotations: IChartAnnotation[]) => void\u003C/code>\u003C/td>\u003Ctd>Updates I-Chart annotation list\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ichartAnnotations\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">IChartAnnotation[]\u003C/code>\u003C/td>\u003Ctd>Current I-Chart annotation array\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">clearAnnotations\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(chartType) => void\u003C/code>\u003C/td>\u003Ctd>Clears all for chart type (\u003Ccode dir=\"auto\">'boxplot'\u003C/code>, \u003Ccode dir=\"auto\">'pareto'\u003C/code>, \u003Ccode dir=\"auto\">'ichart'\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">hasAnnotations\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">boolean\u003C/code>\u003C/td>\u003Ctd>Any annotations or highlights exist\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Mobile note:\u003C/strong> \u003Ccode dir=\"auto\">handleContextMenu\u003C/code> is desktop-only (right-click). On mobile (<640px), \u003Ccode dir=\"auto\">MobileCategorySheet\u003C/code> (from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>) handles highlight and finding creation for Boxplot and Pareto categories. Text annotations (\u003Ccode dir=\"auto\">ChartAnnotation\u003C/code> boxes) are not created on mobile.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-example-4\">Usage Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-example-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">contextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleContextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">closeContextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setHighlight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createAnnotation\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">clearAnnotations\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hasAnnotations\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">} = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useAnnotations\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">displayOptions\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setDisplayOptions\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">dataFingerprint\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Wire to chart wrapper\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">BoxplotBase\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onBoxContextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleContextMenu\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">e)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Render context menu\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">isOpen\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">AnnotationContextMenu\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">categoryKey\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">categoryKey\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">position\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">position\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onSetHighlight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">color\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setHighlight\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(contextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">chartType\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">categoryKey\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">color)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">closeContextMenu\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onAddNote\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">createAnnotation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(contextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">chartType\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">categoryKey\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">closeContextMenu\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClose\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">closeContextMenu\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { contextMenu, handleContextMenu, closeContextMenu, setHighlight, createAnnotation, clearAnnotations, hasAnnotations,} = useAnnotations({ displayOptions, setDisplayOptions, dataFingerprint });// Wire to chart wrapper\u003CBoxplotBase onBoxContextMenu={(key, e) => handleContextMenu('boxplot', key, e)} />;// Render context menu{ contextMenu.isOpen && ( \u003CAnnotationContextMenu categoryKey={contextMenu.categoryKey} position={contextMenu.position} onSetHighlight={color => { setHighlight(contextMenu.chartType, contextMenu.categoryKey, color); closeContextMenu(); }} onAddNote={() => { createAnnotation(contextMenu.chartType, contextMenu.categoryKey); closeContextMenu(); }} onClose={closeContextMenu} /> );}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"settings-architecture\">Settings Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#settings-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Settings Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Display settings are split into two categories based on scope:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"global-preferences-settingspanel\">Global Preferences (SettingsPanel)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#global-preferences-settingspanel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Global Preferences (SettingsPanel)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Accessible via the Settings gear icon. These apply to all charts and persist across sessions.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Setting\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Effect\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Lock Y-axis to data\u003C/td>\u003Ctd>boolean\u003C/td>\u003Ctd>false\u003C/td>\u003Ctd>Use full data range for chart scale\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Show spec limits\u003C/td>\u003Ctd>boolean\u003C/td>\u003Ctd>true\u003C/td>\u003Ctd>Display USL/LSL lines on charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Show Cpk\u003C/td>\u003Ctd>boolean\u003C/td>\u003Ctd>true\u003C/td>\u003Ctd>Display Cpk in stats panel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Show filter context\u003C/td>\u003Ctd>boolean\u003C/td>\u003Ctd>true\u003C/td>\u003Ctd>Display active filters on charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Chart text size\u003C/td>\u003Ctd>preset\u003C/td>\u003Ctd>Normal\u003C/td>\u003Ctd>Compact / Normal / Large\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>PWA\u003C/strong> has a slim panel (4 display toggles + chart text size). \u003Cstrong>Azure\u003C/strong> adds theme toggle, company accent color, and font scale.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"contextual-toggles-chart-card-headers\">Contextual Toggles (Chart Card Headers)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#contextual-toggles-chart-card-headers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Contextual Toggles (Chart Card Headers)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Attached directly to individual chart cards. These are chart-specific display options.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Toggle\u003C/th>\u003Cth>Component\u003C/th>\u003Cth>Location\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Violin mode\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">BoxplotDisplayToggle\u003C/code>\u003C/td>\u003Ctd>Boxplot card header\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Contribution labels\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">BoxplotDisplayToggle\u003C/code>\u003C/td>\u003Ctd>Boxplot card header\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sort order\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">BoxplotDisplayToggle\u003C/code>\u003C/td>\u003Ctd>Boxplot card header\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Ccode dir=\"auto\">BoxplotDisplayToggle\u003C/code> is a shared popover component from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code> (SlidersHorizontal icon triggering a popover with 2 checkboxes and sort controls). It manages local state that feeds into the Boxplot’s \u003Ccode dir=\"auto\">showViolin\u003C/code>, \u003Ccode dir=\"auto\">showContributionLabels\u003C/code>, sort criterion (\u003Ccode dir=\"auto\">boxplotSortBy\u003C/code>), and sort direction (\u003Ccode dir=\"auto\">boxplotSortDirection\u003C/code>) props.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"data-flow.md\">Data Flow\u003C/a> - How data moves through the system\u003C/li>\n\u003Cli>\u003Ca href=\"shared-packages.md\">Shared Packages\u003C/a> - Package exports\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/foundations/colors.md#shared-component-color-schemes\">Colors > Color Schemes\u003C/a> - ColorScheme prop pattern\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/charts/overview.md\">Charts Overview\u003C/a> - Chart components\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-005-props-based-charts.md\">ADR-005: Props-Based Charts\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 7987, + "localImagePaths": 8099, + "remoteImagePaths": 8100, + "frontmatter": 8101, + "imagePaths": 8102 + }, + [ + 7988, 7990, 7993, 7996, 7999, 8002, 8005, 8006, 8009, 8011, 8012, 8015, 8017, 8020, 8022, 8024, + 8027, 8029, 8032, 8034, 8036, 8039, 8042, 8044, 8046, 8047, 8049, 8052, 8054, 8056, 8057, 8060, + 8062, 8064, 8067, 8070, 8073, 8076, 8077, 8080, 8083, 8085, 8087, 8089, 8092, 8095, 8098 + ], + { "depth": 30, "slug": 7989, "text": 7977 }, + "component-patterns", + { "depth": 33, "slug": 7991, "text": 7992 }, + "hook-architecture-overview", + "Hook Architecture Overview", + { "depth": 33, "slug": 7994, "text": 7995 }, + "usedatastate", + "useDataState", + { "depth": 79, "slug": 7997, "text": 7998 }, + "input", + "Input", + { "depth": 79, "slug": 8000, "text": 8001 }, + "output-state", + "Output (State)", + { "depth": 79, "slug": 8003, "text": 8004 }, + "output-actions", + "Output (Actions)", + { "depth": 79, "slug": 3522, "text": 3523 }, + { "depth": 33, "slug": 8007, "text": 8008 }, + "usefilternavigation", + "useFilterNavigation", + { "depth": 79, "slug": 8010, "text": 7998 }, + "input-1", + { "depth": 79, "slug": 7686, "text": 7687 }, + { "depth": 79, "slug": 8013, "text": 8014 }, + "filter-state-shape", + "Filter State Shape", + { "depth": 79, "slug": 8016, "text": 3523 }, + "usage-example-1", + { "depth": 33, "slug": 8018, "text": 8019 }, + "usevariationtracking", + "useVariationTracking", + { "depth": 79, "slug": 8021, "text": 7998 }, + "input-2", + { "depth": 79, "slug": 8023, "text": 7687 }, + "output-1", + { "depth": 79, "slug": 8025, "text": 8026 }, + "filterchipdata-shape", + "FilterChipData Shape", + { "depth": 79, "slug": 8028, "text": 3523 }, + "usage-example-2", + { "depth": 33, "slug": 8030, "text": 8031 }, + "usechartscale", + "useChartScale", + { "depth": 79, "slug": 8033, "text": 7998 }, + "input-3", + { "depth": 79, "slug": 8035, "text": 7687 }, + "output-2", + { "depth": 79, "slug": 8037, "text": 8038 }, + "scale-logic", + "Scale Logic", + { "depth": 33, "slug": 8040, "text": 8041 }, + "usecharttheme", + "useChartTheme", + { "depth": 79, "slug": 8043, "text": 7998 }, + "input-4", + { "depth": 79, "slug": 8045, "text": 7687 }, + "output-3", + { "depth": 79, "slug": 1553, "text": 1554 }, + { "depth": 79, "slug": 8048, "text": 3523 }, + "usage-example-3", + { "depth": 33, "slug": 8050, "text": 8051 }, + "useresponsivechartmargins", + "useResponsiveChartMargins", + { "depth": 79, "slug": 8053, "text": 7998 }, + "input-5", + { "depth": 79, "slug": 8055, "text": 7687 }, + "output-4", + { "depth": 79, "slug": 4253, "text": 4254 }, + { "depth": 33, "slug": 8058, "text": 8059 }, + "usekeyboardnavigation", + "useKeyboardNavigation", + { "depth": 79, "slug": 8061, "text": 7998 }, + "input-6", + { "depth": 79, "slug": 8063, "text": 7687 }, + "output-5", + { "depth": 79, "slug": 8065, "text": 8066 }, + "key-bindings", + "Key Bindings", + { "depth": 33, "slug": 8068, "text": 8069 }, + "integration-example", + "Integration Example", + { "depth": 33, "slug": 8071, "text": 8072 }, + "shared-ui-components", + "Shared UI Components", + { "depth": 79, "slug": 8074, "text": 8075 }, + "pattern", + "Pattern", + { "depth": 79, "slug": 2008, "text": 2009 }, + { "depth": 79, "slug": 8078, "text": 8079 }, + "available-components", + "Available Components", + { "depth": 33, "slug": 8081, "text": 8082 }, + "useannotations", + "useAnnotations", + { "depth": 79, "slug": 8084, "text": 7998 }, + "input-7", + { "depth": 79, "slug": 8086, "text": 7687 }, + "output-6", + { "depth": 79, "slug": 8088, "text": 3523 }, + "usage-example-4", + { "depth": 33, "slug": 8090, "text": 8091 }, + "settings-architecture", + "Settings Architecture", + { "depth": 79, "slug": 8093, "text": 8094 }, + "global-preferences-settingspanel", + "Global Preferences (SettingsPanel)", + { "depth": 79, "slug": 8096, "text": 8097 }, + "contextual-toggles-chart-card-headers", + "Contextual Toggles (Chart Card Headers)", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 7977 }, + [], + "05-technical/architecture/data-flow", + { "id": 8103, "data": 8105, "body": 8110, "filePath": 8111, "digest": 8112, "rendered": 8113 }, + { + "title": 8106, + "editUrl": 16, + "head": 8107, + "template": 18, + "sidebar": 8108, + "pagefind": 16, + "draft": 20 + }, + "Data Flow Architecture", + [], + { "hidden": 20, "attrs": 8109 }, + {}, + "# Data Flow Architecture\n\nHow data moves through VariScout from upload to persistence.\n\n---\n\n## Overview\n\nVariScout processes data entirely client-side. This diagram shows the complete flow:\n\n```mermaid\nflowchart TB\n subgraph Input[\"Data Input\"]\n A1[File Upload] --> B[Parser]\n A2[Paste Data] --> B\n A3[Sample Dataset] --> B\n end\n\n subgraph Processing[\"Processing Layer\"]\n B --> C[Validation]\n C --> D[Column Detection]\n D --> E[Data State]\n end\n\n subgraph Analysis[\"Analysis Engine\"]\n E --> F1[Statistics]\n E --> F2[ANOVA]\n E --> F3[Regression]\n E --> F5[Performance]\n end\n\n subgraph Presentation[\"Presentation Layer\"]\n F1 --> G1[I-Chart]\n F2 --> G2[Boxplot]\n F2 --> G3[Pareto]\n F1 --> G4[Capability]\n F3 --> G5[Scatter]\n F5 --> G7[Performance Dashboard]\n end\n\n subgraph Persistence[\"Storage Layer\"]\n E --> H1[(IndexedDB)]\n E --> H2[(\"OneDrive (Team plan)\")]\n E --> H3[(Excel Doc Props)]\n end\n```\n\n---\n\n## Data Input Stage\n\n### File Upload Flow\n\n```mermaid\nsequenceDiagram\n participant U as User\n participant UI as Upload UI\n participant H as useDataIngestion\n participant P as Parser\n participant V as Validator\n\n U->>UI: Select file (.csv, .xlsx)\n UI->>H: onFileSelect(file)\n H->>P: parseFile(file)\n P->>P: Detect format\n P->>P: Extract rows\n P-->>H: RawData[]\n H->>V: validateData(data)\n V->>V: Check types\n V->>V: Detect columns\n V-->>H: ValidationResult\n H-->>UI: DataReady + Quality Report\n```\n\n### Supported Formats\n\n| Format | Parser | Notes |\n| ------------- | -------- | ---------------------- |\n| CSV | Built-in | Auto-detects delimiter |\n| TSV | Built-in | Tab-separated |\n| Excel (.xlsx) | SheetJS | First sheet by default |\n| Paste | Built-in | Tab/comma detection |\n\n---\n\n## Validation Stage\n\n### Column Detection\n\n```mermaid\nflowchart LR\n A[Raw Data] --> B{Has numeric columns?}\n B -->|Yes| C[Identify measure columns]\n B -->|No| D[Error: No numeric data]\n C --> E{Has factor columns?}\n E -->|Yes| F[Identify factor columns]\n E -->|No| G[Measure-only mode]\n F --> H[Column Mapping UI]\n G --> H\n```\n\n### Keyword Detection\n\nThe parser detects special columns by keywords:\n\n| Keyword Pattern | Column Type | Example |\n| ------------------------ | -------------- | --------------- |\n| `operator`, `inspector` | Operator (MSA) | \"Operator Name\" |\n| `part`, `sample`, `item` | Part ID (MSA) | \"Sample ID\" |\n| `usl`, `upper spec` | Specification | \"USL_Weight\" |\n| `lsl`, `lower spec` | Specification | \"LSL_Weight\" |\n| `target` | Specification | \"Target Value\" |\n\n### Data Quality Report\n\n```typescript\ninterface ValidationResult {\n isValid: boolean;\n rowCount: number;\n columnCount: number;\n numericColumns: string[];\n factorColumns: string[];\n warnings: ValidationWarning[];\n errors: ValidationError[];\n}\n```\n\n---\n\n## State Management\n\n### DataContext Structure\n\n```mermaid\nflowchart TD\n subgraph DataContext[\"DataContext (Central State)\"]\n R[rawData] --> F[filteredData]\n S[specs] --> C[calculations]\n M[measureSpecs] --> C\n FL[filters] --> F\n PM[isPerformanceMode] --> C\n end\n\n subgraph Actions[\"Actions\"]\n A1[setData]\n A2[setSpecs]\n A3[setFilters]\n A4[setPerformanceMode]\n end\n\n subgraph Consumers[\"Consumers\"]\n CH[Charts]\n ST[Stats Panels]\n FI[Filter UI]\n end\n\n Actions --> DataContext\n DataContext --> Consumers\n```\n\n### Filter Application\n\n```mermaid\nflowchart LR\n A[rawData] --> B{filters active?}\n B -->|No| C[filteredData = rawData]\n B -->|Yes| D[Apply filter predicate]\n D --> E[filteredData = subset]\n E --> F[Recalculate stats]\n F --> G[Update charts]\n```\n\n---\n\n## Analysis Engine\n\n### Statistics Calculation\n\n```mermaid\nflowchart TD\n subgraph Input\n D[filteredData]\n S[specs: USL, LSL, target]\n end\n\n subgraph Core[\"calculateStats()\"]\n M[mean = Σx/n]\n SD[stdDev = √(Σ(x-μ)²/n)]\n CL[UCL = μ + 3σ\u003Cbr/>LCL = μ - 3σ]\n CP[Cp = (USL-LSL)/6σ_within]\n CPK[Cpk = min(CPU, CPL)]\n end\n\n Input --> Core\n Core --> R[StatsResult]\n```\n\n### ANOVA Calculation\n\n```mermaid\nflowchart TD\n A[filteredData] --> B[Group by factor]\n B --> C[Calculate SS_between]\n B --> D[Calculate SS_within]\n C --> E[F = MS_between / MS_within]\n D --> E\n E --> F[p-value from F-distribution]\n C --> G[η² = SS_between / SS_total]\n D --> G\n F --> H[AnovaResult]\n G --> H\n```\n\n---\n\n## Platform-Specific Flows\n\n### PWA Data Flow\n\n```mermaid\nflowchart TB\n subgraph Browser[\"User's Browser\"]\n A[React App] --> B[DataContext]\n B --> C[(IndexedDB)]\n C --> D[Dexie.js]\n end\n\n subgraph Offline[\"Service Worker\"]\n E[Cache API] --> F[Offline Assets]\n end\n\n A \u003C--> E\n```\n\n### Azure App Data Flow\n\nBoth Standard and Team plans store data locally in IndexedDB. Team plan additionally syncs to OneDrive.\n\n```mermaid\nflowchart TB\n subgraph Browser[\"User's Browser\"]\n A[React App] --> B[DataContext]\n B --> C[(IndexedDB)]\n end\n\n subgraph Cloud[\"Microsoft Cloud (Team plan only)\"]\n D[EasyAuth] --> E[Access Token]\n E --> F[Graph API]\n F --> G[(OneDrive)]\n end\n\n B \u003C--> D\n C \u003C--> G\n\n note1[Team plan: Bi-directional sync — local-first, cloud backup\u003Cbr/>Standard plan: IndexedDB only — no cloud sync]\n```\n\n---\n\n## Hook Dependencies\n\n```mermaid\nflowchart TD\n subgraph Core[\"Core Hooks\"]\n DS[useDataState]\n FN[useFilterNavigation]\n VT[useVariationTracking]\n end\n\n subgraph Chart[\"Chart Hooks\"]\n CS[useChartScale]\n CT[useChartTheme]\n RM[useResponsiveChartMargins]\n end\n\n subgraph UI[\"UI Hooks\"]\n KN[useKeyboardNavigation]\n MQ[useIsMobile]\n end\n\n DS --> FN\n FN --> VT\n DS --> CS\n CS --> RM\n```\n\n---\n\n## Data Export\n\n### Export Formats\n\n```mermaid\nflowchart LR\n A[Filtered Data] --> B{Export Format}\n B --> C[CSV]\n B --> D[JSON]\n B --> E[Screenshot]\n\n C --> F[Download file]\n D --> F\n E --> G[Canvas capture]\n G --> F\n```\n\n---\n\n## See Also\n\n- [Data Pipeline Map](data-pipeline-map.md) — End-to-end pipeline with TypeScript interfaces at every boundary\n- [System Map](system-map.md) — Package topology and external integrations\n- [Component Patterns](component-patterns.md) — Hook integration details\n- [Offline-First](offline-first.md) — Persistence strategy\n- [Shared Packages](shared-packages.md) — Package responsibilities\n- [PWA Storage](../../08-products/pwa/storage.md) — IndexedDB details\n- [OneDrive Sync](../../08-products/azure/onedrive-sync.md) — Cloud sync details", + "src/content/docs/05-technical/architecture/data-flow.md", + "311b9d8e717536e4", + { "html": 8114, "metadata": 8115 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"data-flow-architecture\">Data Flow Architecture\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#data-flow-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Flow Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How data moves through VariScout from upload to persistence.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout processes data entirely client-side. This diagram shows the complete flow:\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph Input[\"Data Input\"]\n A1[File Upload] --> B[Parser]\n A2[Paste Data] --> B\n A3[Sample Dataset] --> B\n end\n\n subgraph Processing[\"Processing Layer\"]\n B --> C[Validation]\n C --> D[Column Detection]\n D --> E[Data State]\n end\n\n subgraph Analysis[\"Analysis Engine\"]\n E --> F1[Statistics]\n E --> F2[ANOVA]\n E --> F3[Regression]\n E --> F5[Performance]\n end\n\n subgraph Presentation[\"Presentation Layer\"]\n F1 --> G1[I-Chart]\n F2 --> G2[Boxplot]\n F2 --> G3[Pareto]\n F1 --> G4[Capability]\n F3 --> G5[Scatter]\n F5 --> G7[Performance Dashboard]\n end\n\n subgraph Persistence[\"Storage Layer\"]\n E --> H1[(IndexedDB)]\n E --> H2[(\"OneDrive (Team plan)\")]\n E --> H3[(Excel Doc Props)]\n end\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-input-stage\">Data Input Stage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-input-stage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Input Stage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"file-upload-flow\">File Upload Flow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#file-upload-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “File Upload Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">sequenceDiagram\n participant U as User\n participant UI as Upload UI\n participant H as useDataIngestion\n participant P as Parser\n participant V as Validator\n\n U->>UI: Select file (.csv, .xlsx)\n UI->>H: onFileSelect(file)\n H->>P: parseFile(file)\n P->>P: Detect format\n P->>P: Extract rows\n P-->>H: RawData[]\n H->>V: validateData(data)\n V->>V: Check types\n V->>V: Detect columns\n V-->>H: ValidationResult\n H-->>UI: DataReady + Quality Report\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"supported-formats\">Supported Formats\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#supported-formats\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Supported Formats”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Format\u003C/th>\u003Cth>Parser\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>CSV\u003C/td>\u003Ctd>Built-in\u003C/td>\u003Ctd>Auto-detects delimiter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>TSV\u003C/td>\u003Ctd>Built-in\u003C/td>\u003Ctd>Tab-separated\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel (.xlsx)\u003C/td>\u003Ctd>SheetJS\u003C/td>\u003Ctd>First sheet by default\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Paste\u003C/td>\u003Ctd>Built-in\u003C/td>\u003Ctd>Tab/comma detection\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"validation-stage\">Validation Stage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#validation-stage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Validation Stage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"column-detection\">Column Detection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#column-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Column Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n A[Raw Data] --> B{Has numeric columns?}\n B -->|Yes| C[Identify measure columns]\n B -->|No| D[Error: No numeric data]\n C --> E{Has factor columns?}\n E -->|Yes| F[Identify factor columns]\n E -->|No| G[Measure-only mode]\n F --> H[Column Mapping UI]\n G --> H\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"keyword-detection\">Keyword Detection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The parser detects special columns by keywords:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Keyword Pattern\u003C/th>\u003Cth>Column Type\u003C/th>\u003Cth>Example\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">operator\u003C/code>, \u003Ccode dir=\"auto\">inspector\u003C/code>\u003C/td>\u003Ctd>Operator (MSA)\u003C/td>\u003Ctd>“Operator Name”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">part\u003C/code>, \u003Ccode dir=\"auto\">sample\u003C/code>, \u003Ccode dir=\"auto\">item\u003C/code>\u003C/td>\u003Ctd>Part ID (MSA)\u003C/td>\u003Ctd>“Sample ID”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">usl\u003C/code>, \u003Ccode dir=\"auto\">upper spec\u003C/code>\u003C/td>\u003Ctd>Specification\u003C/td>\u003Ctd>”USL_Weight”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">lsl\u003C/code>, \u003Ccode dir=\"auto\">lower spec\u003C/code>\u003C/td>\u003Ctd>Specification\u003C/td>\u003Ctd>”LSL_Weight”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">target\u003C/code>\u003C/td>\u003Ctd>Specification\u003C/td>\u003Ctd>”Target Value”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-quality-report\">Data Quality Report\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-quality-report\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Quality Report”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ValidationResult {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isValid\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">rowCount\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">columnCount\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">numericColumns\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factorColumns\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">warnings\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ValidationWarning\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">errors\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ValidationError\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ValidationResult { isValid: boolean; rowCount: number; columnCount: number; numericColumns: string[]; factorColumns: string[]; warnings: ValidationWarning[]; errors: ValidationError[];}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"state-management\">State Management\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#state-management\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “State Management”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"datacontext-structure\">DataContext Structure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#datacontext-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “DataContext Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n subgraph DataContext[\"DataContext (Central State)\"]\n R[rawData] --> F[filteredData]\n S[specs] --> C[calculations]\n M[measureSpecs] --> C\n FL[filters] --> F\n PM[isPerformanceMode] --> C\n end\n\n subgraph Actions[\"Actions\"]\n A1[setData]\n A2[setSpecs]\n A3[setFilters]\n A4[setPerformanceMode]\n end\n\n subgraph Consumers[\"Consumers\"]\n CH[Charts]\n ST[Stats Panels]\n FI[Filter UI]\n end\n\n Actions --> DataContext\n DataContext --> Consumers\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filter-application\">Filter Application\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filter-application\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter Application”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n A[rawData] --> B{filters active?}\n B -->|No| C[filteredData = rawData]\n B -->|Yes| D[Apply filter predicate]\n D --> E[filteredData = subset]\n E --> F[Recalculate stats]\n F --> G[Update charts]\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysis-engine\">Analysis Engine\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-engine\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis Engine”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"statistics-calculation\">Statistics Calculation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#statistics-calculation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Statistics Calculation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n subgraph Input\n D[filteredData]\n S[specs: USL, LSL, target]\n end\n\n subgraph Core[\"calculateStats()\"]\n M[mean = Σx/n]\n SD[stdDev = √(Σ(x-μ)²/n)]\n CL[UCL = μ + 3σ<br/>LCL = μ - 3σ]\n CP[Cp = (USL-LSL)/6σ_within]\n CPK[Cpk = min(CPU, CPL)]\n end\n\n Input --> Core\n Core --> R[StatsResult]\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"anova-calculation\">ANOVA Calculation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#anova-calculation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ANOVA Calculation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n A[filteredData] --> B[Group by factor]\n B --> C[Calculate SS_between]\n B --> D[Calculate SS_within]\n C --> E[F = MS_between / MS_within]\n D --> E\n E --> F[p-value from F-distribution]\n C --> G[η² = SS_between / SS_total]\n D --> G\n F --> H[AnovaResult]\n G --> H\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-specific-flows\">Platform-Specific Flows\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-specific-flows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform-Specific Flows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-data-flow\">PWA Data Flow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-data-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA Data Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph Browser[\"User's Browser\"]\n A[React App] --> B[DataContext]\n B --> C[(IndexedDB)]\n C --> D[Dexie.js]\n end\n\n subgraph Offline[\"Service Worker\"]\n E[Cache API] --> F[Offline Assets]\n end\n\n A <--> E\n\u003C/pre>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-app-data-flow\">Azure App Data Flow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-data-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App Data Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both Standard and Team plans store data locally in IndexedDB. Team plan additionally syncs to OneDrive.\u003C/p>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TB\n subgraph Browser[\"User's Browser\"]\n A[React App] --> B[DataContext]\n B --> C[(IndexedDB)]\n end\n\n subgraph Cloud[\"Microsoft Cloud (Team plan only)\"]\n D[EasyAuth] --> E[Access Token]\n E --> F[Graph API]\n F --> G[(OneDrive)]\n end\n\n B <--> D\n C <--> G\n\n note1[Team plan: Bi-directional sync — local-first, cloud backup<br/>Standard plan: IndexedDB only — no cloud sync]\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"hook-dependencies\">Hook Dependencies\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#hook-dependencies\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hook Dependencies”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart TD\n subgraph Core[\"Core Hooks\"]\n DS[useDataState]\n FN[useFilterNavigation]\n VT[useVariationTracking]\n end\n\n subgraph Chart[\"Chart Hooks\"]\n CS[useChartScale]\n CT[useChartTheme]\n RM[useResponsiveChartMargins]\n end\n\n subgraph UI[\"UI Hooks\"]\n KN[useKeyboardNavigation]\n MQ[useIsMobile]\n end\n\n DS --> FN\n FN --> VT\n DS --> CS\n CS --> RM\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-export\">Data Export\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-export\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Export”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"export-formats\">Export Formats\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#export-formats\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Export Formats”\u003C/span>\u003C/a>\u003C/div>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n A[Filtered Data] --> B{Export Format}\n B --> C[CSV]\n B --> D[JSON]\n B --> E[Screenshot]\n\n C --> F[Download file]\n D --> F\n E --> G[Canvas capture]\n G --> F\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"data-pipeline-map.md\">Data Pipeline Map\u003C/a> — End-to-end pipeline with TypeScript interfaces at every boundary\u003C/li>\n\u003Cli>\u003Ca href=\"system-map.md\">System Map\u003C/a> — Package topology and external integrations\u003C/li>\n\u003Cli>\u003Ca href=\"component-patterns.md\">Component Patterns\u003C/a> — Hook integration details\u003C/li>\n\u003Cli>\u003Ca href=\"offline-first.md\">Offline-First\u003C/a> — Persistence strategy\u003C/li>\n\u003Cli>\u003Ca href=\"shared-packages.md\">Shared Packages\u003C/a> — Package responsibilities\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/pwa/storage.md\">PWA Storage\u003C/a> — IndexedDB details\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/onedrive-sync.md\">OneDrive Sync\u003C/a> — Cloud sync details\u003C/li>\n\u003C/ul>", + { + "headings": 8116, + "localImagePaths": 8170, + "remoteImagePaths": 8171, + "frontmatter": 8172, + "imagePaths": 8173 + }, + [ + 8117, 8119, 8120, 8123, 8126, 8127, 8130, 8131, 8134, 8137, 8138, 8141, 8142, 8145, 8148, 8151, + 8154, 8157, 8160, 8163, 8166, 8169 + ], + { "depth": 30, "slug": 8118, "text": 8106 }, + "data-flow-architecture", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 8121, "text": 8122 }, + "data-input-stage", + "Data Input Stage", + { "depth": 79, "slug": 8124, "text": 8125 }, + "file-upload-flow", + "File Upload Flow", + { "depth": 79, "slug": 6925, "text": 6926 }, + { "depth": 33, "slug": 8128, "text": 8129 }, + "validation-stage", + "Validation Stage", + { "depth": 79, "slug": 6928, "text": 6929 }, + { "depth": 79, "slug": 8132, "text": 8133 }, + "keyword-detection", + "Keyword Detection", + { "depth": 79, "slug": 8135, "text": 8136 }, + "data-quality-report", + "Data Quality Report", + { "depth": 33, "slug": 3402, "text": 3403 }, + { "depth": 79, "slug": 8139, "text": 8140 }, + "datacontext-structure", + "DataContext Structure", + { "depth": 79, "slug": 3318, "text": 3319 }, + { "depth": 33, "slug": 8143, "text": 8144 }, + "analysis-engine", + "Analysis Engine", + { "depth": 79, "slug": 8146, "text": 8147 }, + "statistics-calculation", + "Statistics Calculation", + { "depth": 79, "slug": 8149, "text": 8150 }, + "anova-calculation", + "ANOVA Calculation", + { "depth": 33, "slug": 8152, "text": 8153 }, + "platform-specific-flows", + "Platform-Specific Flows", + { "depth": 79, "slug": 8155, "text": 8156 }, + "pwa-data-flow", + "PWA Data Flow", + { "depth": 79, "slug": 8158, "text": 8159 }, + "azure-app-data-flow", + "Azure App Data Flow", + { "depth": 33, "slug": 8161, "text": 8162 }, + "hook-dependencies", + "Hook Dependencies", + { "depth": 33, "slug": 8164, "text": 8165 }, + "data-export", + "Data Export", + { "depth": 79, "slug": 8167, "text": 8168 }, + "export-formats", + "Export Formats", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 8106 }, + [], + "05-technical/architecture/monorepo", + { "id": 8174, "data": 8176, "body": 8181, "filePath": 8182, "digest": 8183, "rendered": 8184 }, + { + "title": 8177, + "editUrl": 16, + "head": 8178, + "template": 18, + "sidebar": 8179, + "pagefind": 16, + "draft": 20 + }, + "Monorepo Architecture", + [], + { "hidden": 20, "attrs": 8180 }, + {}, + "# Monorepo Architecture\n\nVariScout uses a pnpm workspaces monorepo to share code across multiple applications.\n\n---\n\n## Structure\n\n```\nvariscout-lite/\n├── packages/\n│ ├── core/ # @variscout/core - Stats, parser, license, types\n│ ├── charts/ # @variscout/charts - Visx chart components\n│ ├── data/ # @variscout/data - Sample datasets\n│ ├── hooks/ # @variscout/hooks - Shared React hooks\n│ └── ui/ # @variscout/ui - Shared UI utilities\n├── apps/\n│ ├── pwa/ # PWA website (React + Vite)\n│ ├── azure/ # Azure Team App (EasyAuth + OneDrive sync)\n│ └── website/ # Marketing website (Astro + React Islands)\n└── docs/ # Documentation\n```\n\n---\n\n## Package Responsibilities\n\n### @variscout/core\n\nPure logic with no React dependencies:\n\n- Statistical calculations (mean, Cp, Cpk, ANOVA)\n- CSV/Excel parsing and validation\n- TypeScript type definitions\n- Glossary terms and definitions\n\n### @variscout/charts\n\nReact + Visx chart components:\n\n- IChart, Boxplot, ParetoChart, ScatterPlot\n- Performance charts (multi-channel analysis)\n- Theme-aware colors via `useChartTheme`\n- Responsive utilities\n\n### @variscout/hooks\n\nShared React hooks:\n\n- `useChartScale` - Y-axis scale calculation\n- `useFilterNavigation` - Filter navigation with breadcrumbs\n- `useVariationTracking` - Cumulative η² tracking\n- `useDataState` - Shared DataContext state management\n- `useDataIngestion` - File upload and data parsing\n- `useKeyboardNavigation` - Arrow key focus management\n- `useResponsiveChartMargins` - Dynamic chart margins\n- `useColumnClassification` - Column type detection\n- `useRegressionState` - Regression panel state management\n\n### @variscout/ui\n\nShared UI components and utilities:\n\n- `ChartCard` - Reusable chart container with header, controls, and actions\n- `ColumnMapping` - Column selection UI for data setup\n- `MeasureColumnSelector` - Checkbox list for selecting measure columns\n- `PerformanceDetectedModal` - Wide-format data detection prompt\n- `DataQualityBanner` - Data validation summary display\n- `HelpTooltip` - Contextual help with glossary integration\n- `useGlossary` hook\n- `useIsMobile` responsive hook\n- Color constants (statusColors)\n- Error service utilities\n\n### @variscout/data\n\nSample datasets with pre-computed statistics:\n\n- Coffee, journey, bottleneck, sachets samples\n- Pre-computed chart data for demos\n\n---\n\n## Dependency Rules\n\n```\napps/ ──────────────────────────────────────────────────▶\n │\n │ import from packages (never the reverse)\n │\n ▼\npackages/ ──────────────────────────────────────────────▶\n │\n ├── @variscout/core (no React, no external deps)\n │ │\n │ └── types, stats, parser, glossary\n │\n ├── @variscout/charts (depends on core)\n │ │\n │ └── React + Visx chart components\n │\n ├── @variscout/hooks (depends on core)\n │ │\n │ └── shared React hooks\n │\n └── @variscout/ui (depends on core)\n │\n └── UI utilities, HelpTooltip\n```\n\n**Rules:**\n\n- Apps import from packages: `import { calculateStats } from '@variscout/core'`\n- Packages never import from apps\n- `@variscout/core` has no React dependencies\n- Use `workspace:*` for internal package references\n\n---\n\n## Build Commands\n\n```bash\n# Build all packages and apps\npnpm build\n\n# Build specific package/app\npnpm --filter @variscout/pwa build\npnpm --filter @variscout/core build\n\n# Build recursively (dependencies first)\npnpm -r build\n\n# Development servers\npnpm dev # PWA\npnpm --filter @variscout/azure-app dev # Azure app\n```\n\n---\n\n## Adding Dependencies\n\n| Type | Where to Add | Example |\n| ----------------- | ----------------------- | ---------------------------------- |\n| Shared tooling | Root `devDependencies` | TypeScript, ESLint, Vitest |\n| Package-specific | Package `dependencies` | Visx in @variscout/charts |\n| Internal packages | `workspace:*` reference | `\"@variscout/core\": \"workspace:*\"` |\n\n---\n\n## See Also\n\n- [ADR-001: Monorepo Decision](../../07-decisions/adr-001-monorepo.md)\n- [Shared Packages](shared-packages.md)", + "src/content/docs/05-technical/architecture/monorepo.md", + "32835daaaf2d81b1", + { "html": 8185, "metadata": 8186 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"monorepo-architecture\">Monorepo Architecture\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#monorepo-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Monorepo Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses a pnpm workspaces monorepo to share code across multiple applications.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"structure\">Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">variscout-lite/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── packages/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── core/ # @variscout/core - Stats, parser, license, types\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── charts/ # @variscout/charts - Visx chart components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── data/ # @variscout/data - Sample datasets\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── hooks/ # @variscout/hooks - Shared React hooks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── ui/ # @variscout/ui - Shared UI utilities\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── apps/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── pwa/ # PWA website (React + Vite)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── azure/ # Azure Team App (EasyAuth + OneDrive sync)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── website/ # Marketing website (Astro + React Islands)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── docs/ # Documentation\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"variscout-lite/├── packages/│ ├── core/ # @variscout/core - Stats, parser, license, types│ ├── charts/ # @variscout/charts - Visx chart components│ ├── data/ # @variscout/data - Sample datasets│ ├── hooks/ # @variscout/hooks - Shared React hooks│ └── ui/ # @variscout/ui - Shared UI utilities├── apps/│ ├── pwa/ # PWA website (React + Vite)│ ├── azure/ # Azure Team App (EasyAuth + OneDrive sync)│ └── website/ # Marketing website (Astro + React Islands)└── docs/ # Documentation\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"package-responsibilities\">Package Responsibilities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#package-responsibilities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Package Responsibilities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutcore\">@variscout/core\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutcore\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/core”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pure logic with no React dependencies:\u003C/p>\n\u003Cul>\n\u003Cli>Statistical calculations (mean, Cp, Cpk, ANOVA)\u003C/li>\n\u003Cli>CSV/Excel parsing and validation\u003C/li>\n\u003Cli>TypeScript type definitions\u003C/li>\n\u003Cli>Glossary terms and definitions\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutcharts\">@variscout/charts\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutcharts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>React + Visx chart components:\u003C/p>\n\u003Cul>\n\u003Cli>IChart, Boxplot, ParetoChart, ScatterPlot\u003C/li>\n\u003Cli>Performance charts (multi-channel analysis)\u003C/li>\n\u003Cli>Theme-aware colors via \u003Ccode dir=\"auto\">useChartTheme\u003C/code>\u003C/li>\n\u003Cli>Responsive utilities\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscouthooks\">@variscout/hooks\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscouthooks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/hooks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shared React hooks:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">useChartScale\u003C/code> - Y-axis scale calculation\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useFilterNavigation\u003C/code> - Filter navigation with breadcrumbs\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code> - Cumulative η² tracking\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useDataState\u003C/code> - Shared DataContext state management\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useDataIngestion\u003C/code> - File upload and data parsing\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useKeyboardNavigation\u003C/code> - Arrow key focus management\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useResponsiveChartMargins\u003C/code> - Dynamic chart margins\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useColumnClassification\u003C/code> - Column type detection\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useRegressionState\u003C/code> - Regression panel state management\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutui\">@variscout/ui\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutui\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/ui”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shared UI components and utilities:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">ChartCard\u003C/code> - Reusable chart container with header, controls, and actions\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">ColumnMapping\u003C/code> - Column selection UI for data setup\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">MeasureColumnSelector\u003C/code> - Checkbox list for selecting measure columns\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">PerformanceDetectedModal\u003C/code> - Wide-format data detection prompt\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">DataQualityBanner\u003C/code> - Data validation summary display\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">HelpTooltip\u003C/code> - Contextual help with glossary integration\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useGlossary\u003C/code> hook\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useIsMobile\u003C/code> responsive hook\u003C/li>\n\u003Cli>Color constants (statusColors)\u003C/li>\n\u003Cli>Error service utilities\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutdata\">@variscout/data\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutdata\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Sample datasets with pre-computed statistics:\u003C/p>\n\u003Cul>\n\u003Cli>Coffee, journey, bottleneck, sachets samples\u003C/li>\n\u003Cli>Pre-computed chart data for demos\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dependency-rules\">Dependency Rules\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dependency-rules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dependency Rules”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">apps/ ──────────────────────────────────────────────────▶\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ import from packages (never the reverse)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">packages/ ──────────────────────────────────────────────▶\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── @variscout/core (no React, no external deps)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── types, stats, parser, glossary\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── @variscout/charts (depends on core)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── React + Visx chart components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── @variscout/hooks (depends on core)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── shared React hooks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── @variscout/ui (depends on core)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── UI utilities, HelpTooltip\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"apps/ ──────────────────────────────────────────────────▶ │ │ import from packages (never the reverse) │ ▼packages/ ──────────────────────────────────────────────▶ │ ├── @variscout/core (no React, no external deps) │ │ │ └── types, stats, parser, glossary │ ├── @variscout/charts (depends on core) │ │ │ └── React + Visx chart components │ ├── @variscout/hooks (depends on core) │ │ │ └── shared React hooks │ └── @variscout/ui (depends on core) │ └── UI utilities, HelpTooltip\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Rules:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Apps import from packages: \u003Ccode dir=\"auto\">import { calculateStats } from '@variscout/core'\u003C/code>\u003C/li>\n\u003Cli>Packages never import from apps\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">@variscout/core\u003C/code> has no React dependencies\u003C/li>\n\u003Cli>Use \u003Ccode dir=\"auto\">workspace:*\u003C/code> for internal package references\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"build-commands\">Build Commands\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#build-commands\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Build Commands”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build all packages and apps\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build specific package/app\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/pwa\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build recursively (dependencies first)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-r\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Development servers\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># PWA\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Azure app\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm buildpnpm --filter @variscout/pwa buildpnpm --filter @variscout/core buildpnpm -r buildpnpm dev # PWApnpm --filter @variscout/azure-app dev # Azure app\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"adding-dependencies\">Adding Dependencies\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#adding-dependencies\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Adding Dependencies”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Where to Add\u003C/th>\u003Cth>Example\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Shared tooling\u003C/td>\u003Ctd>Root \u003Ccode dir=\"auto\">devDependencies\u003C/code>\u003C/td>\u003Ctd>TypeScript, ESLint, Vitest\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Package-specific\u003C/td>\u003Ctd>Package \u003Ccode dir=\"auto\">dependencies\u003C/code>\u003C/td>\u003Ctd>Visx in @variscout/charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Internal packages\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">workspace:*\u003C/code> reference\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">\"@variscout/core\": \"workspace:*\"\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-001-monorepo.md\">ADR-001: Monorepo Decision\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"shared-packages.md\">Shared Packages\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 8187, + "localImagePaths": 8207, + "remoteImagePaths": 8208, + "frontmatter": 8209, + "imagePaths": 8210 + }, + [8188, 8190, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8202, 8203, 8206], + { "depth": 30, "slug": 8189, "text": 8177 }, + "monorepo-architecture", + { "depth": 33, "slug": 8191, "text": 8192 }, + "structure", + "Structure", + { "depth": 33, "slug": 310, "text": 311 }, + { "depth": 79, "slug": 254, "text": 255 }, + { "depth": 79, "slug": 257, "text": 258 }, + { "depth": 79, "slug": 260, "text": 261 }, + { "depth": 79, "slug": 263, "text": 264 }, + { "depth": 79, "slug": 269, "text": 270 }, + { "depth": 33, "slug": 8200, "text": 8201 }, + "dependency-rules", + "Dependency Rules", + { "depth": 33, "slug": 2314, "text": 2315 }, + { "depth": 33, "slug": 8204, "text": 8205 }, + "adding-dependencies", + "Adding Dependencies", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 8177 }, + [], + "05-technical/architecture/offline-first", + { "id": 8211, "data": 8213, "body": 8218, "filePath": 8219, "digest": 8220, "rendered": 8221 }, + { + "title": 8214, + "editUrl": 16, + "head": 8215, + "template": 18, + "sidebar": 8216, + "pagefind": 16, + "draft": 20 + }, + "Offline-First Architecture", + [], + { "hidden": 20, "attrs": 8217 }, + {}, + "# Offline-First Architecture\n\nVariScout is designed to work without internet access after the initial load.\n\n---\n\n## Principles\n\n1. **No backend required** — All statistical processing in browser\n2. **Service Worker** — Cache app shell and assets\n3. **Local-first data** — All data stays in IndexedDB\n4. **Optional sync** — Azure Team plan can sync to OneDrive when online (Standard plan uses local-only storage)\n\n---\n\n## Why Offline-First?\n\nQuality professionals often work in:\n\n- Manufacturing floors with limited connectivity\n- Remote facilities without reliable internet\n- Secure environments where cloud access is restricted\n\nThe tool must work reliably in these conditions.\n\n---\n\n## Implementation\n\n### PWA Service Worker (Workbox)\n\nGenerated by `vite-plugin-pwa` with `autoUpdate` registration strategy:\n\n| Setting | Value | Purpose |\n| ------------------ | ------------------------------------------- | ---------------------------------------------- |\n| `clientsClaim` | `true` | New SW controls all tabs immediately |\n| `skipWaiting` | `true` | Activate without waiting for old tabs to close |\n| `navigateFallback` | `/index.html` | SPA routing works offline |\n| `globPatterns` | `**/*.{js,css,html,ico,png,svg,woff,woff2}` | Pre-cache all static assets |\n\nSelf-hosted fonts (Caveat) — no Google Fonts CDN dependency, fully offline after first load.\n\n```javascript\n// Caches:\n// 1. App shell (HTML, CSS, JS) — pre-cached via globPatterns\n// 2. Static assets (fonts, icons) — pre-cached\n// 3. Google Fonts (runtime CacheFirst, 1-year TTL) — if ever used\n\n// Does NOT cache:\n// - User data (stays in IndexedDB)\n// - External API calls (none required)\n```\n\n### Data Storage\n\n| Data Type | Storage | Retention |\n| ------------------- | ------------------ | --------------------- |\n| Uploaded datasets | IndexedDB | Until deleted |\n| Computed statistics | IndexedDB (cached) | Until dataset deleted |\n| User settings | IndexedDB | Persistent |\n| Theme preference | localStorage | Persistent |\n\n### No Cloud Dependencies\n\nThe core application has zero runtime dependencies on external services:\n\n- Statistics calculated locally using `@variscout/core`\n- Charts rendered using local Visx components\n- No telemetry or analytics (privacy-first)\n- No authentication required for core features\n\n---\n\n## Update Mechanism\n\nSince there's no backend, updates happen via:\n\n1. Service worker detects new version\n2. New assets cached in background\n3. User prompted to refresh\n4. Old cache cleared after successful update\n\n```\nUSER SERVICE WORKER CACHE\n │ │ │\n │───── Visit app ──────────▶│ │\n │ │───── Check version ───▶│\n │ │◀──── v1.2.3 cached ────│\n │◀──── Serve from cache ────│ │\n │ │ │\n │ │═══ Background check ═══│\n │ │───── Fetch v1.2.4 ────▶│\n │ │◀───── New version ─────│\n │ │───── Cache new ───────▶│\n │ │ │\n │◀──── \"Update available\" ──│ │\n │───── Refresh ────────────▶│ │\n │◀──── Serve v1.2.4 ────────│ │\n```\n\n---\n\n## Azure App: Storage by Plan\n\nBoth Azure plans store data locally in IndexedDB. The Team plan additionally syncs to OneDrive.\n\n**Standard plan (€99/month)** — IndexedDB only, no cloud sync:\n\n```\n┌─────────────────────────────────────────────────────┐\n│ AZURE STANDARD APP │\n│ │\n│ ┌─────────────┐ │\n│ │ IndexedDB │ │\n│ │ (local) │ │\n│ └─────────────┘ │\n│ │ │\n│ │ always available │\n│ ▼ │\n│ ┌───────────────────────────────────────────┐ │\n│ │ Application │ │\n│ └───────────────────────────────────────────┘ │\n│ │\n└─────────────────────────────────────────────────────┘\n```\n\n**Team plan (€299/month)** — IndexedDB + OneDrive sync:\n\n```\n┌─────────────────────────────────────────────────────┐\n│ AZURE TEAM APP │\n│ │\n│ ┌─────────────┐ ┌─────────────┐ │\n│ │ IndexedDB │◄───────▶│ OneDrive │ │\n│ │ (local) │ sync │ (cloud) │ │\n│ └─────────────┘ └─────────────┘ │\n│ │ │ │\n│ │ always │ when online │\n│ │ available │ available │\n│ ▼ ▼ │\n│ ┌───────────────────────────────────────────┐ │\n│ │ Application │ │\n│ │ (works with either) │ │\n│ └───────────────────────────────────────────┘ │\n│ │\n└─────────────────────────────────────────────────────┘\n```\n\n---\n\n## Benefits\n\n| Benefit | Description |\n| --------------- | ---------------------------- |\n| **Reliability** | Works in low/no connectivity |\n| **Privacy** | Data never leaves device |\n| **Speed** | No network latency |\n| **Cost** | No server infrastructure |\n| **Simplicity** | No sync conflicts to resolve |\n\n---\n\n## Trade-offs\n\n| Trade-off | Mitigation |\n| ---------------------------- | ------------------------------------- |\n| No cross-device sync (PWA) | Azure Team plan adds OneDrive sync |\n| Limited by browser resources | Target datasets are typically small |\n| Update requires refresh | Clear messaging when update available |\n\n---\n\n## See Also\n\n- [ADR-004: Offline-First Decision](../../07-decisions/adr-004-offline-first.md)\n- [PWA Storage](../../08-products/pwa/storage.md)", + "src/content/docs/05-technical/architecture/offline-first.md", + "d729c31310b0d916", + { "html": 8222, "metadata": 8223 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"offline-first-architecture\">Offline-First Architecture\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#offline-first-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Offline-First Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is designed to work without internet access after the initial load.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"principles\">Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>No backend required\u003C/strong> — All statistical processing in browser\u003C/li>\n\u003Cli>\u003Cstrong>Service Worker\u003C/strong> — Cache app shell and assets\u003C/li>\n\u003Cli>\u003Cstrong>Local-first data\u003C/strong> — All data stays in IndexedDB\u003C/li>\n\u003Cli>\u003Cstrong>Optional sync\u003C/strong> — Azure Team plan can sync to OneDrive when online (Standard plan uses local-only storage)\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-offline-first\">Why Offline-First?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-offline-first\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Offline-First?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Quality professionals often work in:\u003C/p>\n\u003Cul>\n\u003Cli>Manufacturing floors with limited connectivity\u003C/li>\n\u003Cli>Remote facilities without reliable internet\u003C/li>\n\u003Cli>Secure environments where cloud access is restricted\u003C/li>\n\u003C/ul>\n\u003Cp>The tool must work reliably in these conditions.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation\">Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-service-worker-workbox\">PWA Service Worker (Workbox)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-service-worker-workbox\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA Service Worker (Workbox)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Generated by \u003Ccode dir=\"auto\">vite-plugin-pwa\u003C/code> with \u003Ccode dir=\"auto\">autoUpdate\u003C/code> registration strategy:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Setting\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">clientsClaim\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">true\u003C/code>\u003C/td>\u003Ctd>New SW controls all tabs immediately\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">skipWaiting\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">true\u003C/code>\u003C/td>\u003Ctd>Activate without waiting for old tabs to close\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">navigateFallback\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/index.html\u003C/code>\u003C/td>\u003Ctd>SPA routing works offline\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">globPatterns\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">**/*.{js,css,html,ico,png,svg,woff,woff2}\u003C/code>\u003C/td>\u003Ctd>Pre-cache all static assets\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Self-hosted fonts (Caveat) — no Google Fonts CDN dependency, fully offline after first load.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Caches:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. App shell (HTML, CSS, JS) — pre-cached via globPatterns\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Static assets (fonts, icons) — pre-cached\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Google Fonts (runtime CacheFirst, 1-year TTL) — if ever used\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Does NOT cache:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - User data (stays in IndexedDB)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - External API calls (none required)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Caches:// 1. App shell (HTML, CSS, JS) — pre-cached via globPatterns// 2. Static assets (fonts, icons) — pre-cached// 3. Google Fonts (runtime CacheFirst, 1-year TTL) — if ever used// Does NOT cache:// - User data (stays in IndexedDB)// - External API calls (none required)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-storage\">Data Storage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-storage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Storage”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Data Type\u003C/th>\u003Cth>Storage\u003C/th>\u003Cth>Retention\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Uploaded datasets\u003C/td>\u003Ctd>IndexedDB\u003C/td>\u003Ctd>Until deleted\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Computed statistics\u003C/td>\u003Ctd>IndexedDB (cached)\u003C/td>\u003Ctd>Until dataset deleted\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>User settings\u003C/td>\u003Ctd>IndexedDB\u003C/td>\u003Ctd>Persistent\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Theme preference\u003C/td>\u003Ctd>localStorage\u003C/td>\u003Ctd>Persistent\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"no-cloud-dependencies\">No Cloud Dependencies\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#no-cloud-dependencies\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “No Cloud Dependencies”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The core application has zero runtime dependencies on external services:\u003C/p>\n\u003Cul>\n\u003Cli>Statistics calculated locally using \u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/li>\n\u003Cli>Charts rendered using local Visx components\u003C/li>\n\u003Cli>No telemetry or analytics (privacy-first)\u003C/li>\n\u003Cli>No authentication required for core features\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"update-mechanism\">Update Mechanism\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#update-mechanism\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Update Mechanism”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Since there’s no backend, updates happen via:\u003C/p>\n\u003Col>\n\u003Cli>Service worker detects new version\u003C/li>\n\u003Cli>New assets cached in background\u003C/li>\n\u003Cli>User prompted to refresh\u003C/li>\n\u003Cli>Old cache cleared after successful update\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USER SERVICE WORKER CACHE\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│───── Visit app ──────────▶│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │───── Check version ───▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │◀──── v1.2.3 cached ────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀──── Serve from cache ────│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │═══ Background check ═══│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │───── Fetch v1.2.4 ────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │◀───── New version ─────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │───── Cache new ───────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀──── \"Update available\" ──│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│───── Refresh ────────────▶│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀──── Serve v1.2.4 ────────│ │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"USER SERVICE WORKER CACHE │ │ │ │───── Visit app ──────────▶│ │ │ │───── Check version ───▶│ │ │◀──── v1.2.3 cached ────│ │◀──── Serve from cache ────│ │ │ │ │ │ │═══ Background check ═══│ │ │───── Fetch v1.2.4 ────▶│ │ │◀───── New version ─────│ │ │───── Cache new ───────▶│ │ │ │ │◀──── "Update available" ──│ │ │───── Refresh ────────────▶│ │ │◀──── Serve v1.2.4 ────────│ │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"azure-app-storage-by-plan\">Azure App: Storage by Plan\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-storage-by-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App: Storage by Plan”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both Azure plans store data locally in IndexedDB. The Team plan additionally syncs to OneDrive.\u003C/p>\n\u003Cp>\u003Cstrong>Standard plan (€99/month)\u003C/strong> — IndexedDB only, no cloud sync:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ AZURE STANDARD APP │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌─────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ IndexedDB │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ (local) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └─────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ always available │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▼ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌───────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Application │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────┐│ AZURE STANDARD APP ││ ││ ┌─────────────┐ ││ │ IndexedDB │ ││ │ (local) │ ││ └─────────────┘ ││ │ ││ │ always available ││ ▼ ││ ┌───────────────────────────────────────────┐ ││ │ Application │ ││ └───────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Team plan (€299/month)\u003C/strong> — IndexedDB + OneDrive sync:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ AZURE TEAM APP │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌─────────────┐ ┌─────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ IndexedDB │◄───────▶│ OneDrive │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ (local) │ sync │ (cloud) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └─────────────┘ └─────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ always │ when online │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ available │ available │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▼ ▼ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌───────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Application │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ (works with either) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────┐│ AZURE TEAM APP ││ ││ ┌─────────────┐ ┌─────────────┐ ││ │ IndexedDB │◄───────▶│ OneDrive │ ││ │ (local) │ sync │ (cloud) │ ││ └─────────────┘ └─────────────┘ ││ │ │ ││ │ always │ when online ││ │ available │ available ││ ▼ ▼ ││ ┌───────────────────────────────────────────┐ ││ │ Application │ ││ │ (works with either) │ ││ └───────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"benefits\">Benefits\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#benefits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Benefits”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Benefit\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Reliability\u003C/strong>\u003C/td>\u003Ctd>Works in low/no connectivity\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Privacy\u003C/strong>\u003C/td>\u003Ctd>Data never leaves device\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Speed\u003C/strong>\u003C/td>\u003Ctd>No network latency\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Cost\u003C/strong>\u003C/td>\u003Ctd>No server infrastructure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Simplicity\u003C/strong>\u003C/td>\u003Ctd>No sync conflicts to resolve\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"trade-offs\">Trade-offs\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#trade-offs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Trade-offs”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Trade-off\u003C/th>\u003Cth>Mitigation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No cross-device sync (PWA)\u003C/td>\u003Ctd>Azure Team plan adds OneDrive sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Limited by browser resources\u003C/td>\u003Ctd>Target datasets are typically small\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Update requires refresh\u003C/td>\u003Ctd>Clear messaging when update available\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-004-offline-first.md\">ADR-004: Offline-First Decision\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/pwa/storage.md\">PWA Storage\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 8224, + "localImagePaths": 8250, + "remoteImagePaths": 8251, + "frontmatter": 8252, + "imagePaths": 8253 + }, + [8225, 8227, 8228, 8231, 8232, 8235, 8238, 8241, 8244, 8247, 8248, 8249], + { "depth": 30, "slug": 8226, "text": 8214 }, + "offline-first-architecture", + { "depth": 33, "slug": 1988, "text": 1989 }, + { "depth": 33, "slug": 8229, "text": 8230 }, + "why-offline-first", + "Why Offline-First?", + { "depth": 33, "slug": 1885, "text": 1886 }, + { "depth": 79, "slug": 8233, "text": 8234 }, + "pwa-service-worker-workbox", + "PWA Service Worker (Workbox)", + { "depth": 79, "slug": 8236, "text": 8237 }, + "data-storage", + "Data Storage", + { "depth": 79, "slug": 8239, "text": 8240 }, + "no-cloud-dependencies", + "No Cloud Dependencies", + { "depth": 33, "slug": 8242, "text": 8243 }, + "update-mechanism", + "Update Mechanism", + { "depth": 33, "slug": 8245, "text": 8246 }, + "azure-app-storage-by-plan", + "Azure App: Storage by Plan", + { "depth": 33, "slug": 2156, "text": 2157 }, + { "depth": 33, "slug": 2159, "text": 2160 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 8214 }, + [], + "05-technical/architecture/shared-packages", + { "id": 8254, "data": 8256, "body": 8261, "filePath": 8262, "digest": 8263, "rendered": 8264 }, + { + "title": 8257, + "editUrl": 16, + "head": 8258, + "template": 18, + "sidebar": 8259, + "pagefind": 16, + "draft": 20 + }, + "Shared Packages", + [], + { "hidden": 20, "attrs": 8260 }, + {}, + "# Shared Packages\n\nThe monorepo contains several shared packages that provide common functionality across apps.\n\n---\n\n## Package Overview\n\n| Package | Purpose | React? |\n| ------------------- | --------------------------- | ------ |\n| `@variscout/core` | Statistics, parsing, types | No |\n| `@variscout/charts` | Visx chart components | Yes |\n| `@variscout/hooks` | Shared React hooks | Yes |\n| `@variscout/ui` | UI components and utilities | Yes |\n| `@variscout/data` | Sample datasets | No |\n\n---\n\n## @variscout/core\n\n**Pure logic with no React dependencies.**\n\n### Key Exports\n\n```typescript\n// Statistics\nimport { calculateStats, calculateAnova } from '@variscout/core';\n\n// Parsing\nimport { parseCSV, validateData, detectColumns } from '@variscout/core';\n\n// Types\nimport type {\n StatsResult,\n SpecLimits,\n DataPoint,\n BoxplotSortBy,\n BoxplotSortDirection,\n} from '@variscout/core';\n\n// Boxplot sorting\nimport { sortBoxplotData } from '@variscout/core';\n\n// Glossary\nimport { glossaryTerms, getTerm, hasTerm } from '@variscout/core';\n\n// Navigation\nimport type { DrillLevel, BreadcrumbItem } from '@variscout/core';\n```\n\n### Key Files\n\n| File | Purpose |\n| ------------------- | ------------------------------------------------------------- |\n| `stats/` | Statistics engine (mean, Cp, Cpk, ANOVA) — 13 domain modules |\n| `parser/` | CSV/Excel parsing, validation, keyword detection — submodules |\n| `variation/` | Variation tracking, drill suggestions, simulation |\n| `types.ts` | Shared TypeScript interfaces |\n| `glossary/terms.ts` | Glossary content (~20 terms) |\n\n---\n\n## @variscout/charts\n\n**React + Visx chart components.**\n\n### Key Exports\n\n```typescript\n// Standard charts\nimport { IChart, Boxplot, ParetoChart } from '@variscout/charts';\n\n// Performance charts (multi-channel)\nimport {\n PerformanceIChart,\n PerformanceBoxplot,\n PerformancePareto,\n PerformanceCapability,\n} from '@variscout/charts';\n\n// Theme hook\nimport { useChartTheme } from '@variscout/charts';\n\n// Colors\nimport { chartColors, chromeColors, operatorColors } from '@variscout/charts';\n```\n\n### Component Pattern\n\nAll charts are props-based:\n\n```tsx\n\u003CIChart\n data={measurements}\n specs={{ lsl: 98, usl: 102, target: 100 }}\n stats={calculatedStats}\n showBranding={true}\n/>\n```\n\n---\n\n## @variscout/hooks\n\n**Shared React hooks for state and behavior.**\n\n### Key Exports\n\n```typescript\nimport {\n // State management\n useDataState,\n useDataIngestion,\n useTier,\n\n // Navigation & filtering\n useFilterNavigation,\n useVariationTracking,\n useKeyboardNavigation,\n\n // Chart helpers\n useChartScale,\n useResponsiveChartMargins,\n useBoxplotData,\n useIChartData,\n\n // Chart wrapper data\n useBoxplotWrapperData,\n useIChartWrapperData,\n useParetoChartData,\n useDashboardComputedData,\n\n // Column analysis\n useColumnClassification,\n\n // Analysis state\n useDrillPath,\n useFindings,\n useAnnotations,\n useControlViolations,\n useFocusedChartNav,\n useThemeState,\n\n // UI utilities\n useDataTablePagination,\n useHighlightFade,\n useResizablePanel,\n} from '@variscout/hooks';\n```\n\n### useDataState\n\nCentral state management hook used by both PWA and Azure apps. Returns `[state, actions]` tuple.\n\n**Key DataState properties:**\n\n| Property | Type | Purpose |\n| -------------------- | ---------------------------- | ------------------------------- |\n| `rawData` | `DataRow[]` | Original dataset |\n| `filteredData` | `DataRow[]` | After filter application |\n| `specs` | `SpecLimits` | Global specification limits |\n| `measureSpecs` | `Record\u003Cstring, SpecLimits>` | Per-measure spec overrides |\n| `getSpecsForMeasure` | `(id: string) => SpecLimits` | Get effective specs for measure |\n| `isPerformanceMode` | `boolean` | Multi-measure analysis active |\n| `measureColumns` | `string[]` | Selected measure column names |\n\n**Key DataActions:**\n\n| Action | Purpose |\n| -------------------- | ------------------------------- |\n| `setSpecs` | Set global specification limits |\n| `setMeasureSpecs` | Set all per-measure overrides |\n| `setMeasureSpec` | Update single measure's specs |\n| `setFilters` | Update active filters |\n| `setPerformanceMode` | Toggle Performance Mode |\n\n### Usage Example\n\n```tsx\nconst [state, actions] = useDataState({ persistence: adapter });\n\n// Get specs for a specific measure (returns override or global)\nconst specs = state.getSpecsForMeasure('FillHead_1');\n\n// Set per-measure spec override\nactions.setMeasureSpec('FillHead_1', { usl: 105, lsl: 95 });\n```\n\n---\n\n## @variscout/ui\n\n**Shared UI components and utilities.**\n\n### Key Exports\n\n```typescript\n// Analysis\nimport { AnovaResults, StatsPanelBase, CapabilityHistogram, ProbabilityPlot } from '@variscout/ui';\n\n// Data Input\nimport {\n ColumnMapping,\n MeasureColumnSelector,\n ManualEntryBase,\n ManualEntrySetupBase,\n DataTableBase,\n PerformanceDetectedModal,\n DataQualityBanner,\n} from '@variscout/ui';\n\n// Filtering\nimport { FilterBreadcrumb, FilterChipDropdown, FilterContextBar } from '@variscout/ui';\n\n// Navigation\nimport { VariationBar, FindingsWindow, FindingsLog } from '@variscout/ui';\n\n// Settings\nimport {\n BoxplotDisplayToggle,\n SpecsPopover,\n SpecEditor,\n YAxisPopover,\n AxisEditor,\n FactorSelector,\n} from '@variscout/ui';\n\n// Interaction\nimport {\n Slider,\n WhatIfSimulator,\n WhatIfPageBase,\n SelectionPanel,\n CreateFactorModal,\n} from '@variscout/ui';\n\n// Layout\nimport {\n ChartCard,\n ErrorBoundary,\n UpgradePrompt,\n HelpTooltip,\n PerformanceSetupPanelBase,\n} from '@variscout/ui';\n\n// Hooks & Services\nimport { useGlossary, useIsMobile, errorService } from '@variscout/ui';\n```\n\n---\n\n## @variscout/data\n\n**Sample datasets with pre-computed statistics.**\n\n### Usage\n\n```typescript\nimport { coffeeData, journeyData, bottleneckData } from '@variscout/data';\n\n// Each dataset includes:\n// - Raw data points\n// - Pre-computed stats\n// - Chart-ready data structures\n```\n\n---\n\n## Import Rules\n\n```typescript\n// ✅ Correct: Apps import from packages\nimport { calculateStats } from '@variscout/core';\nimport { IChart } from '@variscout/charts';\n\n// ❌ Wrong: Packages should not import from apps\n// import { Dashboard } from '@variscout/pwa';\n\n// ✅ Correct: Use workspace protocol in package.json\n// \"@variscout/core\": \"workspace:*\"\n```\n\n---\n\n## See Also\n\n- [Monorepo Architecture](monorepo.md)\n- [Charts Package](../../06-design-system/charts/overview.md)", + "src/content/docs/05-technical/architecture/shared-packages.md", + "da0fb08bec6afe02", + { "html": 8265, "metadata": 8266 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"shared-packages\">Shared Packages\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#shared-packages\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Shared Packages”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The monorepo contains several shared packages that provide common functionality across apps.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"package-overview\">Package Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#package-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Package Overview”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Package\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>React?\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/td>\u003Ctd>Statistics, parsing, types\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/td>\u003Ctd>Visx chart components\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003Ctd>Shared React hooks\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>UI components and utilities\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/data\u003C/code>\u003C/td>\u003Ctd>Sample datasets\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscoutcore\">@variscout/core\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutcore\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/core”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Pure logic with no React dependencies.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-exports\">Key Exports\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-exports\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Statistics\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateStats, calculateAnova } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Parsing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { parseCSV, validateData, detectColumns } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Types\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">StatsResult,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">SpecLimits,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">DataPoint,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">BoxplotSortBy,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">BoxplotSortDirection,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Boxplot sorting\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { sortBoxplotData } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Glossary\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { glossaryTerms, getTerm, hasTerm } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Navigation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { DrillLevel, BreadcrumbItem } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Statisticsimport { calculateStats, calculateAnova } from '@variscout/core';// Parsingimport { parseCSV, validateData, detectColumns } from '@variscout/core';// Typesimport type { StatsResult, SpecLimits, DataPoint, BoxplotSortBy, BoxplotSortDirection,} from '@variscout/core';// Boxplot sortingimport { sortBoxplotData } from '@variscout/core';// Glossaryimport { glossaryTerms, getTerm, hasTerm } from '@variscout/core';// Navigationimport type { DrillLevel, BreadcrumbItem } from '@variscout/core';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-files\">Key Files\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-files\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Files”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stats/\u003C/code>\u003C/td>\u003Ctd>Statistics engine (mean, Cp, Cpk, ANOVA) — 13 domain modules\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">parser/\u003C/code>\u003C/td>\u003Ctd>CSV/Excel parsing, validation, keyword detection — submodules\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">variation/\u003C/code>\u003C/td>\u003Ctd>Variation tracking, drill suggestions, simulation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">types.ts\u003C/code>\u003C/td>\u003Ctd>Shared TypeScript interfaces\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">glossary/terms.ts\u003C/code>\u003C/td>\u003Ctd>Glossary content (~20 terms)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscoutcharts\">@variscout/charts\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutcharts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>React + Visx chart components.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-exports-1\">Key Exports\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-exports-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard charts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { IChart, Boxplot, ParetoChart } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Performance charts (multi-channel)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">PerformanceIChart,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">PerformanceBoxplot,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">PerformancePareto,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">PerformanceCapability,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Theme hook\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useChartTheme } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Colors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { chartColors, chromeColors, operatorColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Standard chartsimport { IChart, Boxplot, ParetoChart } from '@variscout/charts';// Performance charts (multi-channel)import { PerformanceIChart, PerformanceBoxplot, PerformancePareto, PerformanceCapability,} from '@variscout/charts';// Theme hookimport { useChartTheme } from '@variscout/charts';// Colorsimport { chartColors, chromeColors, operatorColors } from '@variscout/charts';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"component-pattern\">Component Pattern\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#component-pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Component Pattern”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All charts are props-based:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measurements\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">98\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">102\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, target: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">calculatedStats\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">showBranding\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CIChart data={measurements} specs={{ lsl: 98, usl: 102, target: 100 }} stats={calculatedStats} showBranding={true}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscouthooks\">@variscout/hooks\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscouthooks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/hooks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Shared React hooks for state and behavior.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-exports-2\">Key Exports\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-exports-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// State management\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useDataState,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useDataIngestion,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useTier,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Navigation & filtering\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useFilterNavigation,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useVariationTracking,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useKeyboardNavigation,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart helpers\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useChartScale,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useResponsiveChartMargins,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useBoxplotData,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useIChartData,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart wrapper data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useBoxplotWrapperData,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useIChartWrapperData,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useParetoChartData,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useDashboardComputedData,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Column analysis\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useColumnClassification,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Analysis state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useDrillPath,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useFindings,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useAnnotations,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useControlViolations,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useFocusedChartNav,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useThemeState,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// UI utilities\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useDataTablePagination,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useHighlightFade,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useResizablePanel,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/hooks\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { // State management useDataState, useDataIngestion, useTier, // Navigation & filtering useFilterNavigation, useVariationTracking, useKeyboardNavigation, // Chart helpers useChartScale, useResponsiveChartMargins, useBoxplotData, useIChartData, // Chart wrapper data useBoxplotWrapperData, useIChartWrapperData, useParetoChartData, useDashboardComputedData, // Column analysis useColumnClassification, // Analysis state useDrillPath, useFindings, useAnnotations, useControlViolations, useFocusedChartNav, useThemeState, // UI utilities useDataTablePagination, useHighlightFade, useResizablePanel,} from '@variscout/hooks';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usedatastate\">useDataState\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usedatastate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useDataState”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Central state management hook used by both PWA and Azure apps. Returns \u003Ccode dir=\"auto\">[state, actions]\u003C/code> tuple.\u003C/p>\n\u003Cp>\u003Cstrong>Key DataState properties:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">rawData\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code>\u003C/td>\u003Ctd>Original dataset\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">filteredData\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code>\u003C/td>\u003Ctd>After filter application\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">specs\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">SpecLimits\u003C/code>\u003C/td>\u003Ctd>Global specification limits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">measureSpecs\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Record<string, SpecLimits>\u003C/code>\u003C/td>\u003Ctd>Per-measure spec overrides\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">getSpecsForMeasure\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(id: string) => SpecLimits\u003C/code>\u003C/td>\u003Ctd>Get effective specs for measure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">isPerformanceMode\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">boolean\u003C/code>\u003C/td>\u003Ctd>Multi-measure analysis active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">measureColumns\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string[]\u003C/code>\u003C/td>\u003Ctd>Selected measure column names\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key DataActions:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setSpecs\u003C/code>\u003C/td>\u003Ctd>Set global specification limits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setMeasureSpecs\u003C/code>\u003C/td>\u003Ctd>Set all per-measure overrides\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setMeasureSpec\u003C/code>\u003C/td>\u003Ctd>Update single measure’s specs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setFilters\u003C/code>\u003C/td>\u003Ctd>Update active filters\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">setPerformanceMode\u003C/code>\u003C/td>\u003Ctd>Toggle Performance Mode\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-example\">Usage Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const [\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">actions\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">] = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useDataState\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ persistence: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">adapter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Get specs for a specific measure (returns override or global)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getSpecsForMeasure\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">FillHead_1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Set per-measure spec override\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">actions\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setMeasureSpec\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">FillHead_1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, { usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">105\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">95\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> });\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const [state, actions] = useDataState({ persistence: adapter });// Get specs for a specific measure (returns override or global)const specs = state.getSpecsForMeasure('FillHead_1');// Set per-measure spec overrideactions.setMeasureSpec('FillHead_1', { usl: 105, lsl: 95 });\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscoutui\">@variscout/ui\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutui\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/ui”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Shared UI components and utilities.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-exports-3\">Key Exports\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-exports-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Analysis\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { AnovaResults, StatsPanelBase, CapabilityHistogram, ProbabilityPlot } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Data Input\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ColumnMapping,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">MeasureColumnSelector,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ManualEntryBase,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ManualEntrySetupBase,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">DataTableBase,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">PerformanceDetectedModal,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">DataQualityBanner,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Filtering\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { FilterBreadcrumb, FilterChipDropdown, FilterContextBar } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Navigation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { VariationBar, FindingsWindow, FindingsLog } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Settings\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">BoxplotDisplayToggle,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">SpecsPopover,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">SpecEditor,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">YAxisPopover,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">AxisEditor,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">FactorSelector,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Interaction\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Slider,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">WhatIfSimulator,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">WhatIfPageBase,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">SelectionPanel,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">CreateFactorModal,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Layout\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ChartCard,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ErrorBoundary,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">UpgradePrompt,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">HelpTooltip,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">PerformanceSetupPanelBase,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Hooks & Services\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useGlossary, useIsMobile, errorService } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Analysisimport { AnovaResults, StatsPanelBase, CapabilityHistogram, ProbabilityPlot } from '@variscout/ui';// Data Inputimport { ColumnMapping, MeasureColumnSelector, ManualEntryBase, ManualEntrySetupBase, DataTableBase, PerformanceDetectedModal, DataQualityBanner,} from '@variscout/ui';// Filteringimport { FilterBreadcrumb, FilterChipDropdown, FilterContextBar } from '@variscout/ui';// Navigationimport { VariationBar, FindingsWindow, FindingsLog } from '@variscout/ui';// Settingsimport { BoxplotDisplayToggle, SpecsPopover, SpecEditor, YAxisPopover, AxisEditor, FactorSelector,} from '@variscout/ui';// Interactionimport { Slider, WhatIfSimulator, WhatIfPageBase, SelectionPanel, CreateFactorModal,} from '@variscout/ui';// Layoutimport { ChartCard, ErrorBoundary, UpgradePrompt, HelpTooltip, PerformanceSetupPanelBase,} from '@variscout/ui';// Hooks & Servicesimport { useGlossary, useIsMobile, errorService } from '@variscout/ui';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscoutdata\">@variscout/data\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutdata\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Sample datasets with pre-computed statistics.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage\">Usage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { coffeeData, journeyData, bottleneckData } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/data\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Each dataset includes:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - Raw data points\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - Pre-computed stats\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - Chart-ready data structures\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { coffeeData, journeyData, bottleneckData } from '@variscout/data';// Each dataset includes:// - Raw data points// - Pre-computed stats// - Chart-ready data structures\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"import-rules\">Import Rules\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#import-rules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Import Rules”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ✅ Correct: Apps import from packages\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateStats } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { IChart } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ❌ Wrong: Packages should not import from apps\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// import { Dashboard } from '@variscout/pwa';\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ✅ Correct: Use workspace protocol in package.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// \"@variscout/core\": \"workspace:*\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// ✅ Correct: Apps import from packagesimport { calculateStats } from '@variscout/core';import { IChart } from '@variscout/charts';// ❌ Wrong: Packages should not import from apps// import { Dashboard } from '@variscout/pwa';// ✅ Correct: Use workspace protocol in package.json// "@variscout/core": "workspace:*"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"monorepo.md\">Monorepo Architecture\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/charts/overview.md\">Charts Package\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 8267, + "localImagePaths": 8298, + "remoteImagePaths": 8299, + "frontmatter": 8300, + "imagePaths": 8301 + }, + [ + 8268, 8270, 8271, 8272, 8275, 8278, 8279, 8281, 8284, 8285, 8287, 8288, 8289, 8290, 8292, 8293, + 8294, 8297 + ], + { "depth": 30, "slug": 8269, "text": 8257 }, + "shared-packages", + { "depth": 33, "slug": 251, "text": 252 }, + { "depth": 33, "slug": 254, "text": 255 }, + { "depth": 79, "slug": 8273, "text": 8274 }, + "key-exports", + "Key Exports", + { "depth": 79, "slug": 8276, "text": 8277 }, + "key-files", + "Key Files", + { "depth": 33, "slug": 257, "text": 258 }, + { "depth": 79, "slug": 8280, "text": 8274 }, + "key-exports-1", + { "depth": 79, "slug": 8282, "text": 8283 }, + "component-pattern", + "Component Pattern", + { "depth": 33, "slug": 260, "text": 261 }, + { "depth": 79, "slug": 8286, "text": 8274 }, + "key-exports-2", + { "depth": 79, "slug": 7994, "text": 7995 }, + { "depth": 79, "slug": 3522, "text": 3523 }, + { "depth": 33, "slug": 263, "text": 264 }, + { "depth": 79, "slug": 8291, "text": 8274 }, + "key-exports-3", + { "depth": 33, "slug": 269, "text": 270 }, + { "depth": 79, "slug": 2008, "text": 2009 }, + { "depth": 33, "slug": 8295, "text": 8296 }, + "import-rules", + "Import Rules", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 8257 }, + [], + "05-technical/implementation/azure-testing-plan", + { "id": 8302, "data": 8304, "body": 8309, "filePath": 8310, "digest": 8311, "rendered": 8312 }, + { + "title": 8305, + "editUrl": 16, + "head": 8306, + "template": 18, + "sidebar": 8307, + "pagefind": 16, + "draft": 20 + }, + "Azure App Testing Plan — rdmaic Organization", + [], + { "hidden": 20, "attrs": 8308 }, + {}, + "# Azure App Testing Plan — rdmaic Organization\n\nInternal testing plan for VariScout Azure App before Azure Marketplace submission. Covers browser-based App Service testing and Microsoft Teams tab integration.\n\n**Target environment:** rdmaic Azure subscription\n**App type:** Azure App Service (browser SPA) + Teams personal tab\n**Auth:** EasyAuth (App Service Authentication) with Entra ID\n\n---\n\n## A. Prerequisites Checklist\n\n### Azure Subscription\n\n- [ ] rdmaic Azure subscription active with Contributor access\n- [ ] Azure CLI installed (`az --version`)\n- [ ] Logged in (`az login`)\n\n### Entra ID App Registration\n\nCreate an App Registration before deploying the app. EasyAuth requires customer-provided credentials (Managed Applications cannot create App Registrations in the customer's tenant).\n\n1. **Azure Portal → Entra ID → App registrations → New registration**\n2. **Name:** `VariScout Test`\n3. **Supported account types:** \"Accounts in this organizational directory only\" (single tenant)\n4. **Redirect URI:** Web platform →\n ```\n https://\u003Capp-name>.azurewebsites.net/.auth/login/aad/callback\n ```\n Replace `\u003Capp-name>` with the App Service name you'll use during deployment (e.g., `variscout-test-rdmaic`).\n5. **Register**, then copy the **Application (client) ID**\n\n**API Permissions** (Microsoft Graph → Delegated):\n\n- `User.Read` — sign-in and read user profile (both plans)\n- `Files.ReadWrite.All` — read and write OneDrive + SharePoint files (Team plan only)\n- `Channel.ReadBasic.All` — resolve channel SharePoint drives (Team plan only)\n- `People.Read` — people picker for @mentions (Team plan only)\n- `ChannelMessage.Send` — post findings to Teams channel (Team plan only)\n- Standard plan: only `User.Read` needed, no admin consent required\n- Team plan: admin consent required for `Files.ReadWrite.All`, `Channel.ReadBasic.All`, `ChannelMessage.Send`\n\n**Client Secret:**\n\n1. Certificates & secrets → Client secrets → New client secret\n2. Description: `VariScout EasyAuth Test`\n3. Expiration: 6 months (sufficient for testing)\n4. Copy the secret value immediately — it won't be shown again\n\n### Local Build\n\n```bash\n# Install dependencies\npnpm install\n\n# Build all packages (core, charts, hooks, ui, data) + Azure app\npnpm build\n\n# Verify Azure app built successfully\nls apps/azure/dist/\n```\n\nThe build output at `apps/azure/dist/` is what gets deployed.\n\n---\n\n## B. Deployment Guide\n\nTwo approaches: ARM template (mirrors Marketplace flow) or direct zip deploy (simpler for testing).\n\n### Option 1: Direct Zip Deploy (recommended for testing)\n\nSimpler setup — deploys the built app directly to App Service without the full ARM template.\n\n```bash\n# 1. Create resource group\naz group create \\\n --name rg-variscout-test \\\n --location westeurope\n\n# 2. Create App Service Plan (B1 is sufficient for testing)\naz appservice plan create \\\n --name variscout-test-plan \\\n --resource-group rg-variscout-test \\\n --sku B1 \\\n --is-linux\n\n# 3. Create Web App\naz webapp create \\\n --name variscout-test-rdmaic \\\n --resource-group rg-variscout-test \\\n --plan variscout-test-plan \\\n --runtime \"NODE|22-lts\"\n\n# 4. Configure app settings\naz webapp config appsettings set \\\n --name variscout-test-rdmaic \\\n --resource-group rg-variscout-test \\\n --settings \\\n VITE_LICENSE_TIER=\"enterprise\" \\\n VITE_VARISCOUT_PLAN=\"team\" \\\n SCM_DO_BUILD_DURING_DEPLOYMENT=\"false\"\n\n# 5. Set startup command (Node server.js, not PM2)\naz webapp config set \\\n --name variscout-test-rdmaic \\\n --resource-group rg-variscout-test \\\n --startup-file \"node server.js\"\n\n# 6. Configure EasyAuth (authsettingsV2)\n# Store the client secret as an app setting first\naz webapp config appsettings set \\\n --name variscout-test-rdmaic \\\n --resource-group rg-variscout-test \\\n --settings MICROSOFT_PROVIDER_AUTHENTICATION_SECRET=\"\u003CYOUR_CLIENT_SECRET>\"\n\n# Then configure authsettingsV2 via REST API (most reliable method)\naz rest --method PUT \\\n --uri \"/subscriptions/{subscriptionId}/resourceGroups/rg-variscout-test/providers/Microsoft.Web/sites/variscout-test-rdmaic/config/authsettingsV2?api-version=2024-04-01\" \\\n --body '{\n \"properties\": {\n \"platform\": { \"enabled\": true },\n \"globalValidation\": {\n \"requireAuthentication\": true,\n \"unauthenticatedClientAction\": \"RedirectToLoginPage\",\n \"redirectToProvider\": \"azureactivedirectory\",\n \"excludedPaths\": [\"/health\"]\n },\n \"identityProviders\": {\n \"azureActiveDirectory\": {\n \"enabled\": true,\n \"registration\": {\n \"openIdIssuer\": \"https://login.microsoftonline.com/\u003CYOUR_TENANT_ID>/v2.0\",\n \"clientId\": \"\u003CYOUR_CLIENT_ID>\",\n \"clientSecretSettingName\": \"MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\"\n },\n \"login\": {\n \"loginParameters\": [\"scope=openid profile email User.Read Files.ReadWrite Files.ReadWrite.All Channel.ReadBasic.All People.Read ChannelMessage.Send\"]\n }\n }\n },\n \"login\": {\n \"tokenStore\": { \"enabled\": true }\n }\n }\n }'\n\n# 7. Build, package, and deploy\n# Package must include server.js + package.json (not just dist/)\nmkdir -p deploy/dist\ncp -r apps/azure/dist/* deploy/dist/\ncp apps/azure/server.js deploy/server.js\necho '{\"type\":\"module\",\"scripts\":{\"start\":\"node server.js\"}}' > deploy/package.json\ncd deploy && zip -r ../variscout-azure.zip . && cd ..\n\naz webapp deploy \\\n --name variscout-test-rdmaic \\\n --resource-group rg-variscout-test \\\n --src-path variscout-azure.zip \\\n --type zip\n\n# Cleanup\nrm -rf deploy variscout-azure.zip\n```\n\n### Option 2: ARM Template Deploy (mirrors Marketplace)\n\nUses `infra/mainTemplate.json` — tests the actual deployment experience customers will have.\n\n```bash\n# 1. Create resource group\naz group create \\\n --name rg-variscout-test \\\n --location westeurope\n\n# 2. Build the deployment zip (server.js + package.json + dist/)\nmkdir -p deploy/dist\ncp -r apps/azure/dist/* deploy/dist/\ncp apps/azure/server.js deploy/server.js\necho '{\"type\":\"module\",\"scripts\":{\"start\":\"node server.js\"}}' > deploy/package.json\ncd deploy && zip -r ../variscout-azure.zip . && cd ..\n\n# 3. Upload the zip to a storage account\n# The ARM template expects a publicly accessible URL for WEBSITE_RUN_FROM_PACKAGE\naz storage account create \\\n --name variscoutreleases \\\n --resource-group rg-variscout-test \\\n --sku Standard_LRS\n\naz storage container create \\\n --name releases \\\n --account-name variscoutreleases \\\n --public-access blob\n\naz storage blob upload \\\n --account-name variscoutreleases \\\n --container-name releases \\\n --name variscout-azure-test.zip \\\n --file variscout-azure.zip\n\n# 4. Deploy ARM template\naz deployment group create \\\n --resource-group rg-variscout-test \\\n --template-file infra/mainTemplate.json \\\n --parameters \\\n appName=\"variscout-test-rdmaic\" \\\n variscoutPlan=\"team\" \\\n clientId=\"\u003CYOUR_CLIENT_ID>\" \\\n clientSecret=\"\u003CYOUR_CLIENT_SECRET>\" \\\n packageUrl=\"https://variscoutreleases.blob.core.windows.net/releases/variscout-azure-test.zip\"\n```\n\n### Verify Deployment\n\n1. Visit `https://variscout-test-rdmaic.azurewebsites.net`\n2. Expected: redirect to Entra ID login\n3. After sign-in: app loads with empty state (no data)\n4. Check header shows authenticated user name\n\n---\n\n## C. Browser Test Scenarios (Standalone)\n\nTest the app at `https://\u003Capp-name>.azurewebsites.net` in a desktop browser.\n\n| # | Scenario | Steps | What to Record |\n| --- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |\n| 1 | **Authentication** | Visit app URL → redirected to Entra ID → sign in → see user name in header | Redirect speed, error messages, user display name correctness |\n| 2 | **Sample data loading** | Click a sample dataset in the empty-state Editor → charts render | Load time, chart correctness, all 4 chart types visible |\n| 3 | **Paste data input** | Editor → Add Data → Paste → paste CSV text → column mapping → analysis | Tab/comma detection accuracy, column type detection, mapping UX |\n| 4 | **File upload (CSV)** | Editor → Add Data → Upload File → select CSV → column mapping → analysis | Parse correctness, column detection, large file handling (try 10K+ rows) |\n| 5 | **Manual entry** | Editor → Add Data → Manual Entry → create columns → add rows → analyze | Input UX, validation feedback, performance mode toggle |\n| 6 | **I-Chart analysis** | Load data with spec limits → verify control limits, Nelson rule markers, dot colors | Blue=in-control, red=violation, correct UCL/LCL, Nelson sequence overlays |\n| 7 | **Boxplot analysis** | Drill by category factor → verify groups, toggle violin mode, try sorting (name/mean/spread), contribution labels | Visual quality, violin overlay, sort correctness, contribution % labels |\n| 8 | **Pareto analysis** | Verify Cpk ranking chart → click bar to drill into channel | Chart readability, bar ordering (worst first), drill interaction |\n| 9 | **Capability (Cp/Cpk)** | Set spec limits via SpecEditor popover → verify histogram + probability plot | SpecEditor UX, Cp/Cpk calculation correctness |\n| 10 | **ANOVA results** | Drill by factor → check F-statistic, p-value, η² in ANOVA panel | Statistical accuracy (spot-check against known dataset values) |\n| 11 | **Performance Mode** | Load multi-column CSV → PerformanceSetupPanel → select measures → Cpk scatter, boxplot, Pareto | Column detection, measure selection, channel drill navigation |\n| 12 | **Filter navigation** | Apply factor filters → verify breadcrumbs → navigate back → apply multi-select | Filter chips display, variation % contribution, back navigation, cumulative scope |\n| 13 | **Findings panel** | Open findings panel → pin observation from chart → change status (observed→investigating→analyzed) → add comment → What-If | Findings list rendering, status transitions, comment persistence, What-If slider |\n| 14 | **OneDrive sync** | Save project → check OneDrive/VariScout/Projects folder → close tab → reopen → verify data loads | Sync speed, file appears in OneDrive, data persists across sessions |\n| 15 | **Theme switching** | Settings → toggle dark/light/system → verify all views adapt | Color consistency across charts, panels, editor; chrome color adaptation |\n| 16 | **Chart export** | Copy chart to clipboard → paste in document; download PNG; download SVG | Export quality, correct dimensions (see chart export sizes), branding hidden (paid tier) |\n| 17 | **Settings persistence** | Change display options (Y-axis lock, show specs, chart text size) → reload → verify retained | localStorage reliability, all toggle states restored |\n| 18 | **Factor management** | Click \"Factors\" in nav bar → ColumnMapping opens in edit mode → add/remove factor → Apply → verify filter cleanup | State consistency, orphaned filters cleaned, cancel preserves data |\n| 19 | **Data table editing** | Open data table → edit cell values → verify charts update | Inline editing UX, bi-directional sync, undo behavior |\n| 20 | **Chart annotations** | Right-click boxplot/Pareto → highlight + add note; right-click I-Chart → add free-floating note | Context menu positioning, annotation persistence, drag-to-reposition |\n| 21 | **CSV export** | Editor header → export CSV → open in Excel | Data completeness, column ordering, encoding (UTF-8 with special characters) |\n| 22 | **Editable chart titles** | Click chart title → edit text → verify persistence | Inline editing UX, title saved across sessions |\n| 23 | **Presentation mode** | Enter presentation mode → full-screen chart overlay → navigate charts | Full-screen rendering, keyboard navigation, exit behavior |\n\n---\n\n## D. Teams Test Scenarios\n\n### Prerequisite: Generate and Upload Manifest\n\nThe Azure app includes an admin page (`AdminTeamsSetup.tsx`) that generates a Teams manifest `.zip` file containing the app configuration and icons.\n\n| # | Scenario | Steps | What to Record |\n| --- | -------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |\n| 1 | **Generate manifest** | Navigate to admin/Teams setup page → download `.zip` → inspect contents (manifest.json, icons) | Manifest correctness, icon presence (color + outline), app ID matches |\n| 2 | **Upload to Teams** | Teams Admin Center → Manage apps → Upload → select the `.zip` → verify app appears in catalog | Upload process, any validation errors, app listing appearance |\n| 3 | **Open in Teams** | Teams → Apps → Built for your org → open VariScout as personal tab | Load time, iframe rendering, no console errors |\n| 4 | **Auth in Teams** | First open → expect login redirect to `*.azurewebsites.net` → sign in via Entra ID | SSO behavior (note: `*.azurewebsites.net` domains require one-time redirect, no seamless SSO), redirect UX |\n| 5 | **Full workflow in Teams** | Load sample → drill by factor → set specs → export chart | Iframe constraints, scrolling behavior, popup/modal rendering |\n| 6 | **Responsive in Teams** | Resize Teams window → check chart responsiveness → try narrow sidebar mode | Layout adaptation, breakpoints, chart readability at small sizes |\n| 7 | **Findings popout** | Open findings panel → click popout to new window | `window.open` behavior in Teams (may be blocked), fallback behavior |\n| 8 | **OneDrive sync in Teams** | Save project in Teams tab → verify appears in OneDrive | Same Graph API flow as standalone, verify token available |\n\n---\n\n## E. Evaluation Template\n\nFill this form during and after testing. Rate items 1–5 (1=poor, 5=excellent) where applicable.\n\n### Deployment Experience\n\n| Criterion | Rating / Answer |\n| --------------------------------------- | --------------- |\n| Time to deploy (minutes) | |\n| Clarity of deployment instructions | /5 |\n| Issues encountered | |\n| App Registration creation ease | /5 |\n| ARM template deploy success (if tested) | yes / no |\n| Portal wizard usability (if tested) | /5 |\n\n### Authentication & Security\n\n| Criterion | Rating / Answer |\n| --------------------------------------------------------------- | --------------- |\n| Login flow smoothness | /5 |\n| Token refresh behavior (any interruptions during long session?) | |\n| Logout → re-login works cleanly? | yes / no |\n| User display name correct in header? | yes / no |\n| Auth error messages clear? | /5 |\n\n### Core Analysis Quality\n\n| Criterion | Rating / Answer |\n| ---------------------------------------------------------------------- | --------------- |\n| Statistical correctness (spot-check Cpk, mean, σ against known values) | /5 |\n| Chart visual quality | /5 |\n| Interactivity responsiveness (hover, click, drill) | /5 |\n| Performance with larger datasets (10K+ rows) | /5 |\n| Nelson rule detection accuracy | /5 |\n| ANOVA results match expectations? | yes / no |\n\n### Data Input\n\n| Criterion | Rating / Answer |\n| ------------------------------------------------ | --------------- |\n| Paste data detection accuracy (tab vs comma) | /5 |\n| File upload reliability | /5 |\n| Column type detection (numeric/categorical/date) | /5 |\n| Manual entry UX | /5 |\n| Add Data dropdown clarity | /5 |\n| Data merge behavior (append vs replace) | /5 |\n\n### OneDrive Sync\n\n| Criterion | Rating / Answer |\n| ------------------------------------------------ | --------------- |\n| Save reliability | /5 |\n| Load reliability (data persists across sessions) | /5 |\n| Offline → online sync behavior | |\n| Error messages clarity | /5 |\n| Sync speed | |\n| File visible in OneDrive folder? | yes / no |\n\n### Teams Integration\n\n| Criterion | Rating / Answer |\n| -------------------------------------- | --------------- |\n| Manifest generation works? | yes / no |\n| Upload to Teams Admin Center | /5 |\n| App renders correctly in Teams iframe? | yes / no |\n| Auth flow in Teams | /5 |\n| Any iframe-specific issues? | |\n| Popout windows work (findings)? | yes / no |\n| Scrolling behavior in Teams | /5 |\n\n### Accessibility\n\n| Criterion | Rating / Answer |\n| ----------------------------------------------------------- | --------------- |\n| Keyboard navigation works? (Tab, Enter, Escape, Arrow keys) | yes / no |\n| Skip link functional? | yes / no |\n| Screen reader announcements (ARIA live regions)? | yes / no |\n| Color contrast sufficient (light + dark themes)? | yes / no |\n| Focus indicators visible? | yes / no |\n\n### Overall Assessment\n\n| Criterion | Rating / Answer |\n| -------------------------------------------------- | ------------------------------ |\n| Missing features for real-world use | |\n| Bugs found | |\n| Comparison to PWA experience (what's better/worse) | |\n| Would you use this daily? | /5 |\n| Top 3 suggested improvements | |\n| Marketplace readiness assessment | ready / needs work / not ready |\n\n---\n\n## F. Known Limitations\n\nDocument these with testers so they don't report them as bugs:\n\n| Limitation | Detail | Workaround / Timeline |\n| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |\n| **Teams SSO** | `*.azurewebsites.net` domains don't support seamless Teams SSO. Users see a one-time login redirect. | Custom domain needed for seamless SSO. Not blocking for testing. |\n| **Storage scope** | Standard plan: local files only (no cloud sync). Team plan: OneDrive personal + SharePoint channel storage. | Standard needs only `User.Read`. Team needs `Files.ReadWrite.All` + `Channel.ReadBasic.All`. |\n| **Local dev** | Graph API unavailable on localhost. Auth returns mock user, OneDrive sync is no-op. | Expected behavior per `easyAuth.ts` — test sync only on deployed instance. |\n| **Admin consent** | `User.Read` + `Files.ReadWrite` don't require admin consent by default, but org Entra ID policies may block user consent. | If blocked, tenant admin grants consent via App Registration → API permissions → Grant admin consent. |\n| **Performance Mode in PWA** | PWA detection modal shows \"available in Azure App\" — Performance Mode is Azure-only. | Expected behavior — PWA is free tier. |\n| **Client secret expiration** | Test secret expires based on chosen duration. Production deployments should use 24-month secrets. | Set calendar reminder to rotate before expiration. |\n\n---\n\n## G. Test Data Recommendations\n\n### Built-in Samples\n\nThe app ships with sample datasets (via `@variscout/data`). Use these for initial smoke testing:\n\n- **Coffee** — extraction temperature with spec limits, good for capability analysis\n- **Journey** — multi-factor dataset, good for drill-down and ANOVA\n- **Bottleneck** — multi-channel data, good for Performance Mode testing\n- **Sachets** — packaging weights, good for Nelson rule testing\n\n### Custom Test Data\n\nFor thorough testing, prepare CSV files that exercise edge cases:\n\n| Test File | Purpose | Characteristics |\n| -------------------- | ------------------- | --------------------------------------------- |\n| `large-dataset.csv` | Performance testing | 10,000+ rows, 3 factors, 1 measure |\n| `multi-measure.csv` | Performance Mode | 5+ numeric columns (fill heads / cavities) |\n| `unicode-data.csv` | Encoding | Column names with ÄÖÅ, accented characters |\n| `missing-values.csv` | Validation | Rows with blank cells, mixed types |\n| `single-value.csv` | Edge case | All measurements identical (σ=0) |\n| `two-rows.csv` | Minimum data | Just 2 data points (control limits undefined) |\n\n---\n\n## H. Cleanup\n\nAfter testing is complete:\n\n```bash\n# Delete the test resource group (removes all resources)\naz group delete --name rg-variscout-test --yes --no-wait\n\n# Delete the App Registration (Azure Portal)\n# Entra ID → App registrations → VariScout Test → Delete\n```\n\n---\n\n## I. Automated E2E Coverage\n\nThe Azure app has 9 Playwright spec files in `apps/azure/e2e/` plus a shared helper module:\n\n| File | Covers Scenarios |\n| -------------------------- | ----------------------------------------------------------------------------- |\n| `helpers.ts` | Shared: `confirmColumnMapping`, `loadSampleInEditor`, `loadPerformanceSample` |\n| `editor-workflow.spec.ts` | C-1 (auth mock), C-2 (sample load), C-12 (filter drill) |\n| `samples.spec.ts` | C-2 (all sample datasets), C-6 (I-Chart), C-7 (Boxplot) |\n| `analysis-views.spec.ts` | C-6 (I-Chart), C-7 (Boxplot), C-8 (Pareto) |\n| `stats-anova.spec.ts` | C-9 (Cp/Cpk), C-10 (ANOVA) |\n| `user-flows.spec.ts` | C-3 (paste), C-12 (filter navigation), multi-step workflows |\n| `edge-cases.spec.ts` | Boundary conditions, empty states, error handling |\n| `editor-features.spec.ts` | C-13 (findings), C-19 (data table), C-21 (CSV export), C-22 (chart titles) |\n| `performance-mode.spec.ts` | C-11 (Performance Mode), Cp/Cpk toggle, spec limits |\n| `settings-theme.spec.ts` | C-15 (theme switching), C-17 (settings persistence) |\n\n**Not covered by automation** (require deployed Azure environment):\n\n- C-1 live auth (EasyAuth redirect — mocked in Playwright)\n- C-14 OneDrive sync (requires Graph API token)\n- C-23 Presentation mode (partial — visual verification needed)\n- All section D (Teams integration — requires Teams Admin Center)\n\n**ANOVA check clarification:** ANOVA results (`[data-testid=\"anova-results\"]`) are only visible in FocusedChartView (boxplot focused view). Tests must first maximize the boxplot card to reach this view.\n\n```bash\n# Run all Azure E2E tests\npnpm --filter @variscout/azure-app test:e2e\n```\n\n---\n\n## Related Documentation\n\n- [ARM Template Documentation](../../08-products/azure/arm-template.md) — template parameters and App Registration setup\n- [Authentication (EasyAuth)](../../08-products/azure/authentication.md) — auth flow, endpoints, token management\n- [OneDrive Sync](../../08-products/azure/onedrive-sync.md) — sync architecture and storage structure\n- [Marketplace Submission Checklist](../../08-products/azure/submission-checklist.md) — full submission tracker\n- [Deployment Guide](deployment.md) — build commands and deployment workflows\n- [ADR-007: Azure Marketplace Distribution](../../07-decisions/adr-007-azure-marketplace-distribution.md) — distribution strategy", + "src/content/docs/05-technical/implementation/azure-testing-plan.md", + "d6c32cf750efe369", + { "html": 8313, "metadata": 8314 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"azure-app-testing-plan--rdmaic-organization\">Azure App Testing Plan — rdmaic Organization\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-testing-plan--rdmaic-organization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App Testing Plan — rdmaic Organization”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Internal testing plan for VariScout Azure App before Azure Marketplace submission. Covers browser-based App Service testing and Microsoft Teams tab integration.\u003C/p>\n\u003Cp>\u003Cstrong>Target environment:\u003C/strong> rdmaic Azure subscription\n\u003Cstrong>App type:\u003C/strong> Azure App Service (browser SPA) + Teams personal tab\n\u003Cstrong>Auth:\u003C/strong> EasyAuth (App Service Authentication) with Entra ID\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"a-prerequisites-checklist\">A. Prerequisites Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#a-prerequisites-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “A. Prerequisites Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-subscription\">Azure Subscription\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-subscription\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Subscription”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> rdmaic Azure subscription active with Contributor access\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Azure CLI installed (\u003Ccode dir=\"auto\">az --version\u003C/code>)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Logged in (\u003Ccode dir=\"auto\">az login\u003C/code>)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"entra-id-app-registration\">Entra ID App Registration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#entra-id-app-registration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Entra ID App Registration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Create an App Registration before deploying the app. EasyAuth requires customer-provided credentials (Managed Applications cannot create App Registrations in the customer’s tenant).\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Azure Portal → Entra ID → App registrations → New registration\u003C/strong>\u003C/li>\n\u003Cli>\u003Cstrong>Name:\u003C/strong> \u003Ccode dir=\"auto\">VariScout Test\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Supported account types:\u003C/strong> “Accounts in this organizational directory only” (single tenant)\u003C/li>\n\u003Cli>\u003Cstrong>Redirect URI:\u003C/strong> Web platform →\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">https://<app-name>.azurewebsites.net/.auth/login/aad/callback\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"https://\u003Capp-name>.azurewebsites.net/.auth/login/aad/callback\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\nReplace \u003Ccode dir=\"auto\"><app-name>\u003C/code> with the App Service name you’ll use during deployment (e.g., \u003Ccode dir=\"auto\">variscout-test-rdmaic\u003C/code>).\u003C/li>\n\u003Cli>\u003Cstrong>Register\u003C/strong>, then copy the \u003Cstrong>Application (client) ID\u003C/strong>\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>API Permissions\u003C/strong> (Microsoft Graph → Delegated):\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">User.Read\u003C/code> — sign-in and read user profile (both plans)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> — read and write OneDrive + SharePoint files (Team plan only)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code> — resolve channel SharePoint drives (Team plan only)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">People.Read\u003C/code> — people picker for @mentions (Team plan only)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">ChannelMessage.Send\u003C/code> — post findings to Teams channel (Team plan only)\u003C/li>\n\u003Cli>Standard plan: only \u003Ccode dir=\"auto\">User.Read\u003C/code> needed, no admin consent required\u003C/li>\n\u003Cli>Team plan: admin consent required for \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>, \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>, \u003Ccode dir=\"auto\">ChannelMessage.Send\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Client Secret:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Certificates & secrets → Client secrets → New client secret\u003C/li>\n\u003Cli>Description: \u003Ccode dir=\"auto\">VariScout EasyAuth Test\u003C/code>\u003C/li>\n\u003Cli>Expiration: 6 months (sufficient for testing)\u003C/li>\n\u003Cli>Copy the secret value immediately — it won’t be shown again\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"local-build\">Local Build\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#local-build\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Local Build”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Install dependencies\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">install\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build all packages (core, charts, hooks, ui, data) + Azure app\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Verify Azure app built successfully\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">ls\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">apps/azure/dist/\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm installpnpm buildls apps/azure/dist/\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The build output at \u003Ccode dir=\"auto\">apps/azure/dist/\u003C/code> is what gets deployed.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"b-deployment-guide\">B. Deployment Guide\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#b-deployment-guide\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “B. Deployment Guide”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Two approaches: ARM template (mirrors Marketplace flow) or direct zip deploy (simpler for testing).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"option-1-direct-zip-deploy-recommended-for-testing\">Option 1: Direct Zip Deploy (recommended for testing)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#option-1-direct-zip-deploy-recommended-for-testing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Option 1: Direct Zip Deploy (recommended for testing)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Simpler setup — deploys the built app directly to App Service without the full ARM template.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 1. Create resource group\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--location\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">westeurope\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 2. Create App Service Plan (B1 is sufficient for testing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">appservice\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">plan\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-test-plan\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--sku\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">B1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--is-linux\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 3. Create Web App\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">webapp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-test-rdmaic\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--plan\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-test-plan\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--runtime\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">NODE|22-lts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 4. Configure app settings\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">webapp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">config\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">appsettings\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-test-rdmaic\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--settings\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">VITE_LICENSE_TIER=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">enterprise\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">VITE_VARISCOUT_PLAN=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">team\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">SCM_DO_BUILD_DURING_DEPLOYMENT=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">false\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 5. Set startup command (Node server.js, not PM2)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">webapp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">config\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-test-rdmaic\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--startup-file\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">node server.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 6. Configure EasyAuth (authsettingsV2)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Store the client secret as an app setting first\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">webapp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">config\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">appsettings\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-test-rdmaic\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--settings\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">MICROSOFT_PROVIDER_AUTHENTICATION_SECRET=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"><YOUR_CLIENT_SECRET>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Then configure authsettingsV2 via REST API (most reliable method)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--method\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">PUT\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--uri\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">/subscriptions/{subscriptionId}/resourceGroups/rg-variscout-test/providers/Microsoft.Web/sites/variscout-test-rdmaic/config/authsettingsV2?api-version=2024-04-01\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--body\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"properties\": {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"platform\": { \"enabled\": true },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"globalValidation\": {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"requireAuthentication\": true,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"unauthenticatedClientAction\": \"RedirectToLoginPage\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"redirectToProvider\": \"azureactivedirectory\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"excludedPaths\": [\"/health\"]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"identityProviders\": {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"azureActiveDirectory\": {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"enabled\": true,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"registration\": {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"openIdIssuer\": \"https://login.microsoftonline.com/<YOUR_TENANT_ID>/v2.0\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"clientId\": \"<YOUR_CLIENT_ID>\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"clientSecretSettingName\": \"MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"login\": {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"loginParameters\": [\"scope=openid profile email User.Read Files.ReadWrite Files.ReadWrite.All Channel.ReadBasic.All People.Read ChannelMessage.Send\"]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"login\": {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"tokenStore\": { \"enabled\": true }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 7. Build, package, and deploy\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Package must include server.js + package.json (not just dist/)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mkdir\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-p\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy/dist\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-r\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">apps/azure/dist/\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy/dist/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">apps/azure/server.js\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy/server.js\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">echo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">{\"type\":\"module\",\"scripts\":{\"start\":\"node server.js\"}}\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy/package.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">cd\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> && \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">zip\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-r\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">../variscout-azure.zip\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> && \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">cd\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">..\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">webapp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-test-rdmaic\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--src-path\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-azure.zip\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">zip\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Cleanup\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">rm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-rf\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-azure.zip\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az group create \\ --name rg-variscout-test \\ --location westeuropeaz appservice plan create \\ --name variscout-test-plan \\ --resource-group rg-variscout-test \\ --sku B1 \\ --is-linuxaz webapp create \\ --name variscout-test-rdmaic \\ --resource-group rg-variscout-test \\ --plan variscout-test-plan \\ --runtime "NODE|22-lts"az webapp config appsettings set \\ --name variscout-test-rdmaic \\ --resource-group rg-variscout-test \\ --settings \\ VITE_LICENSE_TIER="enterprise" \\ VITE_VARISCOUT_PLAN="team" \\ SCM_DO_BUILD_DURING_DEPLOYMENT="false"az webapp config set \\ --name variscout-test-rdmaic \\ --resource-group rg-variscout-test \\ --startup-file "node server.js"az webapp config appsettings set \\ --name variscout-test-rdmaic \\ --resource-group rg-variscout-test \\ --settings MICROSOFT_PROVIDER_AUTHENTICATION_SECRET="\u003CYOUR_CLIENT_SECRET>"az rest --method PUT \\ --uri "/subscriptions/{subscriptionId}/resourceGroups/rg-variscout-test/providers/Microsoft.Web/sites/variscout-test-rdmaic/config/authsettingsV2?api-version=2024-04-01" \\ --body '{ "properties": { "platform": { "enabled": true }, "globalValidation": { "requireAuthentication": true, "unauthenticatedClientAction": "RedirectToLoginPage", "redirectToProvider": "azureactivedirectory", "excludedPaths": ["/health"] }, "identityProviders": { "azureActiveDirectory": { "enabled": true, "registration": { "openIdIssuer": "https://login.microsoftonline.com/\u003CYOUR_TENANT_ID>/v2.0", "clientId": "\u003CYOUR_CLIENT_ID>", "clientSecretSettingName": "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET" }, "login": { "loginParameters": ["scope=openid profile email User.Read Files.ReadWrite Files.ReadWrite.All Channel.ReadBasic.All People.Read ChannelMessage.Send"] } } }, "login": { "tokenStore": { "enabled": true } } } }'mkdir -p deploy/distcp -r apps/azure/dist/* deploy/dist/cp apps/azure/server.js deploy/server.jsecho '{"type":"module","scripts":{"start":"node server.js"}}' > deploy/package.jsoncd deploy && zip -r ../variscout-azure.zip . && cd ..az webapp deploy \\ --name variscout-test-rdmaic \\ --resource-group rg-variscout-test \\ --src-path variscout-azure.zip \\ --type ziprm -rf deploy variscout-azure.zip\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"option-2-arm-template-deploy-mirrors-marketplace\">Option 2: ARM Template Deploy (mirrors Marketplace)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#option-2-arm-template-deploy-mirrors-marketplace\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Option 2: ARM Template Deploy (mirrors Marketplace)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Uses \u003Ccode dir=\"auto\">infra/mainTemplate.json\u003C/code> — tests the actual deployment experience customers will have.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 1. Create resource group\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--location\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">westeurope\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 2. Build the deployment zip (server.js + package.json + dist/)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mkdir\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-p\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy/dist\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-r\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">apps/azure/dist/\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy/dist/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">cp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">apps/azure/server.js\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy/server.js\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">echo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">{\"type\":\"module\",\"scripts\":{\"start\":\"node server.js\"}}\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy/package.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">cd\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deploy\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> && \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">zip\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-r\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">../variscout-azure.zip\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> && \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">cd\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">..\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 3. Upload the zip to a storage account\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># The ARM template expects a publicly accessible URL for WEBSITE_RUN_FROM_PACKAGE\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">storage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">account\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscoutreleases\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--sku\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Standard_LRS\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">storage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">container\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">releases\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--account-name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscoutreleases\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--public-access\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">blob\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">storage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">blob\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">upload\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--account-name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscoutreleases\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--container-name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">releases\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-azure-test.zip\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--file\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-azure.zip\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># 4. Deploy ARM template\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deployment\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--template-file\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">infra/mainTemplate.json\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--parameters\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">appName=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">variscout-test-rdmaic\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscoutPlan=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">team\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">clientId=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"><YOUR_CLIENT_ID>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">clientSecret=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"><YOUR_CLIENT_SECRET>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">packageUrl=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://variscoutreleases.blob.core.windows.net/releases/variscout-azure-test.zip\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az group create \\ --name rg-variscout-test \\ --location westeuropemkdir -p deploy/distcp -r apps/azure/dist/* deploy/dist/cp apps/azure/server.js deploy/server.jsecho '{"type":"module","scripts":{"start":"node server.js"}}' > deploy/package.jsoncd deploy && zip -r ../variscout-azure.zip . && cd ..az storage account create \\ --name variscoutreleases \\ --resource-group rg-variscout-test \\ --sku Standard_LRSaz storage container create \\ --name releases \\ --account-name variscoutreleases \\ --public-access blobaz storage blob upload \\ --account-name variscoutreleases \\ --container-name releases \\ --name variscout-azure-test.zip \\ --file variscout-azure.zipaz deployment group create \\ --resource-group rg-variscout-test \\ --template-file infra/mainTemplate.json \\ --parameters \\ appName="variscout-test-rdmaic" \\ variscoutPlan="team" \\ clientId="\u003CYOUR_CLIENT_ID>" \\ clientSecret="\u003CYOUR_CLIENT_SECRET>" \\ packageUrl="https://variscoutreleases.blob.core.windows.net/releases/variscout-azure-test.zip"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"verify-deployment\">Verify Deployment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#verify-deployment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Verify Deployment”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Visit \u003Ccode dir=\"auto\">https://variscout-test-rdmaic.azurewebsites.net\u003C/code>\u003C/li>\n\u003Cli>Expected: redirect to Entra ID login\u003C/li>\n\u003Cli>After sign-in: app loads with empty state (no data)\u003C/li>\n\u003Cli>Check header shows authenticated user name\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"c-browser-test-scenarios-standalone\">C. Browser Test Scenarios (Standalone)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#c-browser-test-scenarios-standalone\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “C. Browser Test Scenarios (Standalone)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Test the app at \u003Ccode dir=\"auto\">https://<app-name>.azurewebsites.net\u003C/code> in a desktop browser.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Scenario\u003C/th>\u003Cth>Steps\u003C/th>\u003Cth>What to Record\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>\u003Cstrong>Authentication\u003C/strong>\u003C/td>\u003Ctd>Visit app URL → redirected to Entra ID → sign in → see user name in header\u003C/td>\u003Ctd>Redirect speed, error messages, user display name correctness\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>\u003Cstrong>Sample data loading\u003C/strong>\u003C/td>\u003Ctd>Click a sample dataset in the empty-state Editor → charts render\u003C/td>\u003Ctd>Load time, chart correctness, all 4 chart types visible\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>\u003Cstrong>Paste data input\u003C/strong>\u003C/td>\u003Ctd>Editor → Add Data → Paste → paste CSV text → column mapping → analysis\u003C/td>\u003Ctd>Tab/comma detection accuracy, column type detection, mapping UX\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>\u003Cstrong>File upload (CSV)\u003C/strong>\u003C/td>\u003Ctd>Editor → Add Data → Upload File → select CSV → column mapping → analysis\u003C/td>\u003Ctd>Parse correctness, column detection, large file handling (try 10K+ rows)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>\u003Cstrong>Manual entry\u003C/strong>\u003C/td>\u003Ctd>Editor → Add Data → Manual Entry → create columns → add rows → analyze\u003C/td>\u003Ctd>Input UX, validation feedback, performance mode toggle\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>\u003Cstrong>I-Chart analysis\u003C/strong>\u003C/td>\u003Ctd>Load data with spec limits → verify control limits, Nelson rule markers, dot colors\u003C/td>\u003Ctd>Blue=in-control, red=violation, correct UCL/LCL, Nelson sequence overlays\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>\u003Cstrong>Boxplot analysis\u003C/strong>\u003C/td>\u003Ctd>Drill by category factor → verify groups, toggle violin mode, try sorting (name/mean/spread), contribution labels\u003C/td>\u003Ctd>Visual quality, violin overlay, sort correctness, contribution % labels\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>\u003Cstrong>Pareto analysis\u003C/strong>\u003C/td>\u003Ctd>Verify Cpk ranking chart → click bar to drill into channel\u003C/td>\u003Ctd>Chart readability, bar ordering (worst first), drill interaction\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>\u003Cstrong>Capability (Cp/Cpk)\u003C/strong>\u003C/td>\u003Ctd>Set spec limits via SpecEditor popover → verify histogram + probability plot\u003C/td>\u003Ctd>SpecEditor UX, Cp/Cpk calculation correctness\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>\u003Cstrong>ANOVA results\u003C/strong>\u003C/td>\u003Ctd>Drill by factor → check F-statistic, p-value, η² in ANOVA panel\u003C/td>\u003Ctd>Statistical accuracy (spot-check against known dataset values)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>\u003Cstrong>Performance Mode\u003C/strong>\u003C/td>\u003Ctd>Load multi-column CSV → PerformanceSetupPanel → select measures → Cpk scatter, boxplot, Pareto\u003C/td>\u003Ctd>Column detection, measure selection, channel drill navigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>\u003Cstrong>Filter navigation\u003C/strong>\u003C/td>\u003Ctd>Apply factor filters → verify breadcrumbs → navigate back → apply multi-select\u003C/td>\u003Ctd>Filter chips display, variation % contribution, back navigation, cumulative scope\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>13\u003C/td>\u003Ctd>\u003Cstrong>Findings panel\u003C/strong>\u003C/td>\u003Ctd>Open findings panel → pin observation from chart → change status (observed→investigating→analyzed) → add comment → What-If\u003C/td>\u003Ctd>Findings list rendering, status transitions, comment persistence, What-If slider\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>14\u003C/td>\u003Ctd>\u003Cstrong>OneDrive sync\u003C/strong>\u003C/td>\u003Ctd>Save project → check OneDrive/VariScout/Projects folder → close tab → reopen → verify data loads\u003C/td>\u003Ctd>Sync speed, file appears in OneDrive, data persists across sessions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>15\u003C/td>\u003Ctd>\u003Cstrong>Theme switching\u003C/strong>\u003C/td>\u003Ctd>Settings → toggle dark/light/system → verify all views adapt\u003C/td>\u003Ctd>Color consistency across charts, panels, editor; chrome color adaptation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>16\u003C/td>\u003Ctd>\u003Cstrong>Chart export\u003C/strong>\u003C/td>\u003Ctd>Copy chart to clipboard → paste in document; download PNG; download SVG\u003C/td>\u003Ctd>Export quality, correct dimensions (see chart export sizes), branding hidden (paid tier)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>17\u003C/td>\u003Ctd>\u003Cstrong>Settings persistence\u003C/strong>\u003C/td>\u003Ctd>Change display options (Y-axis lock, show specs, chart text size) → reload → verify retained\u003C/td>\u003Ctd>localStorage reliability, all toggle states restored\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>18\u003C/td>\u003Ctd>\u003Cstrong>Factor management\u003C/strong>\u003C/td>\u003Ctd>Click “Factors” in nav bar → ColumnMapping opens in edit mode → add/remove factor → Apply → verify filter cleanup\u003C/td>\u003Ctd>State consistency, orphaned filters cleaned, cancel preserves data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>19\u003C/td>\u003Ctd>\u003Cstrong>Data table editing\u003C/strong>\u003C/td>\u003Ctd>Open data table → edit cell values → verify charts update\u003C/td>\u003Ctd>Inline editing UX, bi-directional sync, undo behavior\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>20\u003C/td>\u003Ctd>\u003Cstrong>Chart annotations\u003C/strong>\u003C/td>\u003Ctd>Right-click boxplot/Pareto → highlight + add note; right-click I-Chart → add free-floating note\u003C/td>\u003Ctd>Context menu positioning, annotation persistence, drag-to-reposition\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>21\u003C/td>\u003Ctd>\u003Cstrong>CSV export\u003C/strong>\u003C/td>\u003Ctd>Editor header → export CSV → open in Excel\u003C/td>\u003Ctd>Data completeness, column ordering, encoding (UTF-8 with special characters)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>22\u003C/td>\u003Ctd>\u003Cstrong>Editable chart titles\u003C/strong>\u003C/td>\u003Ctd>Click chart title → edit text → verify persistence\u003C/td>\u003Ctd>Inline editing UX, title saved across sessions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>23\u003C/td>\u003Ctd>\u003Cstrong>Presentation mode\u003C/strong>\u003C/td>\u003Ctd>Enter presentation mode → full-screen chart overlay → navigate charts\u003C/td>\u003Ctd>Full-screen rendering, keyboard navigation, exit behavior\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"d-teams-test-scenarios\">D. Teams Test Scenarios\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#d-teams-test-scenarios\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “D. Teams Test Scenarios”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"prerequisite-generate-and-upload-manifest\">Prerequisite: Generate and Upload Manifest\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#prerequisite-generate-and-upload-manifest\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Prerequisite: Generate and Upload Manifest”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure app includes an admin page (\u003Ccode dir=\"auto\">AdminTeamsSetup.tsx\u003C/code>) that generates a Teams manifest \u003Ccode dir=\"auto\">.zip\u003C/code> file containing the app configuration and icons.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Scenario\u003C/th>\u003Cth>Steps\u003C/th>\u003Cth>What to Record\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>\u003Cstrong>Generate manifest\u003C/strong>\u003C/td>\u003Ctd>Navigate to admin/Teams setup page → download \u003Ccode dir=\"auto\">.zip\u003C/code> → inspect contents (manifest.json, icons)\u003C/td>\u003Ctd>Manifest correctness, icon presence (color + outline), app ID matches\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>\u003Cstrong>Upload to Teams\u003C/strong>\u003C/td>\u003Ctd>Teams Admin Center → Manage apps → Upload → select the \u003Ccode dir=\"auto\">.zip\u003C/code> → verify app appears in catalog\u003C/td>\u003Ctd>Upload process, any validation errors, app listing appearance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>\u003Cstrong>Open in Teams\u003C/strong>\u003C/td>\u003Ctd>Teams → Apps → Built for your org → open VariScout as personal tab\u003C/td>\u003Ctd>Load time, iframe rendering, no console errors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>\u003Cstrong>Auth in Teams\u003C/strong>\u003C/td>\u003Ctd>First open → expect login redirect to \u003Ccode dir=\"auto\">*.azurewebsites.net\u003C/code> → sign in via Entra ID\u003C/td>\u003Ctd>SSO behavior (note: \u003Ccode dir=\"auto\">*.azurewebsites.net\u003C/code> domains require one-time redirect, no seamless SSO), redirect UX\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>\u003Cstrong>Full workflow in Teams\u003C/strong>\u003C/td>\u003Ctd>Load sample → drill by factor → set specs → export chart\u003C/td>\u003Ctd>Iframe constraints, scrolling behavior, popup/modal rendering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>\u003Cstrong>Responsive in Teams\u003C/strong>\u003C/td>\u003Ctd>Resize Teams window → check chart responsiveness → try narrow sidebar mode\u003C/td>\u003Ctd>Layout adaptation, breakpoints, chart readability at small sizes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>\u003Cstrong>Findings popout\u003C/strong>\u003C/td>\u003Ctd>Open findings panel → click popout to new window\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">window.open\u003C/code> behavior in Teams (may be blocked), fallback behavior\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>\u003Cstrong>OneDrive sync in Teams\u003C/strong>\u003C/td>\u003Ctd>Save project in Teams tab → verify appears in OneDrive\u003C/td>\u003Ctd>Same Graph API flow as standalone, verify token available\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"e-evaluation-template\">E. Evaluation Template\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#e-evaluation-template\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “E. Evaluation Template”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Fill this form during and after testing. Rate items 1–5 (1=poor, 5=excellent) where applicable.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deployment-experience\">Deployment Experience\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deployment-experience\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment Experience”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Rating / Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Time to deploy (minutes)\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Clarity of deployment instructions\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Issues encountered\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>App Registration creation ease\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ARM template deploy success (if tested)\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Portal wizard usability (if tested)\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"authentication--security\">Authentication & Security\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#authentication--security\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Authentication & Security”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Rating / Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Login flow smoothness\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Token refresh behavior (any interruptions during long session?)\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Logout → re-login works cleanly?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>User display name correct in header?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Auth error messages clear?\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-analysis-quality\">Core Analysis Quality\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-analysis-quality\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Analysis Quality”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Rating / Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Statistical correctness (spot-check Cpk, mean, σ against known values)\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Chart visual quality\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Interactivity responsiveness (hover, click, drill)\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance with larger datasets (10K+ rows)\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Nelson rule detection accuracy\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ANOVA results match expectations?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-input\">Data Input\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-input\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Input”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Rating / Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Paste data detection accuracy (tab vs comma)\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>File upload reliability\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Column type detection (numeric/categorical/date)\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Manual entry UX\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Add Data dropdown clarity\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data merge behavior (append vs replace)\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"onedrive-sync\">OneDrive Sync\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#onedrive-sync\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “OneDrive Sync”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Rating / Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Save reliability\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Load reliability (data persists across sessions)\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Offline → online sync behavior\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Error messages clarity\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sync speed\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>File visible in OneDrive folder?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"teams-integration\">Teams Integration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#teams-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teams Integration”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Rating / Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Manifest generation works?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Upload to Teams Admin Center\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>App renders correctly in Teams iframe?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Auth flow in Teams\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Any iframe-specific issues?\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Popout windows work (findings)?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Scrolling behavior in Teams\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"accessibility\">Accessibility\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#accessibility\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Accessibility”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Rating / Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Keyboard navigation works? (Tab, Enter, Escape, Arrow keys)\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Skip link functional?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Screen reader announcements (ARIA live regions)?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Color contrast sufficient (light + dark themes)?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Focus indicators visible?\u003C/td>\u003Ctd>yes / no\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"overall-assessment\">Overall Assessment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#overall-assessment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overall Assessment”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Rating / Answer\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Missing features for real-world use\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Bugs found\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Comparison to PWA experience (what’s better/worse)\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Would you use this daily?\u003C/td>\u003Ctd>/5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Top 3 suggested improvements\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Marketplace readiness assessment\u003C/td>\u003Ctd>ready / needs work / not ready\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"f-known-limitations\">F. Known Limitations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#f-known-limitations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “F. Known Limitations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Document these with testers so they don’t report them as bugs:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Limitation\u003C/th>\u003Cth>Detail\u003C/th>\u003Cth>Workaround / Timeline\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Teams SSO\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">*.azurewebsites.net\u003C/code> domains don’t support seamless Teams SSO. Users see a one-time login redirect.\u003C/td>\u003Ctd>Custom domain needed for seamless SSO. Not blocking for testing.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Storage scope\u003C/strong>\u003C/td>\u003Ctd>Standard plan: local files only (no cloud sync). Team plan: OneDrive personal + SharePoint channel storage.\u003C/td>\u003Ctd>Standard needs only \u003Ccode dir=\"auto\">User.Read\u003C/code>. Team needs \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> + \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Local dev\u003C/strong>\u003C/td>\u003Ctd>Graph API unavailable on localhost. Auth returns mock user, OneDrive sync is no-op.\u003C/td>\u003Ctd>Expected behavior per \u003Ccode dir=\"auto\">easyAuth.ts\u003C/code> — test sync only on deployed instance.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Admin consent\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">User.Read\u003C/code> + \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> don’t require admin consent by default, but org Entra ID policies may block user consent.\u003C/td>\u003Ctd>If blocked, tenant admin grants consent via App Registration → API permissions → Grant admin consent.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Performance Mode in PWA\u003C/strong>\u003C/td>\u003Ctd>PWA detection modal shows “available in Azure App” — Performance Mode is Azure-only.\u003C/td>\u003Ctd>Expected behavior — PWA is free tier.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Client secret expiration\u003C/strong>\u003C/td>\u003Ctd>Test secret expires based on chosen duration. Production deployments should use 24-month secrets.\u003C/td>\u003Ctd>Set calendar reminder to rotate before expiration.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"g-test-data-recommendations\">G. Test Data Recommendations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#g-test-data-recommendations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “G. Test Data Recommendations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"built-in-samples\">Built-in Samples\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#built-in-samples\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Built-in Samples”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The app ships with sample datasets (via \u003Ccode dir=\"auto\">@variscout/data\u003C/code>). Use these for initial smoke testing:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Coffee\u003C/strong> — extraction temperature with spec limits, good for capability analysis\u003C/li>\n\u003Cli>\u003Cstrong>Journey\u003C/strong> — multi-factor dataset, good for drill-down and ANOVA\u003C/li>\n\u003Cli>\u003Cstrong>Bottleneck\u003C/strong> — multi-channel data, good for Performance Mode testing\u003C/li>\n\u003Cli>\u003Cstrong>Sachets\u003C/strong> — packaging weights, good for Nelson rule testing\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"custom-test-data\">Custom Test Data\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#custom-test-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Custom Test Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For thorough testing, prepare CSV files that exercise edge cases:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Test File\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Characteristics\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">large-dataset.csv\u003C/code>\u003C/td>\u003Ctd>Performance testing\u003C/td>\u003Ctd>10,000+ rows, 3 factors, 1 measure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">multi-measure.csv\u003C/code>\u003C/td>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>5+ numeric columns (fill heads / cavities)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">unicode-data.csv\u003C/code>\u003C/td>\u003Ctd>Encoding\u003C/td>\u003Ctd>Column names with ÄÖÅ, accented characters\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">missing-values.csv\u003C/code>\u003C/td>\u003Ctd>Validation\u003C/td>\u003Ctd>Rows with blank cells, mixed types\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">single-value.csv\u003C/code>\u003C/td>\u003Ctd>Edge case\u003C/td>\u003Ctd>All measurements identical (σ=0)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">two-rows.csv\u003C/code>\u003C/td>\u003Ctd>Minimum data\u003C/td>\u003Ctd>Just 2 data points (control limits undefined)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"h-cleanup\">H. Cleanup\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#h-cleanup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “H. Cleanup”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After testing is complete:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Delete the test resource group (removes all resources)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">delete\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--yes\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--no-wait\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Delete the App Registration (Azure Portal)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Entra ID → App registrations → VariScout Test → Delete\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az group delete --name rg-variscout-test --yes --no-wait\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"i-automated-e2e-coverage\">I. Automated E2E Coverage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#i-automated-e2e-coverage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “I. Automated E2E Coverage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure app has 9 Playwright spec files in \u003Ccode dir=\"auto\">apps/azure/e2e/\u003C/code> plus a shared helper module:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Covers Scenarios\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">helpers.ts\u003C/code>\u003C/td>\u003Ctd>Shared: \u003Ccode dir=\"auto\">confirmColumnMapping\u003C/code>, \u003Ccode dir=\"auto\">loadSampleInEditor\u003C/code>, \u003Ccode dir=\"auto\">loadPerformanceSample\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">editor-workflow.spec.ts\u003C/code>\u003C/td>\u003Ctd>C-1 (auth mock), C-2 (sample load), C-12 (filter drill)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">samples.spec.ts\u003C/code>\u003C/td>\u003Ctd>C-2 (all sample datasets), C-6 (I-Chart), C-7 (Boxplot)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">analysis-views.spec.ts\u003C/code>\u003C/td>\u003Ctd>C-6 (I-Chart), C-7 (Boxplot), C-8 (Pareto)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stats-anova.spec.ts\u003C/code>\u003C/td>\u003Ctd>C-9 (Cp/Cpk), C-10 (ANOVA)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">user-flows.spec.ts\u003C/code>\u003C/td>\u003Ctd>C-3 (paste), C-12 (filter navigation), multi-step workflows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">edge-cases.spec.ts\u003C/code>\u003C/td>\u003Ctd>Boundary conditions, empty states, error handling\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">editor-features.spec.ts\u003C/code>\u003C/td>\u003Ctd>C-13 (findings), C-19 (data table), C-21 (CSV export), C-22 (chart titles)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">performance-mode.spec.ts\u003C/code>\u003C/td>\u003Ctd>C-11 (Performance Mode), Cp/Cpk toggle, spec limits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">settings-theme.spec.ts\u003C/code>\u003C/td>\u003Ctd>C-15 (theme switching), C-17 (settings persistence)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Not covered by automation\u003C/strong> (require deployed Azure environment):\u003C/p>\n\u003Cul>\n\u003Cli>C-1 live auth (EasyAuth redirect — mocked in Playwright)\u003C/li>\n\u003Cli>C-14 OneDrive sync (requires Graph API token)\u003C/li>\n\u003Cli>C-23 Presentation mode (partial — visual verification needed)\u003C/li>\n\u003Cli>All section D (Teams integration — requires Teams Admin Center)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>ANOVA check clarification:\u003C/strong> ANOVA results (\u003Ccode dir=\"auto\">[data-testid=\"anova-results\"]\u003C/code>) are only visible in FocusedChartView (boxplot focused view). Tests must first maximize the boxplot card to reach this view.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run all Azure E2E tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test:e2e\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm --filter @variscout/azure-app test:e2e\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../08-products/azure/arm-template.md\">ARM Template Documentation\u003C/a> — template parameters and App Registration setup\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/authentication.md\">Authentication (EasyAuth)\u003C/a> — auth flow, endpoints, token management\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/onedrive-sync.md\">OneDrive Sync\u003C/a> — sync architecture and storage structure\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/submission-checklist.md\">Marketplace Submission Checklist\u003C/a> — full submission tracker\u003C/li>\n\u003Cli>\u003Ca href=\"deployment.md\">Deployment Guide\u003C/a> — build commands and deployment workflows\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007: Azure Marketplace Distribution\u003C/a> — distribution strategy\u003C/li>\n\u003C/ul>", + { + "headings": 8315, + "localImagePaths": 8389, + "remoteImagePaths": 8390, + "frontmatter": 8391, + "imagePaths": 8392 + }, + [ + 8316, 8318, 8321, 8324, 8327, 8330, 8333, 8336, 8339, 8342, 8345, 8348, 8351, 8354, 8357, 8358, + 8361, 8362, 8365, 8366, 8367, 8370, 8373, 8376, 8379, 8382, 8385, 8388 + ], + { "depth": 30, "slug": 8317, "text": 8305 }, + "azure-app-testing-plan--rdmaic-organization", + { "depth": 33, "slug": 8319, "text": 8320 }, + "a-prerequisites-checklist", + "A. Prerequisites Checklist", + { "depth": 79, "slug": 8322, "text": 8323 }, + "azure-subscription", + "Azure Subscription", + { "depth": 79, "slug": 8325, "text": 8326 }, + "entra-id-app-registration", + "Entra ID App Registration", + { "depth": 79, "slug": 8328, "text": 8329 }, + "local-build", + "Local Build", + { "depth": 33, "slug": 8331, "text": 8332 }, + "b-deployment-guide", + "B. Deployment Guide", + { "depth": 79, "slug": 8334, "text": 8335 }, + "option-1-direct-zip-deploy-recommended-for-testing", + "Option 1: Direct Zip Deploy (recommended for testing)", + { "depth": 79, "slug": 8337, "text": 8338 }, + "option-2-arm-template-deploy-mirrors-marketplace", + "Option 2: ARM Template Deploy (mirrors Marketplace)", + { "depth": 79, "slug": 8340, "text": 8341 }, + "verify-deployment", + "Verify Deployment", + { "depth": 33, "slug": 8343, "text": 8344 }, + "c-browser-test-scenarios-standalone", + "C. Browser Test Scenarios (Standalone)", + { "depth": 33, "slug": 8346, "text": 8347 }, + "d-teams-test-scenarios", + "D. Teams Test Scenarios", + { "depth": 79, "slug": 8349, "text": 8350 }, + "prerequisite-generate-and-upload-manifest", + "Prerequisite: Generate and Upload Manifest", + { "depth": 33, "slug": 8352, "text": 8353 }, + "e-evaluation-template", + "E. Evaluation Template", + { "depth": 79, "slug": 8355, "text": 8356 }, + "deployment-experience", + "Deployment Experience", + { "depth": 79, "slug": 2058, "text": 2059 }, + { "depth": 79, "slug": 8359, "text": 8360 }, + "core-analysis-quality", + "Core Analysis Quality", + { "depth": 79, "slug": 974, "text": 975 }, + { "depth": 79, "slug": 8363, "text": 8364 }, + "onedrive-sync", + "OneDrive Sync", + { "depth": 79, "slug": 2055, "text": 2056 }, + { "depth": 79, "slug": 3565, "text": 3566 }, + { "depth": 79, "slug": 8368, "text": 8369 }, + "overall-assessment", + "Overall Assessment", + { "depth": 33, "slug": 8371, "text": 8372 }, + "f-known-limitations", + "F. Known Limitations", + { "depth": 33, "slug": 8374, "text": 8375 }, + "g-test-data-recommendations", + "G. Test Data Recommendations", + { "depth": 79, "slug": 8377, "text": 8378 }, + "built-in-samples", + "Built-in Samples", + { "depth": 79, "slug": 8380, "text": 8381 }, + "custom-test-data", + "Custom Test Data", + { "depth": 33, "slug": 8383, "text": 8384 }, + "h-cleanup", + "H. Cleanup", + { "depth": 33, "slug": 8386, "text": 8387 }, + "i-automated-e2e-coverage", + "I. Automated E2E Coverage", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 8305 }, + [], + "05-technical/implementation/data-input", + { "id": 8393, "data": 8395, "body": 8400, "filePath": 8401, "digest": 8402, "rendered": 8403 }, + { + "title": 8396, + "editUrl": 16, + "head": 8397, + "template": 18, + "sidebar": 8398, + "pagefind": 16, + "draft": 20 + }, + "Data Input System", + [], + { "hidden": 20, "attrs": 8399 }, + {}, + "# Data Input System\n\nTechnical documentation for data parsing, validation, and auto-mapping in VariScout Lite.\n\n## File Locations\n\n| File | Purpose |\n| ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |\n| `packages/core/src/parser/` | **Shared** parsing, validation, and detection logic (csv, excel, detection, validation, pareto submodules) |\n| `packages/hooks/src/useDataIngestion.ts` | **Shared** file upload handlers |\n| `packages/ui/src/components/ColumnMapping/` | **Shared** column selection UI |\n| `packages/ui/src/components/DataQualityBanner/` | **Shared** validation summary component |\n| `packages/ui/src/components/MeasureColumnSelector/` | **Shared** measure column selector |\n| `packages/ui/src/components/PerformanceDetectedModal/` | **Shared** wide-format detection modal |\n| `apps/pwa/src/hooks/useDataIngestion.ts` | PWA wrapper (adds loadSample) |\n| `packages/ui/src/components/DataTable/` | **Shared** inline editing table with multi-cell paste, arrow-key navigation |\n| `apps/pwa/src/components/data/DataTableModal.tsx` | Data view with multi-cell paste and excluded row support |\n| `apps/pwa/src/context/DataContext.tsx` | State management for data and validation |\n\n**Cross-platform availability**: All parser functions are in `@variscout/core` and can be used by:\n\n- PWA (apps/pwa)\n- Azure/Teams app (apps/azure)\n\n---\n\n## Smart Auto-Mapping\n\n### Keyword Detection\n\nColumn type detection uses keyword matching for intelligent suggestions. When a column name contains these keywords, it's prioritized for that role.\n\n**Outcome Keywords** (numeric columns):\n\n```\ntime, duration, cycle, lead, ct\nweight, length, width, height, thickness\ntemperature, temp, pressure\nvalue, measurement, result, y, response\nyield, output, reading\n```\n\n**Factor Keywords** (categorical columns):\n\n```\nshift, operator, machine, line, cell\nproduct, batch, supplier, day, week\nstation, tool, lot, group, team\n```\n\n**Time Keywords** (date/time columns):\n\n```\ndate, time, timestamp, datetime, created, recorded\n```\n\n### Detection Algorithm\n\nThe `detectColumns()` function in `parser/detection.ts` follows this logic:\n\n1. **Analyze each column**:\n - Sample multiple rows (not just first) to determine type\n - Check if >90% of values are numeric → `numeric` type\n - Check for date patterns → `date` type\n - Otherwise → `categorical` type\n\n2. **Select Outcome (Y)**:\n - First priority: Numeric column with keyword match\n - Fallback: First numeric column with variation\n\n3. **Select Factors (X)**:\n - Priority: Categorical columns with keyword matches\n - Fallback: First 3 categorical columns\n - Maximum: 3 factors\n\n4. **Select Time Column**:\n - Priority: Column matching time keywords\n - Used for I-Chart ordering when available\n - When detected, triggers the **Time Factor Extraction** panel in ColumnMapping\n\n### Time Factor Extraction\n\nWhen `detectColumns()` finds a `timeColumn`, the `TimeExtractionPanel` (from `@variscout/ui`) appears in the ColumnMapping screen. On mapping confirm, `augmentWithTimeColumns()` from `@variscout/core/time.ts` adds derived factor columns:\n\n```typescript\nimport { augmentWithTimeColumns } from '@variscout/core';\n\nconst augmented = augmentWithTimeColumns(rawData, 'Date', {\n extractYear: true,\n extractMonth: true,\n extractWeek: false,\n extractDayOfWeek: true,\n extractHour: false,\n});\n// Adds: Date_Year, Date_Month, Date_DayOfWeek columns\n```\n\nThe `applyTimeExtraction()` method in `useDataIngestion` (from `@variscout/hooks`) handles the full pipeline: augmenting data, adding new factor columns, and re-validating.\n\n### Return Type\n\n```typescript\ninterface DetectedColumns {\n outcome: string | null;\n factors: string[];\n timeColumn: string | null;\n}\n```\n\n---\n\n## Data Validation\n\n### Validation Rules\n\nRows are excluded from analysis when the outcome column has:\n\n| Issue | Description | Example |\n| ----------- | -------------------------------- | -------------------- |\n| Missing | null, undefined, or empty string | `\"\"`, `null` |\n| Non-numeric | Cannot be parsed as a number | `\"N/A\"`, `\"pending\"` |\n\nValidation is **informational only** - users can inspect excluded rows but analysis proceeds with valid data.\n\n### DataQualityReport Interface\n\n```typescript\ninterface DataQualityReport {\n totalRows: number;\n validRows: number;\n excludedRows: ExcludedRow[];\n columnIssues: ColumnIssue[];\n}\n\ninterface ExcludedRow {\n index: number; // Original row index (0-based)\n reasons: ExclusionReason[];\n}\n\ninterface ExclusionReason {\n type: 'missing' | 'non_numeric' | 'empty';\n column: string;\n value?: string; // The problematic value\n}\n\ninterface ColumnIssue {\n column: string;\n type: 'missing' | 'non_numeric' | 'no_variation' | 'all_empty';\n count: number;\n severity: 'warning' | 'info';\n}\n```\n\n### Validation Flow\n\n```\nFile Upload\n │\n ▼\nparseCSV() / parseExcel()\n │\n ▼\ndetectColumns() → suggest outcome/factors\n │\n ▼\nvalidateData(data, outcome) → DataQualityReport\n │\n ▼\nStore in DataContext.dataQualityReport\n │\n ▼\nShow DataQualityBanner (from @variscout/ui)\n │\n ├─► \"View Excluded Rows\" → DataTableModal (filtered)\n │\n └─► \"Start Analysis\" → Dashboard with valid rows\n```\n\n### User Interface\n\n**DataQualityBanner** displays:\n\n- Total rows and valid rows count\n- Excluded row count with breakdown by issue type\n- \"View Excluded Rows\" button opens DataTableModal\n\n**DataTableModal** excluded row features:\n\n- \"Show Excluded Only\" toggle button\n- Amber background highlighting for excluded rows\n- AlertTriangle icon with tooltip showing exclusion reasons\n\n---\n\n## Wide-Format (Multi-Measure) Data Detection\n\nVariScout can automatically detect wide-format data with multiple measurement channels (e.g., fill heads, valves, nozzles) and prompt users to enable Performance Mode.\n\n### Detection Mechanism\n\nThe `detectWideFormat()` function in `parser/detection.ts` analyzes data to identify multi-channel structures:\n\n1. **Find numeric columns** - Identify columns with >90% numeric values\n2. **Exclude metadata** - Skip known metadata patterns (date, batch, operator, etc.)\n3. **Match channel patterns** - Check if column names follow channel naming conventions\n4. **Assess data consistency** - Check if ranges are similar across potential channels\n\n### Channel Naming Patterns\n\nColumns matching these patterns are recognized as measurement channels:\n\n```\nV1, V2, V3... # V + number\nValve_1, Valve-1 # Valve prefix\nHead_1, Head1 # Head prefix\nChannel_1, Ch1 # Channel prefix\nNozzle_01, Nozzle-1 # Nozzle prefix\nCavity_1, Die_1 # Injection molding\nStation_1, Cell_1 # Manufacturing\n1, 2, 3... # Plain numbers\n```\n\n### Confidence Levels\n\n| Confidence | Criteria |\n| ---------- | ---------------------------------------------- |\n| `high` | ≥50% of numeric columns match channel patterns |\n| `medium` | ≥5 numeric columns with consistent data ranges |\n| `low` | Meets minimum (3) but no clear channel pattern |\n\n### Detection Options\n\n```typescript\ninterface DetectWideFormatOptions {\n minChannels?: number; // Minimum channels required (default: 3)\n patternMatchThreshold?: number; // Pattern match ratio for high confidence (default: 0.5)\n numericThreshold?: number; // Required numeric ratio (default: 0.9)\n}\n```\n\n### Return Type\n\n```typescript\ninterface WideFormatDetection {\n isWideFormat: boolean; // True if wide format detected with sufficient confidence\n channels: ChannelInfo[]; // Detected channel columns with preview stats\n metadataColumns: string[]; // Non-channel columns (date, batch, etc.)\n confidence: 'high' | 'medium' | 'low';\n reason: string; // Explanation of detection result\n}\n\ninterface ChannelInfo {\n id: string; // Column name\n label: string; // Display name\n n: number; // Valid value count\n preview: { min: number; max: number; mean: number };\n matchedPattern: boolean; // True if name matches channel pattern\n}\n```\n\n### Integration with useDataIngestion\n\nThe `useDataIngestion` hook from `@variscout/hooks` triggers wide-format detection after file upload:\n\n```typescript\nimport { useDataIngestion } from '@variscout/hooks';\n\nconst { handleFileUpload } = useDataIngestion({\n onWideFormatDetected: (detection: WideFormatDetection) => {\n // Show PerformanceDetectedModal to user\n setShowPerformanceModal(true);\n setPendingDetection(detection);\n },\n});\n```\n\nThe callback fires when:\n\n- Detection confidence is `high` or `medium`\n- At least 3 channel columns are found\n- User hasn't dismissed the prompt before\n\n### User Flow\n\n```\nFile Upload\n │\n ▼\ndetectWideFormat(data)\n │\n ├─► confidence: high/medium\n │ │\n │ ▼\n │ PerformanceDetectedModal\n │ │\n │ ├─► \"Enable\" → Performance Mode\n │ │ • setPerformanceMode(true)\n │ │ • setMeasureColumns(channels)\n │ │ • setMeasureLabel(label)\n │ │\n │ └─► \"Not Now\" → Standard Mode\n │\n └─► confidence: low → Continue to ColumnMapping\n```\n\n### Components\n\n| Component | Package | Purpose |\n| -------------------------- | --------------- | ---------------------------------------------- |\n| `PerformanceDetectedModal` | `@variscout/ui` | Auto-detection prompt after file upload |\n| `PerformanceSetupPanel` | App-specific | Manual configuration (inline or modal) |\n| `MeasureColumnSelector` | `@variscout/ui` | Checkbox list with preview stats for selection |\n| `ColumnMapping` | `@variscout/ui` | Column selection and validation UI |\n| `DataQualityBanner` | `@variscout/ui` | Validation summary with excluded row info |\n\n### Performance Mode Features\n\n#### Cp/Cpk Metric Toggle\n\nThe Performance I-Chart displays capability metrics with a toggle to switch between:\n\n- **Cpk** (default) - Process capability index accounting for centering\n- **Cp** - Potential capability (spread only, ignores centering)\n\nToggle location: Top-right of the I-Chart header in Performance Mode.\nTooltip always shows both Cp and Cpk values regardless of selected metric.\n\n```typescript\n// In PerformanceDashboard.tsx\nconst [capabilityMetric, setCapabilityMetric] = useState\u003C'cp' | 'cpk'>('cpk');\n\n// Passed to chart component\n\u003CPerformanceIChart capabilityMetric={capabilityMetric} ... />\n```\n\n#### Drill-Down to Standard I-Chart\n\nWhen a measure is selected in Performance Mode, users can drill down to the standard I-Chart for detailed analysis:\n\n1. Click any channel point in the Performance I-Chart to select it\n2. \"View in I-Chart →\" button appears in the chart header\n3. Click to navigate to standard dashboard with that measure as the outcome variable\n4. \"Back to Performance\" banner shows at the top for return navigation\n\n**Navigation Flow:**\n\n```\nPerformance Mode → Click channel → \"View in I-Chart\" button\n │\n ▼\n Standard Dashboard (measure as outcome)\n │\n ├─► \"Back to Performance\" → Performance Mode\n │\n └─► Continue with standard analysis\n```\n\n**State Management (App.tsx):**\n\n```typescript\n// Track drill navigation origin\nconst [drillFromPerformance, setDrillFromPerformance] = useState\u003Cstring | null>(null);\n\n// Drill to measure\nconst handleDrillToMeasure = useCallback(\n (measureId: string) => {\n setDrillFromPerformance(measureId);\n setOutcome(measureId);\n setActiveView('dashboard');\n },\n [setOutcome]\n);\n\n// Return to Performance\nconst handleBackToPerformance = useCallback(() => {\n setDrillFromPerformance(null);\n setActiveView('performance');\n}, []);\n```\n\n**Dashboard Props:**\n\n| Prop | Type | Purpose |\n| ---------------------- | ----------------------------- | ---------------------------------- |\n| `drillFromPerformance` | `string \\| null` | Measure ID if drilled from Perf |\n| `onBackToPerformance` | `() => void` | Callback to return to Perf Mode |\n| `onDrillToMeasure` | `(measureId: string) => void` | Callback to drill to standard view |\n\n---\n\n## Pareto Data Sources\n\n### Derived Mode (Default)\n\n- Counts computed from selected factors via `d3.rollup()`\n- Linked to main data filters (updates when filters change)\n- Uses `factors[1] || factors[0]` by default\n\n```typescript\n// In ParetoChart.tsx\nconst counts = d3.rollup(\n filteredData,\n v => v.length,\n d => d[factor]\n);\n```\n\n### Separate Mode\n\nFor pre-aggregated count data (e.g., from ERP/MES systems):\n\n- Upload separate CSV/Excel file in ColumnMapping\n- Auto-detects category (first string) and count (first numeric) columns\n- **NOT linked to main data filters**\n- Shows info banner: \"Using separate Pareto file (not linked to filters)\"\n\n### ParetoRow Interface\n\n```typescript\ninterface ParetoRow {\n category: string;\n count: number;\n}\n```\n\n### State in DataContext\n\n```typescript\n// Mode selection\nparetoMode: 'derived' | 'separate';\n\n// Separate Pareto data\nseparateParetoData: ParetoRow[] | null;\nseparateParetoFilename: string | null;\n\n// Setters\nsetParetoMode: (mode: 'derived' | 'separate') => void;\nsetSeparateParetoData: (data: ParetoRow[] | null) => void;\nsetSeparateParetoFilename: (name: string | null) => void;\n```\n\n### Separate Pareto File Format\n\nCSV or Excel with at least two columns:\n\n```csv\nCategory,Count\nMachine A,45\nMachine B,32\nMachine C,18\n```\n\nThe parser auto-detects:\n\n- **Category column**: First string/text column\n- **Count column**: First numeric column\n\n---\n\n## Performance Limits\n\n| Threshold | PWA Behavior | Azure Behavior |\n| ----------------------------- | ------------------------------------- | ------------------------------------- |\n| Below warning (5K / 10K) | Loads immediately | Loads immediately |\n| Warning to hard limit | Warning prompt (may slow performance) | Warning prompt (may slow performance) |\n| Above hard limit (50K / 100K) | Rejected with error message | Rejected with error message |\n\nDefaults in `packages/hooks/src/useDataIngestion.ts`, configurable via `DataIngestionConfig`:\n\n```typescript\nconst DEFAULT_ROW_WARNING_THRESHOLD = 5000;\nconst DEFAULT_ROW_HARD_LIMIT = 50000;\n\n// Azure wrapper overrides:\n{ rowHardLimit: 100_000, rowWarningThreshold: 10_000 }\n```\n\n---\n\n## Supported File Formats\n\n### CSV\n\n- Parsed with PapaParse\n- UTF-8 encoding recommended\n- First row = headers\n- Comma delimiter\n\n### Excel (.xlsx, .xls)\n\n- Parsed with SheetJS (xlsx library)\n- First sheet only\n- First row = headers\n- Numeric columns should be formatted as numbers\n\n---\n\n## Key Functions\n\n### parser/ (from @variscout/core)\n\n| Function | Purpose |\n| ----------------------------- | ----------------------------------------------- |\n| `parseCSV(file)` | Parse CSV file to array of objects |\n| `parseExcel(file)` | Parse Excel file to array of objects |\n| `detectColumns(data)` | Auto-detect column roles with keyword matching |\n| `validateData(data, outcome)` | Validate rows and return quality report |\n| `parseParetoFile(file)` | Parse separate Pareto file to ParetoRow[] |\n| `detectWideFormat(data)` | Auto-detect multi-channel wide format data |\n| `detectChannelColumns(data)` | Find numeric columns that appear to be channels |\n\n### useDataIngestion (from @variscout/hooks)\n\n| Function | Purpose |\n| ---------------------------------- | --------------------------------------------- |\n| `handleFileUpload(e)` | Main file upload handler |\n| `handleParetoFileUpload(file)` | Separate Pareto file handler |\n| `clearParetoFile()` | Reset to derived Pareto mode |\n| `clearData()` | Reset all data state |\n| `applyTimeExtraction(col, config)` | Augment data with time-derived factor columns |\n| `onWideFormatDetected` | Callback when wide format data is detected |\n| `onTimeColumnDetected` | Callback when a date/time column is detected |\n\nNote: `loadSample()` is added by the PWA-specific wrapper in `apps/pwa/src/hooks/useDataIngestion.ts`.", + "src/content/docs/05-technical/implementation/data-input.md", + "7ad7d95b3c98194f", + { "html": 8404, "metadata": 8405 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"data-input-system\">Data Input System\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#data-input-system\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Input System”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Technical documentation for data parsing, validation, and auto-mapping in VariScout Lite.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"file-locations\">File Locations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#file-locations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “File Locations”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/parser/\u003C/code>\u003C/td>\u003Ctd>\u003Cstrong>Shared\u003C/strong> parsing, validation, and detection logic (csv, excel, detection, validation, pareto submodules)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/hooks/src/useDataIngestion.ts\u003C/code>\u003C/td>\u003Ctd>\u003Cstrong>Shared\u003C/strong> file upload handlers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/ColumnMapping/\u003C/code>\u003C/td>\u003Ctd>\u003Cstrong>Shared\u003C/strong> column selection UI\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/DataQualityBanner/\u003C/code>\u003C/td>\u003Ctd>\u003Cstrong>Shared\u003C/strong> validation summary component\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/MeasureColumnSelector/\u003C/code>\u003C/td>\u003Ctd>\u003Cstrong>Shared\u003C/strong> measure column selector\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/PerformanceDetectedModal/\u003C/code>\u003C/td>\u003Ctd>\u003Cstrong>Shared\u003C/strong> wide-format detection modal\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/hooks/useDataIngestion.ts\u003C/code>\u003C/td>\u003Ctd>PWA wrapper (adds loadSample)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/DataTable/\u003C/code>\u003C/td>\u003Ctd>\u003Cstrong>Shared\u003C/strong> inline editing table with multi-cell paste, arrow-key navigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/data/DataTableModal.tsx\u003C/code>\u003C/td>\u003Ctd>Data view with multi-cell paste and excluded row support\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/context/DataContext.tsx\u003C/code>\u003C/td>\u003Ctd>State management for data and validation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Cross-platform availability\u003C/strong>: All parser functions are in \u003Ccode dir=\"auto\">@variscout/core\u003C/code> and can be used by:\u003C/p>\n\u003Cul>\n\u003Cli>PWA (apps/pwa)\u003C/li>\n\u003Cli>Azure/Teams app (apps/azure)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"smart-auto-mapping\">Smart Auto-Mapping\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#smart-auto-mapping\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Smart Auto-Mapping”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"keyword-detection\">Keyword Detection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#keyword-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyword Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Column type detection uses keyword matching for intelligent suggestions. When a column name contains these keywords, it’s prioritized for that role.\u003C/p>\n\u003Cp>\u003Cstrong>Outcome Keywords\u003C/strong> (numeric columns):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">time, duration, cycle, lead, ct\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">weight, length, width, height, thickness\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">temperature, temp, pressure\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">value, measurement, result, y, response\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">yield, output, reading\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"time, duration, cycle, lead, ctweight, length, width, height, thicknesstemperature, temp, pressurevalue, measurement, result, y, responseyield, output, reading\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Factor Keywords\u003C/strong> (categorical columns):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">shift, operator, machine, line, cell\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">product, batch, supplier, day, week\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">station, tool, lot, group, team\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"shift, operator, machine, line, cellproduct, batch, supplier, day, weekstation, tool, lot, group, team\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Time Keywords\u003C/strong> (date/time columns):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">date, time, timestamp, datetime, created, recorded\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"date, time, timestamp, datetime, created, recorded\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"detection-algorithm\">Detection Algorithm\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#detection-algorithm\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Detection Algorithm”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">detectColumns()\u003C/code> function in \u003Ccode dir=\"auto\">parser/detection.ts\u003C/code> follows this logic:\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Analyze each column\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Sample multiple rows (not just first) to determine type\u003C/li>\n\u003Cli>Check if >90% of values are numeric → \u003Ccode dir=\"auto\">numeric\u003C/code> type\u003C/li>\n\u003Cli>Check for date patterns → \u003Ccode dir=\"auto\">date\u003C/code> type\u003C/li>\n\u003Cli>Otherwise → \u003Ccode dir=\"auto\">categorical\u003C/code> type\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Select Outcome (Y)\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>First priority: Numeric column with keyword match\u003C/li>\n\u003Cli>Fallback: First numeric column with variation\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Select Factors (X)\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Priority: Categorical columns with keyword matches\u003C/li>\n\u003Cli>Fallback: First 3 categorical columns\u003C/li>\n\u003Cli>Maximum: 3 factors\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Select Time Column\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Priority: Column matching time keywords\u003C/li>\n\u003Cli>Used for I-Chart ordering when available\u003C/li>\n\u003Cli>When detected, triggers the \u003Cstrong>Time Factor Extraction\u003C/strong> panel in ColumnMapping\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"time-factor-extraction\">Time Factor Extraction\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#time-factor-extraction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Time Factor Extraction”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When \u003Ccode dir=\"auto\">detectColumns()\u003C/code> finds a \u003Ccode dir=\"auto\">timeColumn\u003C/code>, the \u003Ccode dir=\"auto\">TimeExtractionPanel\u003C/code> (from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>) appears in the ColumnMapping screen. On mapping confirm, \u003Ccode dir=\"auto\">augmentWithTimeColumns()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core/time.ts\u003C/code> adds derived factor columns:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { augmentWithTimeColumns } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">augmented\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">augmentWithTimeColumns\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(rawData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Date\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extractYear: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extractMonth: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extractWeek: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extractDayOfWeek: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extractHour: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Adds: Date_Year, Date_Month, Date_DayOfWeek columns\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { augmentWithTimeColumns } from '@variscout/core';const augmented = augmentWithTimeColumns(rawData, 'Date', { extractYear: true, extractMonth: true, extractWeek: false, extractDayOfWeek: true, extractHour: false,});// Adds: Date_Year, Date_Month, Date_DayOfWeek columns\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">applyTimeExtraction()\u003C/code> method in \u003Ccode dir=\"auto\">useDataIngestion\u003C/code> (from \u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>) handles the full pipeline: augmenting data, adding new factor columns, and re-validating.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"return-type\">Return Type\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#return-type\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Return Type”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> DetectedColumns {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factors\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">timeColumn\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface DetectedColumns { outcome: string | null; factors: string[]; timeColumn: string | null;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-validation\">Data Validation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"validation-rules\">Validation Rules\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#validation-rules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Validation Rules”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Rows are excluded from analysis when the outcome column has:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Issue\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Example\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Missing\u003C/td>\u003Ctd>null, undefined, or empty string\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">\"\"\u003C/code>, \u003Ccode dir=\"auto\">null\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Non-numeric\u003C/td>\u003Ctd>Cannot be parsed as a number\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">\"N/A\"\u003C/code>, \u003Ccode dir=\"auto\">\"pending\"\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Validation is \u003Cstrong>informational only\u003C/strong> - users can inspect excluded rows but analysis proceeds with valid data.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"dataqualityreport-interface\">DataQualityReport Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#dataqualityreport-interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “DataQualityReport Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> DataQualityReport {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">totalRows\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">validRows\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">excludedRows\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ExcludedRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">columnIssues\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ColumnIssue\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ExcludedRow {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Original row index (0-based)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">reasons\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ExclusionReason\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ExclusionReason {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">type\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">missing\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">non_numeric\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">empty\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">column\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// The problematic value\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ColumnIssue {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">column\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">type\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">missing\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">non_numeric\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">no_variation\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">all_empty\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">count\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">severity\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">warning\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">info\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface DataQualityReport { totalRows: number; validRows: number; excludedRows: ExcludedRow[]; columnIssues: ColumnIssue[];}interface ExcludedRow { index: number; // Original row index (0-based) reasons: ExclusionReason[];}interface ExclusionReason { type: 'missing' | 'non_numeric' | 'empty'; column: string; value?: string; // The problematic value}interface ColumnIssue { column: string; type: 'missing' | 'non_numeric' | 'no_variation' | 'all_empty'; count: number; severity: 'warning' | 'info';}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"validation-flow\">Validation Flow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#validation-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Validation Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">File Upload\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">parseCSV() / parseExcel()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">detectColumns() → suggest outcome/factors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">validateData(data, outcome) → DataQualityReport\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Store in DataContext.dataQualityReport\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Show DataQualityBanner (from @variscout/ui)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─► \"View Excluded Rows\" → DataTableModal (filtered)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─► \"Start Analysis\" → Dashboard with valid rows\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"File Upload │ ▼parseCSV() / parseExcel() │ ▼detectColumns() → suggest outcome/factors │ ▼validateData(data, outcome) → DataQualityReport │ ▼Store in DataContext.dataQualityReport │ ▼Show DataQualityBanner (from @variscout/ui) │ ├─► "View Excluded Rows" → DataTableModal (filtered) │ └─► "Start Analysis" → Dashboard with valid rows\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-interface\">User Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>DataQualityBanner\u003C/strong> displays:\u003C/p>\n\u003Cul>\n\u003Cli>Total rows and valid rows count\u003C/li>\n\u003Cli>Excluded row count with breakdown by issue type\u003C/li>\n\u003Cli>“View Excluded Rows” button opens DataTableModal\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>DataTableModal\u003C/strong> excluded row features:\u003C/p>\n\u003Cul>\n\u003Cli>“Show Excluded Only” toggle button\u003C/li>\n\u003Cli>Amber background highlighting for excluded rows\u003C/li>\n\u003Cli>AlertTriangle icon with tooltip showing exclusion reasons\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"wide-format-multi-measure-data-detection\">Wide-Format (Multi-Measure) Data Detection\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#wide-format-multi-measure-data-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Wide-Format (Multi-Measure) Data Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout can automatically detect wide-format data with multiple measurement channels (e.g., fill heads, valves, nozzles) and prompt users to enable Performance Mode.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"detection-mechanism\">Detection Mechanism\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#detection-mechanism\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Detection Mechanism”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">detectWideFormat()\u003C/code> function in \u003Ccode dir=\"auto\">parser/detection.ts\u003C/code> analyzes data to identify multi-channel structures:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Find numeric columns\u003C/strong> - Identify columns with >90% numeric values\u003C/li>\n\u003Cli>\u003Cstrong>Exclude metadata\u003C/strong> - Skip known metadata patterns (date, batch, operator, etc.)\u003C/li>\n\u003Cli>\u003Cstrong>Match channel patterns\u003C/strong> - Check if column names follow channel naming conventions\u003C/li>\n\u003Cli>\u003Cstrong>Assess data consistency\u003C/strong> - Check if ranges are similar across potential channels\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"channel-naming-patterns\">Channel Naming Patterns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#channel-naming-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Channel Naming Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Columns matching these patterns are recognized as measurement channels:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">V1, V2, V3... # V + number\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Valve_1, Valve-1 # Valve prefix\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Head_1, Head1 # Head prefix\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Channel_1, Ch1 # Channel prefix\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Nozzle_01, Nozzle-1 # Nozzle prefix\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cavity_1, Die_1 # Injection molding\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Station_1, Cell_1 # Manufacturing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">1, 2, 3... # Plain numbers\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"V1, V2, V3... # V + numberValve_1, Valve-1 # Valve prefixHead_1, Head1 # Head prefixChannel_1, Ch1 # Channel prefixNozzle_01, Nozzle-1 # Nozzle prefixCavity_1, Die_1 # Injection moldingStation_1, Cell_1 # Manufacturing1, 2, 3... # Plain numbers\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"confidence-levels\">Confidence Levels\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#confidence-levels\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Confidence Levels”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Confidence\u003C/th>\u003Cth>Criteria\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">high\u003C/code>\u003C/td>\u003Ctd>≥50% of numeric columns match channel patterns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">medium\u003C/code>\u003C/td>\u003Ctd>≥5 numeric columns with consistent data ranges\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">low\u003C/code>\u003C/td>\u003Ctd>Meets minimum (3) but no clear channel pattern\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"detection-options\">Detection Options\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#detection-options\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Detection Options”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> DetectWideFormatOptions {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">minChannels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Minimum channels required (default: 3)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">patternMatchThreshold\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Pattern match ratio for high confidence (default: 0.5)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">numericThreshold\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Required numeric ratio (default: 0.9)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface DetectWideFormatOptions { minChannels?: number; // Minimum channels required (default: 3) patternMatchThreshold?: number; // Pattern match ratio for high confidence (default: 0.5) numericThreshold?: number; // Required numeric ratio (default: 0.9)}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"return-type-1\">Return Type\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#return-type-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Return Type”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> WideFormatDetection {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isWideFormat\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// True if wide format detected with sufficient confidence\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChannelInfo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Detected channel columns with preview stats\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">metadataColumns\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Non-channel columns (date, batch, etc.)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">confidence\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">high\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">medium\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">low\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">reason\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Explanation of detection result\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChannelInfo {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Column name\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Display name\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">n\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Valid value count\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">preview\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { min\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; max\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; mean\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> };\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">matchedPattern\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// True if name matches channel pattern\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface WideFormatDetection { isWideFormat: boolean; // True if wide format detected with sufficient confidence channels: ChannelInfo[]; // Detected channel columns with preview stats metadataColumns: string[]; // Non-channel columns (date, batch, etc.) confidence: 'high' | 'medium' | 'low'; reason: string; // Explanation of detection result}interface ChannelInfo { id: string; // Column name label: string; // Display name n: number; // Valid value count preview: { min: number; max: number; mean: number }; matchedPattern: boolean; // True if name matches channel pattern}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"integration-with-usedataingestion\">Integration with useDataIngestion\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#integration-with-usedataingestion\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integration with useDataIngestion”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">useDataIngestion\u003C/code> hook from \u003Ccode dir=\"auto\">@variscout/hooks\u003C/code> triggers wide-format detection after file upload:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useDataIngestion } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/hooks\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleFileUpload\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useDataIngestion\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onWideFormatDetected\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">detection\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#FFCB8B\">WideFormatDetection\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Show PerformanceDetectedModal to user\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setShowPerformanceModal\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setPendingDetection\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(detection)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useDataIngestion } from '@variscout/hooks';const { handleFileUpload } = useDataIngestion({ onWideFormatDetected: (detection: WideFormatDetection) => { // Show PerformanceDetectedModal to user setShowPerformanceModal(true); setPendingDetection(detection); },});\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The callback fires when:\u003C/p>\n\u003Cul>\n\u003Cli>Detection confidence is \u003Ccode dir=\"auto\">high\u003C/code> or \u003Ccode dir=\"auto\">medium\u003C/code>\u003C/li>\n\u003Cli>At least 3 channel columns are found\u003C/li>\n\u003Cli>User hasn’t dismissed the prompt before\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-flow\">User Flow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">File Upload\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">detectWideFormat(data)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─► confidence: high/medium\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ PerformanceDetectedModal\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├─► \"Enable\" → Performance Mode\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ • setPerformanceMode(true)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ • setMeasureColumns(channels)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ • setMeasureLabel(label)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └─► \"Not Now\" → Standard Mode\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─► confidence: low → Continue to ColumnMapping\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"File Upload │ ▼detectWideFormat(data) │ ├─► confidence: high/medium │ │ │ ▼ │ PerformanceDetectedModal │ │ │ ├─► "Enable" → Performance Mode │ │ • setPerformanceMode(true) │ │ • setMeasureColumns(channels) │ │ • setMeasureLabel(label) │ │ │ └─► "Not Now" → Standard Mode │ └─► confidence: low → Continue to ColumnMapping\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"components\">Components\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Components”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Package\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceDetectedModal\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Auto-detection prompt after file upload\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceSetupPanel\u003C/code>\u003C/td>\u003Ctd>App-specific\u003C/td>\u003Ctd>Manual configuration (inline or modal)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">MeasureColumnSelector\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Checkbox list with preview stats for selection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ColumnMapping\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Column selection and validation UI\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">DataQualityBanner\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Validation summary with excluded row info\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performance-mode-features\">Performance Mode Features\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performance-mode-features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Mode Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"cpcpk-metric-toggle\">Cp/Cpk Metric Toggle\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#cpcpk-metric-toggle\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cp/Cpk Metric Toggle”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Performance I-Chart displays capability metrics with a toggle to switch between:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Cpk\u003C/strong> (default) - Process capability index accounting for centering\u003C/li>\n\u003Cli>\u003Cstrong>Cp\u003C/strong> - Potential capability (spread only, ignores centering)\u003C/li>\n\u003C/ul>\n\u003Cp>Toggle location: Top-right of the I-Chart header in Performance Mode.\nTooltip always shows both Cp and Cpk values regardless of selected metric.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// In PerformanceDashboard.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const [\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">capabilityMetric\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setCapabilityMetric\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">] = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useState\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cp\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Passed to chart component\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">PerformanceIChart capabilityMetric\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{capabilityMetric} \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// In PerformanceDashboard.tsxconst [capabilityMetric, setCapabilityMetric] = useState\u003C'cp' | 'cpk'>('cpk');// Passed to chart component\u003CPerformanceIChart capabilityMetric={capabilityMetric} ... />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"drill-down-to-standard-i-chart\">Drill-Down to Standard I-Chart\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#drill-down-to-standard-i-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill-Down to Standard I-Chart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When a measure is selected in Performance Mode, users can drill down to the standard I-Chart for detailed analysis:\u003C/p>\n\u003Col>\n\u003Cli>Click any channel point in the Performance I-Chart to select it\u003C/li>\n\u003Cli>“View in I-Chart →” button appears in the chart header\u003C/li>\n\u003Cli>Click to navigate to standard dashboard with that measure as the outcome variable\u003C/li>\n\u003Cli>“Back to Performance” banner shows at the top for return navigation\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Navigation Flow:\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Performance Mode → Click channel → \"View in I-Chart\" button\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Standard Dashboard (measure as outcome)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─► \"Back to Performance\" → Performance Mode\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─► Continue with standard analysis\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Performance Mode → Click channel → "View in I-Chart" button │ ▼ Standard Dashboard (measure as outcome) │ ├─► "Back to Performance" → Performance Mode │ └─► Continue with standard analysis\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>State Management (App.tsx):\u003C/strong>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Track drill navigation origin\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const [\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">drillFromPerformance\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setDrillFromPerformance\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">] = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useState\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Drill to measure\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleDrillToMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useCallback\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">measureId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setDrillFromPerformance\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(measureId)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setOutcome\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(measureId)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setActiveView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">dashboard\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[setOutcome]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Return to Performance\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleBackToPerformance\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useCallback\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setDrillFromPerformance\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setActiveView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">performance\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">},\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> []);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Track drill navigation originconst [drillFromPerformance, setDrillFromPerformance] = useState\u003Cstring | null>(null);// Drill to measureconst handleDrillToMeasure = useCallback( (measureId: string) => { setDrillFromPerformance(measureId); setOutcome(measureId); setActiveView('dashboard'); }, [setOutcome]);// Return to Performanceconst handleBackToPerformance = useCallback(() => { setDrillFromPerformance(null); setActiveView('performance');}, []);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Dashboard Props:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Prop\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">drillFromPerformance\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string | null\u003C/code>\u003C/td>\u003Ctd>Measure ID if drilled from Perf\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">onBackToPerformance\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">() => void\u003C/code>\u003C/td>\u003Ctd>Callback to return to Perf Mode\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">onDrillToMeasure\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(measureId: string) => void\u003C/code>\u003C/td>\u003Ctd>Callback to drill to standard view\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pareto-data-sources\">Pareto Data Sources\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pareto-data-sources\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pareto Data Sources”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"derived-mode-default\">Derived Mode (Default)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#derived-mode-default\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Derived Mode (Default)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Counts computed from selected factors via \u003Ccode dir=\"auto\">d3.rollup()\u003C/code>\u003C/li>\n\u003Cli>Linked to main data filters (updates when filters change)\u003C/li>\n\u003Cli>Uses \u003Ccode dir=\"auto\">factors[1] || factors[0]\u003C/code> by default\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// In ParetoChart.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">counts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">d3\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">rollup\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">v\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">v\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">length\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">d[factor]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// In ParetoChart.tsxconst counts = d3.rollup( filteredData, v => v.length, d => d[factor]);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"separate-mode\">Separate Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#separate-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Separate Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For pre-aggregated count data (e.g., from ERP/MES systems):\u003C/p>\n\u003Cul>\n\u003Cli>Upload separate CSV/Excel file in ColumnMapping\u003C/li>\n\u003Cli>Auto-detects category (first string) and count (first numeric) columns\u003C/li>\n\u003Cli>\u003Cstrong>NOT linked to main data filters\u003C/strong>\u003C/li>\n\u003Cli>Shows info banner: “Using separate Pareto file (not linked to filters)“\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"paretorow-interface\">ParetoRow Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#paretorow-interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ParetoRow Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ParetoRow {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">category\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">count\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ParetoRow { category: string; count: number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"state-in-datacontext\">State in DataContext\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#state-in-datacontext\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “State in DataContext”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mode selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">paretoMode: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">derived\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">separate\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Separate Pareto data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">separateParetoData: ParetoRow[] \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">separateParetoFilename: string \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Setters\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setParetoMode: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">mode\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">derived\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">separate\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setSeparateParetoData: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ParetoRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[] \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setSeparateParetoFilename: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Mode selectionparetoMode: 'derived' | 'separate';// Separate Pareto dataseparateParetoData: ParetoRow[] | null;separateParetoFilename: string | null;// SetterssetParetoMode: (mode: 'derived' | 'separate') => void;setSeparateParetoData: (data: ParetoRow[] | null) => void;setSeparateParetoFilename: (name: string | null) => void;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"separate-pareto-file-format\">Separate Pareto File Format\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#separate-pareto-file-format\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Separate Pareto File Format”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>CSV or Excel with at least two columns:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"csv\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Category,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Count\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Machine A,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">45\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Machine B,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">32\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Machine C,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">18\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Category,CountMachine A,45Machine B,32Machine C,18\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The parser auto-detects:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Category column\u003C/strong>: First string/text column\u003C/li>\n\u003Cli>\u003Cstrong>Count column\u003C/strong>: First numeric column\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performance-limits\">Performance Limits\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performance-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Limits”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Threshold\u003C/th>\u003Cth>PWA Behavior\u003C/th>\u003Cth>Azure Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Below warning (5K / 10K)\u003C/td>\u003Ctd>Loads immediately\u003C/td>\u003Ctd>Loads immediately\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Warning to hard limit\u003C/td>\u003Ctd>Warning prompt (may slow performance)\u003C/td>\u003Ctd>Warning prompt (may slow performance)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Above hard limit (50K / 100K)\u003C/td>\u003Ctd>Rejected with error message\u003C/td>\u003Ctd>Rejected with error message\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Defaults in \u003Ccode dir=\"auto\">packages/hooks/src/useDataIngestion.ts\u003C/code>, configurable via \u003Ccode dir=\"auto\">DataIngestionConfig\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">DEFAULT_ROW_WARNING_THRESHOLD\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">5000\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">DEFAULT_ROW_HARD_LIMIT\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">50000\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Azure wrapper overrides:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ rowHardLimit: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100_000\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, rowWarningThreshold: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">10_000\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const DEFAULT_ROW_WARNING_THRESHOLD = 5000;const DEFAULT_ROW_HARD_LIMIT = 50000;// Azure wrapper overrides:{ rowHardLimit: 100_000, rowWarningThreshold: 10_000 }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"supported-file-formats\">Supported File Formats\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#supported-file-formats\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Supported File Formats”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"csv\">CSV\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#csv\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CSV”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Parsed with PapaParse\u003C/li>\n\u003Cli>UTF-8 encoding recommended\u003C/li>\n\u003Cli>First row = headers\u003C/li>\n\u003Cli>Comma delimiter\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"excel-xlsx-xls\">Excel (.xlsx, .xls)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#excel-xlsx-xls\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Excel (.xlsx, .xls)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Parsed with SheetJS (xlsx library)\u003C/li>\n\u003Cli>First sheet only\u003C/li>\n\u003Cli>First row = headers\u003C/li>\n\u003Cli>Numeric columns should be formatted as numbers\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-functions\">Key Functions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-functions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Functions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"parser-from-variscoutcore\">parser/ (from @variscout/core)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#parser-from-variscoutcore\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “parser/ (from @variscout/core)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Function\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">parseCSV(file)\u003C/code>\u003C/td>\u003Ctd>Parse CSV file to array of objects\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">parseExcel(file)\u003C/code>\u003C/td>\u003Ctd>Parse Excel file to array of objects\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">detectColumns(data)\u003C/code>\u003C/td>\u003Ctd>Auto-detect column roles with keyword matching\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">validateData(data, outcome)\u003C/code>\u003C/td>\u003Ctd>Validate rows and return quality report\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">parseParetoFile(file)\u003C/code>\u003C/td>\u003Ctd>Parse separate Pareto file to ParetoRow[]\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">detectWideFormat(data)\u003C/code>\u003C/td>\u003Ctd>Auto-detect multi-channel wide format data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">detectChannelColumns(data)\u003C/code>\u003C/td>\u003Ctd>Find numeric columns that appear to be channels\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usedataingestion-from-variscouthooks\">useDataIngestion (from @variscout/hooks)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usedataingestion-from-variscouthooks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useDataIngestion (from @variscout/hooks)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Function\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">handleFileUpload(e)\u003C/code>\u003C/td>\u003Ctd>Main file upload handler\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">handleParetoFileUpload(file)\u003C/code>\u003C/td>\u003Ctd>Separate Pareto file handler\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">clearParetoFile()\u003C/code>\u003C/td>\u003Ctd>Reset to derived Pareto mode\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">clearData()\u003C/code>\u003C/td>\u003Ctd>Reset all data state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">applyTimeExtraction(col, config)\u003C/code>\u003C/td>\u003Ctd>Augment data with time-derived factor columns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">onWideFormatDetected\u003C/code>\u003C/td>\u003Ctd>Callback when wide format data is detected\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">onTimeColumnDetected\u003C/code>\u003C/td>\u003Ctd>Callback when a date/time column is detected\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Note: \u003Ccode dir=\"auto\">loadSample()\u003C/code> is added by the PWA-specific wrapper in \u003Ccode dir=\"auto\">apps/pwa/src/hooks/useDataIngestion.ts\u003C/code>.\u003C/p>", + { + "headings": 8406, + "localImagePaths": 8504, + "remoteImagePaths": 8505, + "frontmatter": 8506, + "imagePaths": 8507 + }, + [ + 8407, 8409, 8412, 8415, 8416, 8419, 8420, 8423, 8424, 8425, 8428, 8431, 8434, 8437, 8438, 8441, + 8444, 8447, 8449, 8452, 8455, 8456, 8459, 8462, 8465, 8468, 8471, 8474, 8477, 8480, 8483, 8486, + 8489, 8492, 8495, 8498, 8501 + ], + { "depth": 30, "slug": 8408, "text": 8396 }, + "data-input-system", + { "depth": 33, "slug": 8410, "text": 8411 }, + "file-locations", + "File Locations", + { "depth": 33, "slug": 8413, "text": 8414 }, + "smart-auto-mapping", + "Smart Auto-Mapping", + { "depth": 79, "slug": 8132, "text": 8133 }, + { "depth": 79, "slug": 8417, "text": 8418 }, + "detection-algorithm", + "Detection Algorithm", + { "depth": 79, "slug": 6943, "text": 6944 }, + { "depth": 79, "slug": 8421, "text": 8422 }, + "return-type", + "Return Type", + { "depth": 33, "slug": 1227, "text": 1228 }, + { "depth": 79, "slug": 6990, "text": 6991 }, + { "depth": 79, "slug": 8426, "text": 8427 }, + "dataqualityreport-interface", + "DataQualityReport Interface", + { "depth": 79, "slug": 8429, "text": 8430 }, + "validation-flow", + "Validation Flow", + { "depth": 79, "slug": 8432, "text": 8433 }, + "user-interface", + "User Interface", + { "depth": 33, "slug": 8435, "text": 8436 }, + "wide-format-multi-measure-data-detection", + "Wide-Format (Multi-Measure) Data Detection", + { "depth": 79, "slug": 2296, "text": 2297 }, + { "depth": 79, "slug": 8439, "text": 8440 }, + "channel-naming-patterns", + "Channel Naming Patterns", + { "depth": 79, "slug": 8442, "text": 8443 }, + "confidence-levels", + "Confidence Levels", + { "depth": 79, "slug": 8445, "text": 8446 }, + "detection-options", + "Detection Options", + { "depth": 79, "slug": 8448, "text": 8422 }, + "return-type-1", + { "depth": 79, "slug": 8450, "text": 8451 }, + "integration-with-usedataingestion", + "Integration with useDataIngestion", + { "depth": 79, "slug": 8453, "text": 8454 }, + "user-flow", + "User Flow", + { "depth": 79, "slug": 2002, "text": 2003 }, + { "depth": 79, "slug": 8457, "text": 8458 }, + "performance-mode-features", + "Performance Mode Features", + { "depth": 621, "slug": 8460, "text": 8461 }, + "cpcpk-metric-toggle", + "Cp/Cpk Metric Toggle", + { "depth": 621, "slug": 8463, "text": 8464 }, + "drill-down-to-standard-i-chart", + "Drill-Down to Standard I-Chart", + { "depth": 33, "slug": 8466, "text": 8467 }, + "pareto-data-sources", + "Pareto Data Sources", + { "depth": 79, "slug": 8469, "text": 8470 }, + "derived-mode-default", + "Derived Mode (Default)", + { "depth": 79, "slug": 8472, "text": 8473 }, + "separate-mode", + "Separate Mode", + { "depth": 79, "slug": 8475, "text": 8476 }, + "paretorow-interface", + "ParetoRow Interface", + { "depth": 79, "slug": 8478, "text": 8479 }, + "state-in-datacontext", + "State in DataContext", + { "depth": 79, "slug": 8481, "text": 8482 }, + "separate-pareto-file-format", + "Separate Pareto File Format", + { "depth": 33, "slug": 8484, "text": 8485 }, + "performance-limits", + "Performance Limits", + { "depth": 33, "slug": 8487, "text": 8488 }, + "supported-file-formats", + "Supported File Formats", + { "depth": 79, "slug": 8490, "text": 8491 }, + "csv", + "CSV", + { "depth": 79, "slug": 8493, "text": 8494 }, + "excel-xlsx-xls", + "Excel (.xlsx, .xls)", + { "depth": 33, "slug": 8496, "text": 8497 }, + "key-functions", + "Key Functions", + { "depth": 79, "slug": 8499, "text": 8500 }, + "parser-from-variscoutcore", + "parser/ (from @variscout/core)", + { "depth": 79, "slug": 8502, "text": 8503 }, + "usedataingestion-from-variscouthooks", + "useDataIngestion (from @variscout/hooks)", + [], + [], + { "title": 8396 }, + [], + "05-technical/implementation/deployment", + { "id": 8508, "data": 8510, "body": 8515, "filePath": 8516, "digest": 8517, "rendered": 8518 }, + { + "title": 8511, + "editUrl": 16, + "head": 8512, + "template": 18, + "sidebar": 8513, + "pagefind": 16, + "draft": 20 + }, + "Deployment Guide", + [], + { "hidden": 20, "attrs": 8514 }, + {}, + "# Deployment Guide\n\nThis document covers build commands, deployment workflows, and environment configurations for VariScout applications.\n\n---\n\n## Distribution Channels\n\n| Product | Distribution | Target |\n| --------- | ----------------- | -------------------- |\n| Azure App | Azure Marketplace | Enterprise customers |\n| PWA | Public URL | Training & education |\n| Website | Vercel | Marketing |\n\nSee [ADR-007: Azure Marketplace Distribution](../../07-decisions/adr-007-azure-marketplace-distribution.md) for the distribution strategy.\n\n---\n\n## Build Commands\n\n### Development\n\n```bash\n# PWA development server (localhost:5173)\npnpm dev\n\n# Azure app development server\npnpm --filter @variscout/azure-app dev\n\n# Marketing website development server\npnpm --filter @variscout/website dev\n```\n\n### Production Builds\n\n```bash\n# Build all packages and apps\npnpm build\n\n# Build specific packages\npnpm --filter @variscout/core build\npnpm --filter @variscout/charts build\npnpm --filter @variscout/azure-app build\n```\n\n### Testing\n\n```bash\n# Run all tests\npnpm test\n\n# Run tests with coverage\npnpm test -- --coverage\n\n# Package-specific tests\npnpm --filter @variscout/core test\npnpm --filter @variscout/pwa test\npnpm --filter @variscout/azure-app test\n```\n\n---\n\n## Environment Configuration\n\n### Azure App Environment Variables\n\n| Variable | Description | Required | Set By |\n| ------------------------------------------ | ---------------------------------- | -------- | ------------ |\n| `VITE_LICENSE_TIER` | License tier (always `enterprise`) | Yes | ARM template |\n| `WEBSITE_RUN_FROM_PACKAGE` | Package deployment URL | Yes | ARM template |\n| `MICROSOFT_PROVIDER_AUTHENTICATION_SECRET` | EasyAuth client secret | Yes | ARM template |\n\n> **Note**: MSAL-era variables (`VITE_AZURE_CLIENT_ID`, `VITE_AZURE_TENANT_ID`, `VITE_AZURE_REDIRECT_URI`, `VITE_MAX_USERS`, `VITE_MAX_CHANNELS`) are no longer used. Authentication is handled by EasyAuth (App Service Authentication), not MSAL.\n\n### PWA Environment Variables\n\n| Variable | Description | Default |\n| ------------------ | ----------------------- | ------------ |\n| `VITE_APP_VERSION` | App version for display | package.json |\n\n> **Note**: The `VITE_LICENSE_API_URL` and `VITE_EDITION` variables are deprecated and no longer used.\n\n---\n\n## Azure Marketplace Publication\n\n### Overview\n\nThe Azure App is published to Azure Marketplace as a **Managed Application**:\n\n```\nAzure Marketplace\n└── VariScout (Managed Application)\n ├── Standard Plan (€99/month, full analysis, local files)\n └── Team Plan (€299/month, + Teams, OneDrive, SharePoint)\n```\n\n### Publication Process\n\n1. **Partner Center Setup**\n - Register at [Partner Center](https://partner.microsoft.com/)\n - Complete publisher profile\n - Enable Azure Marketplace program\n\n2. **Create Azure Application Offer**\n - Offer type: Managed Application\n - Two plans: Standard (€99/month) and Team (€299/month)\n - Upload deployment package (.zip with mainTemplate.json + createUiDefinition.json)\n - Publisher management: Disabled (zero access)\n - Customer access: Enabled (full control)\n\n3. **Configure Pricing**\n - Set monthly prices (Standard €99, Team €299)\n - Configure regional pricing (EUR, USD, GBP)\n - Microsoft handles VAT and billing (3% fee)\n\n4. **Submit for Certification**\n - Microsoft reviews listing content\n - Automated ARM template validation\n - Security assessment\n - Timeline: 5-10 business days\n\nSee [Azure Marketplace Guide](../../08-products/azure/marketplace.md) for detailed instructions.\n\n### ARM Template Deployment\n\nCustomers deploy via ARM template:\n\n```bash\naz deployment group create \\\n --resource-group rg-variscout \\\n --template-uri https://raw.githubusercontent.com/variscout/azure-deploy/main/azuredeploy.json\n```\n\nSee [ARM Template Documentation](../../08-products/azure/arm-template.md) for template details.\n\n---\n\n## Deployment Targets\n\n### Azure App — Staging (CI/CD)\n\nThe staging environment deploys automatically on push to `main` via GitHub Actions with OIDC authentication (no long-lived secrets).\n\n**URL**: `https://variscout-staging.azurewebsites.net`\n\n**Architecture**: The Vite build output (`apps/azure/dist/`) is served by a zero-dependency Node.js static server (`apps/azure/server.js`) running on App Service Linux (Node 22). The server provides:\n\n- SPA fallback routing (all non-file paths → `index.html`)\n- Cache headers (hashed `/assets/*` get 1-year immutable, rest `no-cache`)\n- Security headers on every response: CSP, HSTS (1 year, includeSubDomains), X-Content-Type-Options, Referrer-Policy, Permissions-Policy\n- Dynamic `connect-src` in CSP: includes `graph.microsoft.com` and OBO function URL (from `FUNCTION_URL` env var)\n- Health endpoint (`GET /health` → 200)\n- SIGTERM graceful shutdown (closes server, exits cleanly)\n- Listens on `process.env.PORT` (set by App Service)\n\nEasyAuth intercepts `/.auth/*` at the platform level before the Node server — no conflict.\n\n**Pipeline** (`.github/workflows/deploy-azure-staging.yml`):\n\n1. pnpm install + build Azure app\n2. `pnpm audit --audit-level=high` — fail on high/critical vulnerabilities\n3. Generate CycloneDX SBOM (`sbom.json`) and upload as build artifact\n4. Assemble zip: `dist/` + `server.js` + minimal `package.json`\n5. OIDC login → `azure/webapps-deploy@v3`\n6. Health check (`GET /health`) — verifies deployment stability\n7. (Conditional, separate job) Deploy OBO token-exchange Azure Function — runs only when `AZURE_FUNCTION_APP_NAME` variable is set; deploys `infra/functions/` via `azure/functions-action@v2`\n\n### Supply Chain Security\n\n- **Dependabot** (`.github/dependabot.yml`): weekly updates for both npm and GitHub Actions ecosystems\n- **SHA-pinned actions**: all 6 GitHub Actions use commit SHA (not version tags) to prevent supply chain attacks via tag mutation\n- **SBOM**: CycloneDX JSON generated per build, uploaded as artifact for audit trail\n\n**GitHub secrets** (3, all OIDC — no credentials stored):\n\n- `AZURE_CLIENT_ID` — Service principal for CI/CD deployment\n- `AZURE_TENANT_ID` — AAD tenant\n- `AZURE_SUBSCRIPTION_ID` — Target subscription\n\n**Azure resources** (in `rg-variscout-staging`):\n\n- App Service Plan (B1 Linux)\n- App Service (`variscout-staging`) with EasyAuth (AAD)\n- App Registration (\"VariScout Staging\") with `User.Read` + `Files.ReadWrite` permissions (Files.ReadWrite only needed for Team plan)\n- Separate App Registration (\"VariScout CI/CD\") with federated credential for GitHub Actions OIDC\n\n**One-time setup**: See [Azure Staging Setup](#azure-staging-setup) below.\n\n### Azure App — Marketplace (Production)\n\nDeployed via ARM template to customer's Azure subscription:\n\n```yaml\n# App Service configuration (in ARM template)\nresource:\n type: Microsoft.Web/sites # App Service, not Static Web Apps\n apiVersion: 2025-01-01\n name: variscout-{unique}\n kind: linux\n plan: B1 Basic (Linux, Node 22)\n deployment: WEBSITE_RUN_FROM_PACKAGE\n```\n\n### Marketing Website (Vercel)\n\nStatic Astro 5 site deployed to Vercel:\n\n| Setting | Value |\n| --------------------- | ---------------------------------------- |\n| Framework | Astro 5 (static output) |\n| Build command | `pnpm --filter @variscout/website build` |\n| Output directory | `apps/website/dist` |\n| Deploy trigger | Push to `main` branch |\n| Environment variables | None required |\n| Pages generated | 379 (5 languages × dynamic routes) |\n\nThe website is fully static — no server-side code, no database, no runtime environment variables. Workspace packages (`@variscout/core`, `@variscout/charts`, `@variscout/data`) are resolved at build time for chart demos.\n\nSecurity headers (CSP, Permissions-Policy, X-Content-Type-Options) configured in `apps/website/vercel.json`. Vulnerability disclosure via `/.well-known/security.txt`.\n\nSee `apps/website/README.md` for the development guide.\n\n### PWA (Internal Hosting)\n\nFor demos and development only:\n\n```yaml\n# Static hosting (internal)\n{ 'buildCommand': 'pnpm build', 'outputDirectory': 'apps/pwa/dist' }\n```\n\nSecurity headers (CSP, Permissions-Policy) configured in `apps/pwa/vercel.json`. Service worker (`sw.js`) served with `no-cache` to ensure prompt updates.\n\n---\n\n## Azure App Registration Requirements\n\n### Required for Azure App\n\nThe customer creates an App Registration before deployment (the ARM template references it via `clientId` and `clientSecret` parameters):\n\n| Permission | Type | Purpose | Plan |\n| ----------------- | --------- | --------------------- | --------- |\n| `User.Read` | Delegated | Get user profile | All |\n| `Files.ReadWrite` | Delegated | OneDrive project sync | Team only |\n\n> **Note**: Standard plan deployments only require `User.Read`. The `Files.ReadWrite` permission is needed only for Team plan OneDrive sync. Standard plan stores data locally in IndexedDB.\n\n---\n\n## Pre-Deployment Checklist\n\n### Before Any Deployment\n\n- [ ] All tests passing (`pnpm test`)\n- [ ] Build completes without errors (`pnpm build`)\n- [ ] No TypeScript errors (`pnpm tsc`)\n- [ ] Version numbers updated if releasing\n- [ ] Security scan (`npx ruflo@latest security scan`)\n\n### Azure Marketplace Submission\n\n- [ ] ARM template validates (`az deployment group validate`)\n- [ ] Partner Center account verified\n- [ ] Privacy policy URL accessible\n- [ ] Terms of service URL accessible\n- [ ] All screenshots meet requirements\n- [ ] Pricing configured for all regions\n\n### Azure App Deployment (Per-Customer)\n\n- [ ] Customer has Azure subscription\n- [ ] ARM template deploys successfully\n- [ ] EasyAuth authentication works\n\n---\n\n## Rollback Procedures\n\n### Azure App Service\n\nRollback by changing the `WEBSITE_RUN_FROM_PACKAGE` URL to a previous release:\n\n```bash\n# Point to a previous release package\naz webapp config appsettings set \\\n --name variscout-xyz \\\n --resource-group rg-variscout \\\n --settings WEBSITE_RUN_FROM_PACKAGE=\"https://variscout.blob.core.windows.net/releases/variscout-azure-v1.2.0.zip\"\n\n# Restart to pick up the change\naz webapp restart --name variscout-xyz --resource-group rg-variscout\n```\n\n### ARM Template Updates\n\nFor template updates:\n\n1. Update template in repository\n2. Submit new version to Partner Center\n3. Existing deployments unaffected\n4. New deployments use new template\n\n---\n\n## Monitoring\n\n### Azure App (Customer-Owned)\n\nCustomers can add Application Insights:\n\n```json\n// Optional in ARM template\n{\n \"type\": \"Microsoft.Insights/components\",\n \"apiVersion\": \"2020-02-02\",\n \"name\": \"variscout-insights\",\n \"properties\": {\n \"Application_Type\": \"web\"\n }\n}\n```\n\n### Partner Center Analytics\n\n- Azure Marketplace: Sales, deployments, usage\n\n---\n\n## Azure Staging Setup\n\nOne-time setup commands for the rdmaic staging environment. Run these with `az cli` authenticated to the Perus-RDMAIC subscription.\n\n### 1. Create App Registration (EasyAuth — user login)\n\n```bash\naz ad app create --display-name \"VariScout Staging\" --sign-in-audience AzureADMyOrg\n# → note appId as CLIENT_ID\n\naz ad app update --id $CLIENT_ID \\\n --web-redirect-uris \"https://variscout-staging.azurewebsites.net/.auth/login/aad/callback\"\n\n# Graph API permissions: User.Read (all plans) + Files.ReadWrite (Team plan OneDrive sync)\naz ad app permission add --id $CLIENT_ID \\\n --api 00000003-0000-0000-c000-000000000000 \\\n --api-permissions \"e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope\" \\\n \"5c28c081-612b-4536-8c00-47d2f7f0de0a=Scope\"\n# Note: Files.ReadWrite is only used by Team plan. Standard plan stores data locally in IndexedDB.\n\naz ad app credential reset --id $CLIENT_ID --display-name \"EasyAuth-Staging\" --years 2\n# → note password as CLIENT_SECRET (shown once)\n```\n\n### 2. Create Service Principal (GitHub Actions OIDC — CI/CD)\n\n```bash\naz ad app create --display-name \"VariScout CI/CD\"\n# → note appId as CICD_CLIENT_ID\n\naz ad sp create --id $CICD_CLIENT_ID\n\naz role assignment create \\\n --role \"Website Contributor\" \\\n --assignee $CICD_CLIENT_ID \\\n --scope /subscriptions/f6766ade-aab2-4f13-845a-30eda447e379/resourceGroups/rg-variscout-staging\n\naz ad app federated-credential create --id $CICD_CLIENT_ID \\\n --parameters '{\n \"name\": \"github-actions-main\",\n \"issuer\": \"https://token.actions.githubusercontent.com\",\n \"subject\": \"repo:jukka-matti/variscout:ref:refs/heads/main\",\n \"audiences\": [\"api://AzureADTokenExchange\"]\n }'\n```\n\n### 3. Deploy infrastructure\n\n```bash\naz group create --name rg-variscout-staging --location northeurope\n\naz deployment group create \\\n --resource-group rg-variscout-staging \\\n --template-file infra/mainTemplate.json \\\n --parameters \\\n appName=variscout-staging \\\n clientId=$CLIENT_ID \\\n clientSecret=$CLIENT_SECRET \\\n packageUrl=\"1\"\n```\n\n### 4. Configure App Service\n\n```bash\n# Startup command (Node 14+ does not auto-start with PM2)\naz webapp config set \\\n --name variscout-staging \\\n --resource-group rg-variscout-staging \\\n --startup-file \"node server.js\"\n\n# Health check\naz webapp config set \\\n --name variscout-staging \\\n --resource-group rg-variscout-staging \\\n --generic-configurations '{\"healthCheckPath\": \"/health\"}'\n```\n\n### 5. Configure GitHub secrets\n\n```bash\ngh secret set AZURE_CLIENT_ID --repo jukka-matti/variscout --body \"$CICD_CLIENT_ID\"\ngh secret set AZURE_TENANT_ID --repo jukka-matti/variscout --body \"\u003Ctenant-id>\"\ngh secret set AZURE_SUBSCRIPTION_ID --repo jukka-matti/variscout --body \"f6766ade-aab2-4f13-845a-30eda447e379\"\n```\n\n### 6. First deploy\n\nTrigger via `workflow_dispatch` or push a change to `main`.\n\n### Verification\n\n- `https://variscout-staging.azurewebsites.net` → AAD login redirect\n- `https://variscout-staging.azurewebsites.net/health` → 200\n- Deep URL refresh → SPA serves `index.html` (not 404)\n\n---\n\n## Next Steps\n\n1. Complete Azure Marketplace Partner Center setup\n2. Submit Azure App offer for certification\n3. Configure production telemetry\n\n---\n\n## See Also\n\n- [Azure Marketplace Guide](../../08-products/azure/marketplace.md)\n- [ARM Template](../../08-products/azure/arm-template.md)\n- [ADR-007: Distribution Strategy](../../07-decisions/adr-007-azure-marketplace-distribution.md)", + "src/content/docs/05-technical/implementation/deployment.md", + "6b87c180b1ea2b07", + { "html": 8519, "metadata": 8520 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"deployment-guide\">Deployment Guide\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#deployment-guide\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment Guide”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This document covers build commands, deployment workflows, and environment configurations for VariScout applications.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"distribution-channels\">Distribution Channels\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#distribution-channels\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Distribution Channels”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth>Distribution\u003C/th>\u003Cth>Target\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Azure App\u003C/td>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>Enterprise customers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>PWA\u003C/td>\u003Ctd>Public URL\u003C/td>\u003Ctd>Training & education\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Website\u003C/td>\u003Ctd>Vercel\u003C/td>\u003Ctd>Marketing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"../../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007: Azure Marketplace Distribution\u003C/a> for the distribution strategy.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"build-commands\">Build Commands\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#build-commands\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Build Commands”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"development\">Development\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#development\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Development”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># PWA development server (localhost:5173)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Azure app development server\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Marketing website development server\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/website\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm devpnpm --filter @variscout/azure-app devpnpm --filter @variscout/website dev\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"production-builds\">Production Builds\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#production-builds\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Production Builds”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build all packages and apps\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build specific packages\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm buildpnpm --filter @variscout/core buildpnpm --filter @variscout/charts buildpnpm --filter @variscout/azure-app build\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"testing\">Testing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#testing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Testing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run all tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run tests with coverage\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--coverage\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Package-specific tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/pwa\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm testpnpm test -- --coveragepnpm --filter @variscout/core testpnpm --filter @variscout/pwa testpnpm --filter @variscout/azure-app test\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"environment-configuration\">Environment Configuration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#environment-configuration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Environment Configuration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-app-environment-variables\">Azure App Environment Variables\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-environment-variables\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App Environment Variables”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variable\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Required\u003C/th>\u003Cth>Set By\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">VITE_LICENSE_TIER\u003C/code>\u003C/td>\u003Ctd>License tier (always \u003Ccode dir=\"auto\">enterprise\u003C/code>)\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>ARM template\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">WEBSITE_RUN_FROM_PACKAGE\u003C/code>\u003C/td>\u003Ctd>Package deployment URL\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>ARM template\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\u003C/code>\u003C/td>\u003Ctd>EasyAuth client secret\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>ARM template\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note\u003C/strong>: MSAL-era variables (\u003Ccode dir=\"auto\">VITE_AZURE_CLIENT_ID\u003C/code>, \u003Ccode dir=\"auto\">VITE_AZURE_TENANT_ID\u003C/code>, \u003Ccode dir=\"auto\">VITE_AZURE_REDIRECT_URI\u003C/code>, \u003Ccode dir=\"auto\">VITE_MAX_USERS\u003C/code>, \u003Ccode dir=\"auto\">VITE_MAX_CHANNELS\u003C/code>) are no longer used. Authentication is handled by EasyAuth (App Service Authentication), not MSAL.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-environment-variables\">PWA Environment Variables\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-environment-variables\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA Environment Variables”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variable\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Default\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">VITE_APP_VERSION\u003C/code>\u003C/td>\u003Ctd>App version for display\u003C/td>\u003Ctd>package.json\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note\u003C/strong>: The \u003Ccode dir=\"auto\">VITE_LICENSE_API_URL\u003C/code> and \u003Ccode dir=\"auto\">VITE_EDITION\u003C/code> variables are deprecated and no longer used.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"azure-marketplace-publication\">Azure Marketplace Publication\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#azure-marketplace-publication\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Marketplace Publication”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"overview\">Overview\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure App is published to Azure Marketplace as a \u003Cstrong>Managed Application\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Azure Marketplace\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── VariScout (Managed Application)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Standard Plan (€99/month, full analysis, local files)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Team Plan (€299/month, + Teams, OneDrive, SharePoint)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Azure Marketplace└── VariScout (Managed Application) ├── Standard Plan (€99/month, full analysis, local files) └── Team Plan (€299/month, + Teams, OneDrive, SharePoint)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"publication-process\">Publication Process\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#publication-process\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Publication Process”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Partner Center Setup\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Register at \u003Ca href=\"https://partner.microsoft.com/\">Partner Center\u003C/a>\u003C/li>\n\u003Cli>Complete publisher profile\u003C/li>\n\u003Cli>Enable Azure Marketplace program\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Create Azure Application Offer\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Offer type: Managed Application\u003C/li>\n\u003Cli>Two plans: Standard (€99/month) and Team (€299/month)\u003C/li>\n\u003Cli>Upload deployment package (.zip with mainTemplate.json + createUiDefinition.json)\u003C/li>\n\u003Cli>Publisher management: Disabled (zero access)\u003C/li>\n\u003Cli>Customer access: Enabled (full control)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Configure Pricing\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Set monthly prices (Standard €99, Team €299)\u003C/li>\n\u003Cli>Configure regional pricing (EUR, USD, GBP)\u003C/li>\n\u003Cli>Microsoft handles VAT and billing (3% fee)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Submit for Certification\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Microsoft reviews listing content\u003C/li>\n\u003Cli>Automated ARM template validation\u003C/li>\n\u003Cli>Security assessment\u003C/li>\n\u003Cli>Timeline: 5-10 business days\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cp>See \u003Ca href=\"../../08-products/azure/marketplace.md\">Azure Marketplace Guide\u003C/a> for detailed instructions.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"arm-template-deployment\">ARM Template Deployment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#arm-template-deployment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ARM Template Deployment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Customers deploy via ARM template:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deployment\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--template-uri\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">https://raw.githubusercontent.com/variscout/azure-deploy/main/azuredeploy.json\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az deployment group create \\ --resource-group rg-variscout \\ --template-uri https://raw.githubusercontent.com/variscout/azure-deploy/main/azuredeploy.json\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>See \u003Ca href=\"../../08-products/azure/arm-template.md\">ARM Template Documentation\u003C/a> for template details.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"deployment-targets\">Deployment Targets\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#deployment-targets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment Targets”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-app--staging-cicd\">Azure App — Staging (CI/CD)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app--staging-cicd\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App — Staging (CI/CD)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The staging environment deploys automatically on push to \u003Ccode dir=\"auto\">main\u003C/code> via GitHub Actions with OIDC authentication (no long-lived secrets).\u003C/p>\n\u003Cp>\u003Cstrong>URL\u003C/strong>: \u003Ccode dir=\"auto\">https://variscout-staging.azurewebsites.net\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>Architecture\u003C/strong>: The Vite build output (\u003Ccode dir=\"auto\">apps/azure/dist/\u003C/code>) is served by a zero-dependency Node.js static server (\u003Ccode dir=\"auto\">apps/azure/server.js\u003C/code>) running on App Service Linux (Node 22). The server provides:\u003C/p>\n\u003Cul>\n\u003Cli>SPA fallback routing (all non-file paths → \u003Ccode dir=\"auto\">index.html\u003C/code>)\u003C/li>\n\u003Cli>Cache headers (hashed \u003Ccode dir=\"auto\">/assets/*\u003C/code> get 1-year immutable, rest \u003Ccode dir=\"auto\">no-cache\u003C/code>)\u003C/li>\n\u003Cli>Security headers on every response: CSP, HSTS (1 year, includeSubDomains), X-Content-Type-Options, Referrer-Policy, Permissions-Policy\u003C/li>\n\u003Cli>Dynamic \u003Ccode dir=\"auto\">connect-src\u003C/code> in CSP: includes \u003Ccode dir=\"auto\">graph.microsoft.com\u003C/code> and OBO function URL (from \u003Ccode dir=\"auto\">FUNCTION_URL\u003C/code> env var)\u003C/li>\n\u003Cli>Health endpoint (\u003Ccode dir=\"auto\">GET /health\u003C/code> → 200)\u003C/li>\n\u003Cli>SIGTERM graceful shutdown (closes server, exits cleanly)\u003C/li>\n\u003Cli>Listens on \u003Ccode dir=\"auto\">process.env.PORT\u003C/code> (set by App Service)\u003C/li>\n\u003C/ul>\n\u003Cp>EasyAuth intercepts \u003Ccode dir=\"auto\">/.auth/*\u003C/code> at the platform level before the Node server — no conflict.\u003C/p>\n\u003Cp>\u003Cstrong>Pipeline\u003C/strong> (\u003Ccode dir=\"auto\">.github/workflows/deploy-azure-staging.yml\u003C/code>):\u003C/p>\n\u003Col>\n\u003Cli>pnpm install + build Azure app\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">pnpm audit --audit-level=high\u003C/code> — fail on high/critical vulnerabilities\u003C/li>\n\u003Cli>Generate CycloneDX SBOM (\u003Ccode dir=\"auto\">sbom.json\u003C/code>) and upload as build artifact\u003C/li>\n\u003Cli>Assemble zip: \u003Ccode dir=\"auto\">dist/\u003C/code> + \u003Ccode dir=\"auto\">server.js\u003C/code> + minimal \u003Ccode dir=\"auto\">package.json\u003C/code>\u003C/li>\n\u003Cli>OIDC login → \u003Ccode dir=\"auto\">azure/webapps-deploy@v3\u003C/code>\u003C/li>\n\u003Cli>Health check (\u003Ccode dir=\"auto\">GET /health\u003C/code>) — verifies deployment stability\u003C/li>\n\u003Cli>(Conditional, separate job) Deploy OBO token-exchange Azure Function — runs only when \u003Ccode dir=\"auto\">AZURE_FUNCTION_APP_NAME\u003C/code> variable is set; deploys \u003Ccode dir=\"auto\">infra/functions/\u003C/code> via \u003Ccode dir=\"auto\">azure/functions-action@v2\u003C/code>\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"supply-chain-security\">Supply Chain Security\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#supply-chain-security\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Supply Chain Security”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Dependabot\u003C/strong> (\u003Ccode dir=\"auto\">.github/dependabot.yml\u003C/code>): weekly updates for both npm and GitHub Actions ecosystems\u003C/li>\n\u003Cli>\u003Cstrong>SHA-pinned actions\u003C/strong>: all 6 GitHub Actions use commit SHA (not version tags) to prevent supply chain attacks via tag mutation\u003C/li>\n\u003Cli>\u003Cstrong>SBOM\u003C/strong>: CycloneDX JSON generated per build, uploaded as artifact for audit trail\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>GitHub secrets\u003C/strong> (3, all OIDC — no credentials stored):\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">AZURE_CLIENT_ID\u003C/code> — Service principal for CI/CD deployment\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">AZURE_TENANT_ID\u003C/code> — AAD tenant\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">AZURE_SUBSCRIPTION_ID\u003C/code> — Target subscription\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Azure resources\u003C/strong> (in \u003Ccode dir=\"auto\">rg-variscout-staging\u003C/code>):\u003C/p>\n\u003Cul>\n\u003Cli>App Service Plan (B1 Linux)\u003C/li>\n\u003Cli>App Service (\u003Ccode dir=\"auto\">variscout-staging\u003C/code>) with EasyAuth (AAD)\u003C/li>\n\u003Cli>App Registration (“VariScout Staging”) with \u003Ccode dir=\"auto\">User.Read\u003C/code> + \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> permissions (Files.ReadWrite only needed for Team plan)\u003C/li>\n\u003Cli>Separate App Registration (“VariScout CI/CD”) with federated credential for GitHub Actions OIDC\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>One-time setup\u003C/strong>: See \u003Ca href=\"#azure-staging-setup\">Azure Staging Setup\u003C/a> below.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-app--marketplace-production\">Azure App — Marketplace (Production)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app--marketplace-production\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App — Marketplace (Production)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Deployed via ARM template to customer’s Azure subscription:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"yaml\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># App Service configuration (in ARM template)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">resource\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Microsoft.Web/sites\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># App Service, not Static Web Apps\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">apiVersion\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">2025-01-01\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-{unique}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">kind\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">linux\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">plan\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">B1 Basic (Linux, Node 22)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">deployment\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">WEBSITE_RUN_FROM_PACKAGE\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"# App Service configuration (in ARM template)resource: type: Microsoft.Web/sites # App Service, not Static Web Apps apiVersion: 2025-01-01 name: variscout-{unique} kind: linux plan: B1 Basic (Linux, Node 22) deployment: WEBSITE_RUN_FROM_PACKAGE\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"marketing-website-vercel\">Marketing Website (Vercel)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#marketing-website-vercel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Marketing Website (Vercel)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Static Astro 5 site deployed to Vercel:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Setting\u003C/th>\u003Cth>Value\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Framework\u003C/td>\u003Ctd>Astro 5 (static output)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Build command\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">pnpm --filter @variscout/website build\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Output directory\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/website/dist\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Deploy trigger\u003C/td>\u003Ctd>Push to \u003Ccode dir=\"auto\">main\u003C/code> branch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Environment variables\u003C/td>\u003Ctd>None required\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pages generated\u003C/td>\u003Ctd>379 (5 languages × dynamic routes)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The website is fully static — no server-side code, no database, no runtime environment variables. Workspace packages (\u003Ccode dir=\"auto\">@variscout/core\u003C/code>, \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>, \u003Ccode dir=\"auto\">@variscout/data\u003C/code>) are resolved at build time for chart demos.\u003C/p>\n\u003Cp>Security headers (CSP, Permissions-Policy, X-Content-Type-Options) configured in \u003Ccode dir=\"auto\">apps/website/vercel.json\u003C/code>. Vulnerability disclosure via \u003Ccode dir=\"auto\">/.well-known/security.txt\u003C/code>.\u003C/p>\n\u003Cp>See \u003Ccode dir=\"auto\">apps/website/README.md\u003C/code> for the development guide.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-internal-hosting\">PWA (Internal Hosting)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-internal-hosting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA (Internal Hosting)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For demos and development only:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"yaml\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Static hosting (internal)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">buildCommand\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pnpm build\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">outputDirectory\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">apps/pwa/dist\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"# Static hosting (internal){ 'buildCommand': 'pnpm build', 'outputDirectory': 'apps/pwa/dist' }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Security headers (CSP, Permissions-Policy) configured in \u003Ccode dir=\"auto\">apps/pwa/vercel.json\u003C/code>. Service worker (\u003Ccode dir=\"auto\">sw.js\u003C/code>) served with \u003Ccode dir=\"auto\">no-cache\u003C/code> to ensure prompt updates.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"azure-app-registration-requirements\">Azure App Registration Requirements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-registration-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App Registration Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"required-for-azure-app\">Required for Azure App\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#required-for-azure-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Required for Azure App”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The customer creates an App Registration before deployment (the ARM template references it via \u003Ccode dir=\"auto\">clientId\u003C/code> and \u003Ccode dir=\"auto\">clientSecret\u003C/code> parameters):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Permission\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Plan\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">User.Read\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Get user profile\u003C/td>\u003Ctd>All\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>OneDrive project sync\u003C/td>\u003Ctd>Team only\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note\u003C/strong>: Standard plan deployments only require \u003Ccode dir=\"auto\">User.Read\u003C/code>. The \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> permission is needed only for Team plan OneDrive sync. Standard plan stores data locally in IndexedDB.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pre-deployment-checklist\">Pre-Deployment Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pre-deployment-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pre-Deployment Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"before-any-deployment\">Before Any Deployment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#before-any-deployment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Before Any Deployment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> All tests passing (\u003Ccode dir=\"auto\">pnpm test\u003C/code>)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Build completes without errors (\u003Ccode dir=\"auto\">pnpm build\u003C/code>)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> No TypeScript errors (\u003Ccode dir=\"auto\">pnpm tsc\u003C/code>)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Version numbers updated if releasing\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Security scan (\u003Ccode dir=\"auto\">npx ruflo@latest security scan\u003C/code>)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-marketplace-submission\">Azure Marketplace Submission\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-marketplace-submission\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Marketplace Submission”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> ARM template validates (\u003Ccode dir=\"auto\">az deployment group validate\u003C/code>)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Partner Center account verified\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Privacy policy URL accessible\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Terms of service URL accessible\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> All screenshots meet requirements\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Pricing configured for all regions\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-app-deployment-per-customer\">Azure App Deployment (Per-Customer)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-deployment-per-customer\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App Deployment (Per-Customer)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Customer has Azure subscription\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> ARM template deploys successfully\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> EasyAuth authentication works\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"rollback-procedures\">Rollback Procedures\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#rollback-procedures\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Rollback Procedures”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-app-service\">Azure App Service\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-service\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App Service”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Rollback by changing the \u003Ccode dir=\"auto\">WEBSITE_RUN_FROM_PACKAGE\u003C/code> URL to a previous release:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Point to a previous release package\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">webapp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">config\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">appsettings\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-xyz\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--settings\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">WEBSITE_RUN_FROM_PACKAGE=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://variscout.blob.core.windows.net/releases/variscout-azure-v1.2.0.zip\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Restart to pick up the change\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">webapp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">restart\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-xyz\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az webapp config appsettings set \\ --name variscout-xyz \\ --resource-group rg-variscout \\ --settings WEBSITE_RUN_FROM_PACKAGE="https://variscout.blob.core.windows.net/releases/variscout-azure-v1.2.0.zip"az webapp restart --name variscout-xyz --resource-group rg-variscout\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"arm-template-updates\">ARM Template Updates\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#arm-template-updates\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ARM Template Updates”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For template updates:\u003C/p>\n\u003Col>\n\u003Cli>Update template in repository\u003C/li>\n\u003Cli>Submit new version to Partner Center\u003C/li>\n\u003Cli>Existing deployments unaffected\u003C/li>\n\u003Cli>New deployments use new template\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"monitoring\">Monitoring\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#monitoring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Monitoring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-app-customer-owned\">Azure App (Customer-Owned)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-customer-owned\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App (Customer-Owned)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Customers can add Application Insights:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Optional in ARM template\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"type\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Microsoft.Insights/components\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"apiVersion\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">2020-02-02\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">variscout-insights\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"properties\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"Application_Type\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">web\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Optional in ARM template{ "type": "Microsoft.Insights/components", "apiVersion": "2020-02-02", "name": "variscout-insights", "properties": { "Application_Type": "web" }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"partner-center-analytics\">Partner Center Analytics\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#partner-center-analytics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Partner Center Analytics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Azure Marketplace: Sales, deployments, usage\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"azure-staging-setup\">Azure Staging Setup\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#azure-staging-setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Staging Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>One-time setup commands for the rdmaic staging environment. Run these with \u003Ccode dir=\"auto\">az cli\u003C/code> authenticated to the Perus-RDMAIC subscription.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-create-app-registration-easyauth--user-login\">1. Create App Registration (EasyAuth — user login)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-create-app-registration-easyauth--user-login\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Create App Registration (EasyAuth — user login)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ad\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--display-name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">VariScout Staging\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--sign-in-audience\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">AzureADMyOrg\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># → note appId as CLIENT_ID\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ad\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">update\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CLIENT_ID\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--web-redirect-uris\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://variscout-staging.azurewebsites.net/.auth/login/aad/callback\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Graph API permissions: User.Read (all plans) + Files.ReadWrite (Team plan OneDrive sync)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ad\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">permission\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CLIENT_ID\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--api\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">00000003-0000-0000-c000-000000000000\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--api-permissions\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">5c28c081-612b-4536-8c00-47d2f7f0de0a=Scope\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Note: Files.ReadWrite is only used by Team plan. Standard plan stores data locally in IndexedDB.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ad\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">credential\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">reset\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CLIENT_ID\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--display-name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">EasyAuth-Staging\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--years\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># → note password as CLIENT_SECRET (shown once)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az ad app create --display-name "VariScout Staging" --sign-in-audience AzureADMyOrgaz ad app update --id $CLIENT_ID \\ --web-redirect-uris "https://variscout-staging.azurewebsites.net/.auth/login/aad/callback"az ad app permission add --id $CLIENT_ID \\ --api 00000003-0000-0000-c000-000000000000 \\ --api-permissions "e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope" \\ "5c28c081-612b-4536-8c00-47d2f7f0de0a=Scope"az ad app credential reset --id $CLIENT_ID --display-name "EasyAuth-Staging" --years 2\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-create-service-principal-github-actions-oidc--cicd\">2. Create Service Principal (GitHub Actions OIDC — CI/CD)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-create-service-principal-github-actions-oidc--cicd\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Create Service Principal (GitHub Actions OIDC — CI/CD)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ad\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--display-name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">VariScout CI/CD\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># → note appId as CICD_CLIENT_ID\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ad\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">sp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CICD_CLIENT_ID\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">role\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">assignment\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--role\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Website Contributor\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--assignee\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CICD_CLIENT_ID\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--scope\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/subscriptions/f6766ade-aab2-4f13-845a-30eda447e379/resourceGroups/rg-variscout-staging\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ad\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">federated-credential\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--id\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CICD_CLIENT_ID\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--parameters\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"name\": \"github-actions-main\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"issuer\": \"https://token.actions.githubusercontent.com\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"subject\": \"repo:jukka-matti/variscout:ref:refs/heads/main\",\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">\"audiences\": [\"api://AzureADTokenExchange\"]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">}\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az ad app create --display-name "VariScout CI/CD"az ad sp create --id $CICD_CLIENT_IDaz role assignment create \\ --role "Website Contributor" \\ --assignee $CICD_CLIENT_ID \\ --scope /subscriptions/f6766ade-aab2-4f13-845a-30eda447e379/resourceGroups/rg-variscout-stagingaz ad app federated-credential create --id $CICD_CLIENT_ID \\ --parameters '{ "name": "github-actions-main", "issuer": "https://token.actions.githubusercontent.com", "subject": "repo:jukka-matti/variscout:ref:refs/heads/main", "audiences": ["api://AzureADTokenExchange"] }'\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-deploy-infrastructure\">3. Deploy infrastructure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-deploy-infrastructure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Deploy infrastructure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-staging\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--location\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">northeurope\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deployment\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-staging\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--template-file\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">infra/mainTemplate.json\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--parameters\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">appName=variscout-staging\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">clientId=\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CLIENT_ID\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">clientSecret=\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CLIENT_SECRET\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">packageUrl=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az group create --name rg-variscout-staging --location northeuropeaz deployment group create \\ --resource-group rg-variscout-staging \\ --template-file infra/mainTemplate.json \\ --parameters \\ appName=variscout-staging \\ clientId=$CLIENT_ID \\ clientSecret=$CLIENT_SECRET \\ packageUrl="1"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-configure-app-service\">4. Configure App Service\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-configure-app-service\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Configure App Service”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Startup command (Node 14+ does not auto-start with PM2)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">webapp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">config\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-staging\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-staging\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--startup-file\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">node server.js\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Health check\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">webapp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">config\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-staging\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout-staging\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--generic-configurations\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">{\"healthCheckPath\": \"/health\"}\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az webapp config set \\ --name variscout-staging \\ --resource-group rg-variscout-staging \\ --startup-file "node server.js"az webapp config set \\ --name variscout-staging \\ --resource-group rg-variscout-staging \\ --generic-configurations '{"healthCheckPath": "/health"}'\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"5-configure-github-secrets\">5. Configure GitHub secrets\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#5-configure-github-secrets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Configure GitHub secrets”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">gh\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">secret\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">AZURE_CLIENT_ID\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--repo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">jukka-matti/variscout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--body\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">$CICD_CLIENT_ID\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">gh\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">secret\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">AZURE_TENANT_ID\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--repo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">jukka-matti/variscout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--body\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"><tenant-id>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">gh\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">secret\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">AZURE_SUBSCRIPTION_ID\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--repo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">jukka-matti/variscout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--body\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">f6766ade-aab2-4f13-845a-30eda447e379\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"gh secret set AZURE_CLIENT_ID --repo jukka-matti/variscout --body "$CICD_CLIENT_ID"gh secret set AZURE_TENANT_ID --repo jukka-matti/variscout --body "\u003Ctenant-id>"gh secret set AZURE_SUBSCRIPTION_ID --repo jukka-matti/variscout --body "f6766ade-aab2-4f13-845a-30eda447e379"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"6-first-deploy\">6. First deploy\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#6-first-deploy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. First deploy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Trigger via \u003Ccode dir=\"auto\">workflow_dispatch\u003C/code> or push a change to \u003Ccode dir=\"auto\">main\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"verification\">Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">https://variscout-staging.azurewebsites.net\u003C/code> → AAD login redirect\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">https://variscout-staging.azurewebsites.net/health\u003C/code> → 200\u003C/li>\n\u003Cli>Deep URL refresh → SPA serves \u003Ccode dir=\"auto\">index.html\u003C/code> (not 404)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"next-steps\">Next Steps\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#next-steps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Next Steps”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Complete Azure Marketplace Partner Center setup\u003C/li>\n\u003Cli>Submit Azure App offer for certification\u003C/li>\n\u003Cli>Configure production telemetry\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../08-products/azure/marketplace.md\">Azure Marketplace Guide\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../08-products/azure/arm-template.md\">ARM Template\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007: Distribution Strategy\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 8521, + "localImagePaths": 8634, + "remoteImagePaths": 8635, + "frontmatter": 8636, + "imagePaths": 8637 + }, + [ + 8522, 8524, 8527, 8528, 8531, 8534, 8537, 8540, 8543, 8546, 8549, 8550, 8553, 8556, 8559, 8562, + 8565, 8568, 8571, 8574, 8577, 8580, 8583, 8586, 8589, 8592, 8595, 8598, 8601, 8604, 8607, 8610, + 8613, 8616, 8619, 8622, 8625, 8628, 8631, 8632, 8633 + ], + { "depth": 30, "slug": 8523, "text": 8511 }, + "deployment-guide", + { "depth": 33, "slug": 8525, "text": 8526 }, + "distribution-channels", + "Distribution Channels", + { "depth": 33, "slug": 2314, "text": 2315 }, + { "depth": 79, "slug": 8529, "text": 8530 }, + "development", + "Development", + { "depth": 79, "slug": 8532, "text": 8533 }, + "production-builds", + "Production Builds", + { "depth": 79, "slug": 8535, "text": 8536 }, + "testing", + "Testing", + { "depth": 33, "slug": 8538, "text": 8539 }, + "environment-configuration", + "Environment Configuration", + { "depth": 79, "slug": 8541, "text": 8542 }, + "azure-app-environment-variables", + "Azure App Environment Variables", + { "depth": 79, "slug": 8544, "text": 8545 }, + "pwa-environment-variables", + "PWA Environment Variables", + { "depth": 33, "slug": 8547, "text": 8548 }, + "azure-marketplace-publication", + "Azure Marketplace Publication", + { "depth": 79, "slug": 447, "text": 448 }, + { "depth": 79, "slug": 8551, "text": 8552 }, + "publication-process", + "Publication Process", + { "depth": 79, "slug": 8554, "text": 8555 }, + "arm-template-deployment", + "ARM Template Deployment", + { "depth": 33, "slug": 8557, "text": 8558 }, + "deployment-targets", + "Deployment Targets", + { "depth": 79, "slug": 8560, "text": 8561 }, + "azure-app--staging-cicd", + "Azure App — Staging (CI/CD)", + { "depth": 79, "slug": 8563, "text": 8564 }, + "supply-chain-security", + "Supply Chain Security", + { "depth": 79, "slug": 8566, "text": 8567 }, + "azure-app--marketplace-production", + "Azure App — Marketplace (Production)", + { "depth": 79, "slug": 8569, "text": 8570 }, + "marketing-website-vercel", + "Marketing Website (Vercel)", + { "depth": 79, "slug": 8572, "text": 8573 }, + "pwa-internal-hosting", + "PWA (Internal Hosting)", + { "depth": 33, "slug": 8575, "text": 8576 }, + "azure-app-registration-requirements", + "Azure App Registration Requirements", + { "depth": 79, "slug": 8578, "text": 8579 }, + "required-for-azure-app", + "Required for Azure App", + { "depth": 33, "slug": 8581, "text": 8582 }, + "pre-deployment-checklist", + "Pre-Deployment Checklist", + { "depth": 79, "slug": 8584, "text": 8585 }, + "before-any-deployment", + "Before Any Deployment", + { "depth": 79, "slug": 8587, "text": 8588 }, + "azure-marketplace-submission", + "Azure Marketplace Submission", + { "depth": 79, "slug": 8590, "text": 8591 }, + "azure-app-deployment-per-customer", + "Azure App Deployment (Per-Customer)", + { "depth": 33, "slug": 8593, "text": 8594 }, + "rollback-procedures", + "Rollback Procedures", + { "depth": 79, "slug": 8596, "text": 8597 }, + "azure-app-service", + "Azure App Service", + { "depth": 79, "slug": 8599, "text": 8600 }, + "arm-template-updates", + "ARM Template Updates", + { "depth": 33, "slug": 8602, "text": 8603 }, + "monitoring", + "Monitoring", + { "depth": 79, "slug": 8605, "text": 8606 }, + "azure-app-customer-owned", + "Azure App (Customer-Owned)", + { "depth": 79, "slug": 8608, "text": 8609 }, + "partner-center-analytics", + "Partner Center Analytics", + { "depth": 33, "slug": 8611, "text": 8612 }, + "azure-staging-setup", + "Azure Staging Setup", + { "depth": 79, "slug": 8614, "text": 8615 }, + "1-create-app-registration-easyauth--user-login", + "1. Create App Registration (EasyAuth — user login)", + { "depth": 79, "slug": 8617, "text": 8618 }, + "2-create-service-principal-github-actions-oidc--cicd", + "2. Create Service Principal (GitHub Actions OIDC — CI/CD)", + { "depth": 79, "slug": 8620, "text": 8621 }, + "3-deploy-infrastructure", + "3. Deploy infrastructure", + { "depth": 79, "slug": 8623, "text": 8624 }, + "4-configure-app-service", + "4. Configure App Service", + { "depth": 79, "slug": 8626, "text": 8627 }, + "5-configure-github-secrets", + "5. Configure GitHub secrets", + { "depth": 79, "slug": 8629, "text": 8630 }, + "6-first-deploy", + "6. First deploy", + { "depth": 79, "slug": 3628, "text": 3629 }, + { "depth": 33, "slug": 7266, "text": 7267 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 8511 }, + [], + "05-technical/implementation/glm-roadmap", + { "id": 8638, "data": 8640, "body": 8645, "filePath": 8646, "digest": 8647, "rendered": 8648 }, + { + "title": 8641, + "editUrl": 16, + "head": 8642, + "template": 18, + "sidebar": 8643, + "pagefind": 16, + "draft": 20 + }, + "GLM Engine Roadmap", + [], + { "hidden": 20, "attrs": 8644 }, + {}, + "# GLM Engine Roadmap\n\n> **Note:** Regression UI has been deferred per [ADR-014](../../07-decisions/adr-014-regression-deferral.md). Core math files (regression.ts, multiRegression.ts, interaction.ts, modelReduction.ts, matrix.ts) are preserved in the repository but unexported from `@variscout/core`. This roadmap applies to Phase 2 re-enablement.\n\nPost-MVP enhancements for VariScout's regression engine. Current implementation uses OLS via the Normal Equations `(X'X)⁻¹X'Y` with categorical dummy coding — the General Linear Model (not Generalized). It works well for typical SPC data (3–6 factors, 100–10K rows, roughly normal distributions).\n\n**Status**: Deferred (Phase 2). See [ADR-014](../../07-decisions/adr-014-regression-deferral.md) for re-enablement criteria.\n\n## Summary\n\n| # | Feature | Complexity | Dependencies | Priority |\n| --- | --------------------------- | ---------- | ----------------------- | -------- |\n| 1 | Distribution Identification | ~250 lines | None | Medium |\n| 2 | Residual Diagnostics | ~20 lines | None | High |\n| 3 | Residual Normality Test | ~150 lines | Feature 2 | High |\n| 4 | QR Decomposition | ~120 lines | None | High |\n| 5 | Leverage + Cook's Distance | ~120 lines | Feature 2 | Medium |\n| 6 | Generalized Linear Models | ~400 lines | Feature 4 (recommended) | Low |\n| 7 | Robust/Weighted Regression | ~200 lines | Feature 4 (recommended) | Low |\n\n## Dependency Graph\n\n```\n1 (Distribution ID) — independent\n\n2 (Residuals) ─────┬───→ 3 (Normality Test)\n └───→ 5 (Leverage/Cook's)\n\n4 (QR Decomposition) ──┬─→ 6 (GLM) [recommended]\n └─→ 7 (Robust Regression) [recommended]\n```\n\nFeatures 1, 2, and 4 can be implemented independently and in parallel. Feature 4 is recommended (not required) before 6 and 7 because IRLS and M-estimation benefit from numerically stable decomposition.\n\n---\n\n## Feature 1: Distribution Identification\n\n**What**: Fit Normal, Lognormal, Weibull, and Exponential distributions to data. Rank by Anderson-Darling goodness-of-fit statistic.\n\n**Why for quality engineers**: SPC assumes normality. When data is non-normal (e.g., cycle times follow Lognormal, failure rates follow Weibull), Cpk calculations are misleading. Distribution identification tells the user which distribution fits best, enabling correct capability analysis.\n\n**Current state**: `calculateProbabilityPlotData()` in `packages/core/src/stats/probability.ts` computes normal Q-Q plot data with Benard ranks. The probability plot visually reveals non-normality but doesn't quantify it.\n\n**Implementation sketch**:\n\n- New module: `packages/core/src/stats/distributions-fit.ts`\n- MLE parameter estimation for each family (closed-form for Normal/Exponential, numerical for Weibull/Lognormal)\n- Anderson-Darling statistic: `A² = -n - Σ[(2i-1)/n][ln F(y_i) + ln(1 - F(y_{n+1-i}))]`\n- Return ranked results with parameters, A², and p-value approximation\n- UI: badge on probability plot showing best-fit distribution\n\n**Complexity**: ~250 lines core. MLE for Weibull requires Newton-Raphson iteration (~40 lines). Critical tables for A-D p-values add ~50 lines.\n\n**Dependencies**: None — uses existing sorted data from stats engine.\n\n**Test strategy**: Validate against R `fitdistr()` and `ad.test()`. Generate synthetic data from each distribution family and verify correct identification.\n\n---\n\n## Feature 2: Residual Diagnostics\n\n**What**: Return residuals (e_i = y_i - ŷ_i) and fitted values (ŷ_i) from `calculateMultipleRegression()`.\n\n**Why for quality engineers**: Residual plots reveal model violations — patterns indicate missing terms, non-constant variance (heteroscedasticity), or outliers. Without residuals, users cannot validate that the regression model is appropriate.\n\n**Current state**: `calculateMultipleRegression()` in `packages/core/src/stats/multiRegression.ts` computes β, R², and p-values but discards the fitted values and residuals after using them for RMSE.\n\n**Implementation sketch**:\n\n- Extend `MultiRegressionResult` in `packages/core/src/types.ts` with optional `residuals: number[]` and `fittedValues: number[]`\n- In `multiRegression.ts`, retain `Xβ` (fitted) and `Y - Xβ` (residuals) instead of discarding\n- Optionally gated by a `diagnostics: boolean` option to avoid memory overhead for large datasets\n\n**Complexity**: ~20 lines — the values are already computed, just not returned.\n\n**Dependencies**: None.\n\n**Test strategy**: Verify `sum(residuals) ≈ 0`, `mean(fitted) ≈ mean(Y)`, and residuals match hand calculations for small datasets.\n\n---\n\n## Feature 3: Residual Normality Test\n\n**What**: Shapiro-Wilk test on regression residuals. Surface as amber warning on the regression panel when residuals are non-normal (p \u003C 0.05).\n\n**Why for quality engineers**: OLS assumes normally distributed errors. Non-normal residuals mean confidence intervals, p-values, and prediction intervals may be unreliable. An amber warning alerts users without blocking analysis.\n\n**Current state**: No residual normality checking. Users must visually inspect the probability plot.\n\n**Implementation sketch**:\n\n- New function: `shapiroWilk(values: number[]): { W: number; pValue: number }` in `packages/core/src/stats/normality.ts`\n- Algorithm: Royston's approximation (handles n ≤ 5000)\n- Coefficients: precomputed table for n ≤ 50, polynomial approximation for larger n\n- UI: amber badge on `RegressionPanelBase` when `shapiroWilk(residuals).pValue \u003C 0.05`\n\n**Complexity**: ~150 lines. Royston's algorithm requires ~80 lines for the W statistic and ~40 lines for p-value approximation from normalized W.\n\n**Dependencies**: Feature 2 (residuals must be available in `MultiRegressionResult`).\n\n**Test strategy**: Validate W and p-value against R `shapiro.test()` for normal, uniform, and exponential samples.\n\n---\n\n## Feature 4: QR Decomposition\n\n**What**: Replace Normal Equations `(X'X)⁻¹X'Y` with QR decomposition `X = QR, β = R⁻¹Q'Y` for solving the regression system.\n\n**Why for quality engineers**: The Normal Equations square the condition number of X (κ(X'X) = κ(X)²). For correlated predictors — common in manufacturing (temperature correlates with humidity, shift correlates with time) — this can cause coefficient instability or complete failure. QR decomposition is numerically stable.\n\n**Current state**: `packages/core/src/matrix.ts` implements Gauss-Jordan elimination with partial pivoting for `inverse()`. The Hilbert 4×4 test (`reference-validation.test.ts`) shows 3-digit accuracy, and the 5×5 test documents precision degradation. VIF computation also uses matrix inversion via the same path.\n\n**Implementation sketch**:\n\n- New functions in `packages/core/src/matrix.ts`: `qrDecompose(A): { Q, R }` and `qrSolve(Q, R, b): number[]`\n- Modified Gram-Schmidt process (~60 lines) or Householder reflections (~80 lines, more stable)\n- Update `calculateMultipleRegression()` to use `qrSolve` instead of `inverse(XtX) * XtY`\n- Retain `inverse()` for backward compatibility and VIF computation\n\n**Complexity**: ~120 lines. Householder QR is preferred for numerical stability.\n\n**Dependencies**: None — pure linear algebra addition to `matrix.ts`.\n\n**Test strategy**: Hilbert matrix tests (already in `reference-validation.test.ts`) should show improved precision. Longley dataset (`multiRegression.test.ts`) should achieve tighter coefficient tolerances. Performance benchmarks should show comparable speed.\n\n---\n\n## Feature 5: Leverage + Cook's Distance\n\n**What**: Compute leverage values h_ii (hat matrix diagonal) and Cook's distance D_i for each observation. Flag influential points.\n\n**Why for quality engineers**: A single unusual measurement can dominate the regression model. Leverage identifies points far from the predictor mean; Cook's distance combines leverage with residual magnitude to identify observations that disproportionately influence all fitted values.\n\n**Current state**: No influence diagnostics. Users cannot identify which data points are driving the model.\n\n**Implementation sketch**:\n\n- Leverage: `h_ii = diagonal(X(X'X)⁻¹X')` — requires hat matrix diagonal\n- Cook's distance: `D_i = (e_i² × h_ii) / (p × MSE × (1 - h_ii)²)`\n- Threshold: `D_i > 4/n` flags influential observations\n- Add `leverage: number[]` and `cooksDistance: number[]` to `MultiRegressionResult`\n- UI: highlight influential points in scatter plot (red ring marker)\n\n**Complexity**: ~120 lines. Hat matrix diagonal can be computed without forming the full n×n hat matrix by using the design matrix and inverse.\n\n**Dependencies**: Feature 2 (needs residuals). Benefits from Feature 4 (QR provides cleaner hat matrix computation via `H = Q₁Q₁'`).\n\n**Test strategy**: Verify against R `hatvalues()` and `cooks.distance()` for NIST datasets.\n\n---\n\n## Feature 6: Generalized Linear Models\n\n**What**: Extend regression to non-normal response distributions via Iteratively Reweighted Least Squares (IRLS). Support Logistic (binary outcomes), Poisson (count data), and Gamma (positive continuous) families.\n\n**Why for quality engineers**: Not all quality metrics are continuous and normal. Pass/fail rates (binomial), defect counts per unit (Poisson), and time-to-failure (Gamma) require appropriate link functions for valid inference.\n\n**Current state**: Only OLS (identity link, normal family). The design matrix construction and categorical dummy coding in `multiRegression.ts` are reusable.\n\n**Implementation sketch**:\n\n- New module: `packages/core/src/stats/glm.ts`\n- Family interface: `{ linkFn, inverseLinkFn, varianceFn, devianceFn }`\n- IRLS loop: solve weighted least squares at each iteration until convergence\n- Deviance-based R² analog and likelihood ratio tests for significance\n- Reuse existing `buildDesignMatrix` and `buildDummyVariables` from `multiRegression.ts`\n\n**Complexity**: ~400 lines. IRLS core is ~100 lines; family definitions ~80 lines each; convergence checks and diagnostics ~60 lines.\n\n**Dependencies**: Feature 4 recommended — IRLS solves a weighted least squares problem at each iteration, and QR decomposition handles the changing weights more stably than Normal Equations.\n\n**Test strategy**: Validate against R `glm()` for logistic, Poisson, and Gamma families using small certified datasets.\n\n---\n\n## Feature 7: Robust/Weighted Regression\n\n**What**: Huber M-estimation for regression resistant to outliers. Optionally, user-supplied observation weights.\n\n**Why for quality engineers**: Manufacturing data often contains outliers — measurement errors, equipment malfunctions, or startup transients. A single extreme value can distort OLS coefficients. Robust regression downweights extreme residuals, giving stable estimates without manual outlier removal.\n\n**Current state**: No outlier robustness. Users must manually identify and exclude outliers.\n\n**Implementation sketch**:\n\n- New module: `packages/core/src/stats/robust.ts`\n- Huber M-estimation: IRLS with Huber weight function `w(r) = min(1, c/|r|)` where c = 1.345\n- Converge when max weight change \u003C ε\n- Weighted regression: extend `calculateMultipleRegression` options with `weights: number[]`\n- Return both OLS and robust estimates for comparison\n\n**Complexity**: ~200 lines. Huber IRLS ~80 lines; weight function variants (Tukey bisquare) ~40 lines; integration with existing regression ~80 lines.\n\n**Dependencies**: Feature 4 recommended — weighted least squares with rapidly changing weights benefits from QR stability. Feature 5 helpful — Cook's distance identifies points that robust regression would downweight, useful for validation.\n\n**Test strategy**: Verify that injecting 10% outliers degrades OLS R² but robust R² remains stable. Validate Huber coefficients against R `rlm()` from the MASS package.\n\n---\n\n## Implementation Priority\n\n**Phase 1** (foundation): Features 2, 4 — residuals and QR decomposition. Low effort, high value, unblock everything else.\n\n**Phase 2** (diagnostics): Features 3, 5 — normality test and influence diagnostics. Immediate user value via warnings and highlights.\n\n**Phase 3** (distribution): Feature 1 — distribution identification. Independent, enhances probability plot.\n\n**Phase 4** (advanced): Features 6, 7 — GLM and robust regression. Significant scope expansion, lowest priority for SPC use case.", + "src/content/docs/05-technical/implementation/glm-roadmap.md", + "c33653698a3bffef", + { "html": 8649, "metadata": 8650 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"glm-engine-roadmap\">GLM Engine Roadmap\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#glm-engine-roadmap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “GLM Engine Roadmap”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note:\u003C/strong> Regression UI has been deferred per \u003Ca href=\"../../07-decisions/adr-014-regression-deferral.md\">ADR-014\u003C/a>. Core math files (regression.ts, multiRegression.ts, interaction.ts, modelReduction.ts, matrix.ts) are preserved in the repository but unexported from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>. This roadmap applies to Phase 2 re-enablement.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Post-MVP enhancements for VariScout’s regression engine. Current implementation uses OLS via the Normal Equations \u003Ccode dir=\"auto\">(X'X)⁻¹X'Y\u003C/code> with categorical dummy coding — the General Linear Model (not Generalized). It works well for typical SPC data (3–6 factors, 100–10K rows, roughly normal distributions).\u003C/p>\n\u003Cp>\u003Cstrong>Status\u003C/strong>: Deferred (Phase 2). See \u003Ca href=\"../../07-decisions/adr-014-regression-deferral.md\">ADR-014\u003C/a> for re-enablement criteria.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"summary\">Summary\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Summary”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Feature\u003C/th>\u003Cth>Complexity\u003C/th>\u003Cth>Dependencies\u003C/th>\u003Cth>Priority\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Distribution Identification\u003C/td>\u003Ctd>~250 lines\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>Medium\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Residual Diagnostics\u003C/td>\u003Ctd>~20 lines\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>High\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Residual Normality Test\u003C/td>\u003Ctd>~150 lines\u003C/td>\u003Ctd>Feature 2\u003C/td>\u003Ctd>High\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>QR Decomposition\u003C/td>\u003Ctd>~120 lines\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>High\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Leverage + Cook’s Distance\u003C/td>\u003Ctd>~120 lines\u003C/td>\u003Ctd>Feature 2\u003C/td>\u003Ctd>Medium\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Generalized Linear Models\u003C/td>\u003Ctd>~400 lines\u003C/td>\u003Ctd>Feature 4 (recommended)\u003C/td>\u003Ctd>Low\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>Robust/Weighted Regression\u003C/td>\u003Ctd>~200 lines\u003C/td>\u003Ctd>Feature 4 (recommended)\u003C/td>\u003Ctd>Low\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dependency-graph\">Dependency Graph\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dependency-graph\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dependency Graph”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">1 (Distribution ID) — independent\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">2 (Residuals) ─────┬───→ 3 (Normality Test)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└───→ 5 (Leverage/Cook's)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">4 (QR Decomposition) ──┬─→ 6 (GLM) [recommended]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─→ 7 (Robust Regression) [recommended]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"1 (Distribution ID) — independent2 (Residuals) ─────┬───→ 3 (Normality Test) └───→ 5 (Leverage/Cook's)4 (QR Decomposition) ──┬─→ 6 (GLM) [recommended] └─→ 7 (Robust Regression) [recommended]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Features 1, 2, and 4 can be implemented independently and in parallel. Feature 4 is recommended (not required) before 6 and 7 because IRLS and M-estimation benefit from numerically stable decomposition.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-1-distribution-identification\">Feature 1: Distribution Identification\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-1-distribution-identification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature 1: Distribution Identification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>What\u003C/strong>: Fit Normal, Lognormal, Weibull, and Exponential distributions to data. Rank by Anderson-Darling goodness-of-fit statistic.\u003C/p>\n\u003Cp>\u003Cstrong>Why for quality engineers\u003C/strong>: SPC assumes normality. When data is non-normal (e.g., cycle times follow Lognormal, failure rates follow Weibull), Cpk calculations are misleading. Distribution identification tells the user which distribution fits best, enabling correct capability analysis.\u003C/p>\n\u003Cp>\u003Cstrong>Current state\u003C/strong>: \u003Ccode dir=\"auto\">calculateProbabilityPlotData()\u003C/code> in \u003Ccode dir=\"auto\">packages/core/src/stats/probability.ts\u003C/code> computes normal Q-Q plot data with Benard ranks. The probability plot visually reveals non-normality but doesn’t quantify it.\u003C/p>\n\u003Cp>\u003Cstrong>Implementation sketch\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>New module: \u003Ccode dir=\"auto\">packages/core/src/stats/distributions-fit.ts\u003C/code>\u003C/li>\n\u003Cli>MLE parameter estimation for each family (closed-form for Normal/Exponential, numerical for Weibull/Lognormal)\u003C/li>\n\u003Cli>Anderson-Darling statistic: \u003Ccode dir=\"auto\">A² = -n - Σ[(2i-1)/n][ln F(y_i) + ln(1 - F(y_{n+1-i}))]\u003C/code>\u003C/li>\n\u003Cli>Return ranked results with parameters, A², and p-value approximation\u003C/li>\n\u003Cli>UI: badge on probability plot showing best-fit distribution\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Complexity\u003C/strong>: ~250 lines core. MLE for Weibull requires Newton-Raphson iteration (~40 lines). Critical tables for A-D p-values add ~50 lines.\u003C/p>\n\u003Cp>\u003Cstrong>Dependencies\u003C/strong>: None — uses existing sorted data from stats engine.\u003C/p>\n\u003Cp>\u003Cstrong>Test strategy\u003C/strong>: Validate against R \u003Ccode dir=\"auto\">fitdistr()\u003C/code> and \u003Ccode dir=\"auto\">ad.test()\u003C/code>. Generate synthetic data from each distribution family and verify correct identification.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-2-residual-diagnostics\">Feature 2: Residual Diagnostics\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-2-residual-diagnostics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature 2: Residual Diagnostics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>What\u003C/strong>: Return residuals (e_i = y_i - ŷ_i) and fitted values (ŷ_i) from \u003Ccode dir=\"auto\">calculateMultipleRegression()\u003C/code>.\u003C/p>\n\u003Cp>\u003Cstrong>Why for quality engineers\u003C/strong>: Residual plots reveal model violations — patterns indicate missing terms, non-constant variance (heteroscedasticity), or outliers. Without residuals, users cannot validate that the regression model is appropriate.\u003C/p>\n\u003Cp>\u003Cstrong>Current state\u003C/strong>: \u003Ccode dir=\"auto\">calculateMultipleRegression()\u003C/code> in \u003Ccode dir=\"auto\">packages/core/src/stats/multiRegression.ts\u003C/code> computes β, R², and p-values but discards the fitted values and residuals after using them for RMSE.\u003C/p>\n\u003Cp>\u003Cstrong>Implementation sketch\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Extend \u003Ccode dir=\"auto\">MultiRegressionResult\u003C/code> in \u003Ccode dir=\"auto\">packages/core/src/types.ts\u003C/code> with optional \u003Ccode dir=\"auto\">residuals: number[]\u003C/code> and \u003Ccode dir=\"auto\">fittedValues: number[]\u003C/code>\u003C/li>\n\u003Cli>In \u003Ccode dir=\"auto\">multiRegression.ts\u003C/code>, retain \u003Ccode dir=\"auto\">Xβ\u003C/code> (fitted) and \u003Ccode dir=\"auto\">Y - Xβ\u003C/code> (residuals) instead of discarding\u003C/li>\n\u003Cli>Optionally gated by a \u003Ccode dir=\"auto\">diagnostics: boolean\u003C/code> option to avoid memory overhead for large datasets\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Complexity\u003C/strong>: ~20 lines — the values are already computed, just not returned.\u003C/p>\n\u003Cp>\u003Cstrong>Dependencies\u003C/strong>: None.\u003C/p>\n\u003Cp>\u003Cstrong>Test strategy\u003C/strong>: Verify \u003Ccode dir=\"auto\">sum(residuals) ≈ 0\u003C/code>, \u003Ccode dir=\"auto\">mean(fitted) ≈ mean(Y)\u003C/code>, and residuals match hand calculations for small datasets.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-3-residual-normality-test\">Feature 3: Residual Normality Test\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-3-residual-normality-test\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature 3: Residual Normality Test”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>What\u003C/strong>: Shapiro-Wilk test on regression residuals. Surface as amber warning on the regression panel when residuals are non-normal (p < 0.05).\u003C/p>\n\u003Cp>\u003Cstrong>Why for quality engineers\u003C/strong>: OLS assumes normally distributed errors. Non-normal residuals mean confidence intervals, p-values, and prediction intervals may be unreliable. An amber warning alerts users without blocking analysis.\u003C/p>\n\u003Cp>\u003Cstrong>Current state\u003C/strong>: No residual normality checking. Users must visually inspect the probability plot.\u003C/p>\n\u003Cp>\u003Cstrong>Implementation sketch\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>New function: \u003Ccode dir=\"auto\">shapiroWilk(values: number[]): { W: number; pValue: number }\u003C/code> in \u003Ccode dir=\"auto\">packages/core/src/stats/normality.ts\u003C/code>\u003C/li>\n\u003Cli>Algorithm: Royston’s approximation (handles n ≤ 5000)\u003C/li>\n\u003Cli>Coefficients: precomputed table for n ≤ 50, polynomial approximation for larger n\u003C/li>\n\u003Cli>UI: amber badge on \u003Ccode dir=\"auto\">RegressionPanelBase\u003C/code> when \u003Ccode dir=\"auto\">shapiroWilk(residuals).pValue < 0.05\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Complexity\u003C/strong>: ~150 lines. Royston’s algorithm requires ~80 lines for the W statistic and ~40 lines for p-value approximation from normalized W.\u003C/p>\n\u003Cp>\u003Cstrong>Dependencies\u003C/strong>: Feature 2 (residuals must be available in \u003Ccode dir=\"auto\">MultiRegressionResult\u003C/code>).\u003C/p>\n\u003Cp>\u003Cstrong>Test strategy\u003C/strong>: Validate W and p-value against R \u003Ccode dir=\"auto\">shapiro.test()\u003C/code> for normal, uniform, and exponential samples.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-4-qr-decomposition\">Feature 4: QR Decomposition\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-4-qr-decomposition\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature 4: QR Decomposition”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>What\u003C/strong>: Replace Normal Equations \u003Ccode dir=\"auto\">(X'X)⁻¹X'Y\u003C/code> with QR decomposition \u003Ccode dir=\"auto\">X = QR, β = R⁻¹Q'Y\u003C/code> for solving the regression system.\u003C/p>\n\u003Cp>\u003Cstrong>Why for quality engineers\u003C/strong>: The Normal Equations square the condition number of X (κ(X’X) = κ(X)²). For correlated predictors — common in manufacturing (temperature correlates with humidity, shift correlates with time) — this can cause coefficient instability or complete failure. QR decomposition is numerically stable.\u003C/p>\n\u003Cp>\u003Cstrong>Current state\u003C/strong>: \u003Ccode dir=\"auto\">packages/core/src/matrix.ts\u003C/code> implements Gauss-Jordan elimination with partial pivoting for \u003Ccode dir=\"auto\">inverse()\u003C/code>. The Hilbert 4×4 test (\u003Ccode dir=\"auto\">reference-validation.test.ts\u003C/code>) shows 3-digit accuracy, and the 5×5 test documents precision degradation. VIF computation also uses matrix inversion via the same path.\u003C/p>\n\u003Cp>\u003Cstrong>Implementation sketch\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>New functions in \u003Ccode dir=\"auto\">packages/core/src/matrix.ts\u003C/code>: \u003Ccode dir=\"auto\">qrDecompose(A): { Q, R }\u003C/code> and \u003Ccode dir=\"auto\">qrSolve(Q, R, b): number[]\u003C/code>\u003C/li>\n\u003Cli>Modified Gram-Schmidt process (~60 lines) or Householder reflections (~80 lines, more stable)\u003C/li>\n\u003Cli>Update \u003Ccode dir=\"auto\">calculateMultipleRegression()\u003C/code> to use \u003Ccode dir=\"auto\">qrSolve\u003C/code> instead of \u003Ccode dir=\"auto\">inverse(XtX) * XtY\u003C/code>\u003C/li>\n\u003Cli>Retain \u003Ccode dir=\"auto\">inverse()\u003C/code> for backward compatibility and VIF computation\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Complexity\u003C/strong>: ~120 lines. Householder QR is preferred for numerical stability.\u003C/p>\n\u003Cp>\u003Cstrong>Dependencies\u003C/strong>: None — pure linear algebra addition to \u003Ccode dir=\"auto\">matrix.ts\u003C/code>.\u003C/p>\n\u003Cp>\u003Cstrong>Test strategy\u003C/strong>: Hilbert matrix tests (already in \u003Ccode dir=\"auto\">reference-validation.test.ts\u003C/code>) should show improved precision. Longley dataset (\u003Ccode dir=\"auto\">multiRegression.test.ts\u003C/code>) should achieve tighter coefficient tolerances. Performance benchmarks should show comparable speed.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-5-leverage--cooks-distance\">Feature 5: Leverage + Cook’s Distance\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-5-leverage--cooks-distance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature 5: Leverage + Cook’s Distance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>What\u003C/strong>: Compute leverage values h_ii (hat matrix diagonal) and Cook’s distance D_i for each observation. Flag influential points.\u003C/p>\n\u003Cp>\u003Cstrong>Why for quality engineers\u003C/strong>: A single unusual measurement can dominate the regression model. Leverage identifies points far from the predictor mean; Cook’s distance combines leverage with residual magnitude to identify observations that disproportionately influence all fitted values.\u003C/p>\n\u003Cp>\u003Cstrong>Current state\u003C/strong>: No influence diagnostics. Users cannot identify which data points are driving the model.\u003C/p>\n\u003Cp>\u003Cstrong>Implementation sketch\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Leverage: \u003Ccode dir=\"auto\">h_ii = diagonal(X(X'X)⁻¹X')\u003C/code> — requires hat matrix diagonal\u003C/li>\n\u003Cli>Cook’s distance: \u003Ccode dir=\"auto\">D_i = (e_i² × h_ii) / (p × MSE × (1 - h_ii)²)\u003C/code>\u003C/li>\n\u003Cli>Threshold: \u003Ccode dir=\"auto\">D_i > 4/n\u003C/code> flags influential observations\u003C/li>\n\u003Cli>Add \u003Ccode dir=\"auto\">leverage: number[]\u003C/code> and \u003Ccode dir=\"auto\">cooksDistance: number[]\u003C/code> to \u003Ccode dir=\"auto\">MultiRegressionResult\u003C/code>\u003C/li>\n\u003Cli>UI: highlight influential points in scatter plot (red ring marker)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Complexity\u003C/strong>: ~120 lines. Hat matrix diagonal can be computed without forming the full n×n hat matrix by using the design matrix and inverse.\u003C/p>\n\u003Cp>\u003Cstrong>Dependencies\u003C/strong>: Feature 2 (needs residuals). Benefits from Feature 4 (QR provides cleaner hat matrix computation via \u003Ccode dir=\"auto\">H = Q₁Q₁'\u003C/code>).\u003C/p>\n\u003Cp>\u003Cstrong>Test strategy\u003C/strong>: Verify against R \u003Ccode dir=\"auto\">hatvalues()\u003C/code> and \u003Ccode dir=\"auto\">cooks.distance()\u003C/code> for NIST datasets.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-6-generalized-linear-models\">Feature 6: Generalized Linear Models\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-6-generalized-linear-models\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature 6: Generalized Linear Models”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>What\u003C/strong>: Extend regression to non-normal response distributions via Iteratively Reweighted Least Squares (IRLS). Support Logistic (binary outcomes), Poisson (count data), and Gamma (positive continuous) families.\u003C/p>\n\u003Cp>\u003Cstrong>Why for quality engineers\u003C/strong>: Not all quality metrics are continuous and normal. Pass/fail rates (binomial), defect counts per unit (Poisson), and time-to-failure (Gamma) require appropriate link functions for valid inference.\u003C/p>\n\u003Cp>\u003Cstrong>Current state\u003C/strong>: Only OLS (identity link, normal family). The design matrix construction and categorical dummy coding in \u003Ccode dir=\"auto\">multiRegression.ts\u003C/code> are reusable.\u003C/p>\n\u003Cp>\u003Cstrong>Implementation sketch\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>New module: \u003Ccode dir=\"auto\">packages/core/src/stats/glm.ts\u003C/code>\u003C/li>\n\u003Cli>Family interface: \u003Ccode dir=\"auto\">{ linkFn, inverseLinkFn, varianceFn, devianceFn }\u003C/code>\u003C/li>\n\u003Cli>IRLS loop: solve weighted least squares at each iteration until convergence\u003C/li>\n\u003Cli>Deviance-based R² analog and likelihood ratio tests for significance\u003C/li>\n\u003Cli>Reuse existing \u003Ccode dir=\"auto\">buildDesignMatrix\u003C/code> and \u003Ccode dir=\"auto\">buildDummyVariables\u003C/code> from \u003Ccode dir=\"auto\">multiRegression.ts\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Complexity\u003C/strong>: ~400 lines. IRLS core is ~100 lines; family definitions ~80 lines each; convergence checks and diagnostics ~60 lines.\u003C/p>\n\u003Cp>\u003Cstrong>Dependencies\u003C/strong>: Feature 4 recommended — IRLS solves a weighted least squares problem at each iteration, and QR decomposition handles the changing weights more stably than Normal Equations.\u003C/p>\n\u003Cp>\u003Cstrong>Test strategy\u003C/strong>: Validate against R \u003Ccode dir=\"auto\">glm()\u003C/code> for logistic, Poisson, and Gamma families using small certified datasets.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-7-robustweighted-regression\">Feature 7: Robust/Weighted Regression\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-7-robustweighted-regression\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature 7: Robust/Weighted Regression”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>What\u003C/strong>: Huber M-estimation for regression resistant to outliers. Optionally, user-supplied observation weights.\u003C/p>\n\u003Cp>\u003Cstrong>Why for quality engineers\u003C/strong>: Manufacturing data often contains outliers — measurement errors, equipment malfunctions, or startup transients. A single extreme value can distort OLS coefficients. Robust regression downweights extreme residuals, giving stable estimates without manual outlier removal.\u003C/p>\n\u003Cp>\u003Cstrong>Current state\u003C/strong>: No outlier robustness. Users must manually identify and exclude outliers.\u003C/p>\n\u003Cp>\u003Cstrong>Implementation sketch\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>New module: \u003Ccode dir=\"auto\">packages/core/src/stats/robust.ts\u003C/code>\u003C/li>\n\u003Cli>Huber M-estimation: IRLS with Huber weight function \u003Ccode dir=\"auto\">w(r) = min(1, c/|r|)\u003C/code> where c = 1.345\u003C/li>\n\u003Cli>Converge when max weight change < ε\u003C/li>\n\u003Cli>Weighted regression: extend \u003Ccode dir=\"auto\">calculateMultipleRegression\u003C/code> options with \u003Ccode dir=\"auto\">weights: number[]\u003C/code>\u003C/li>\n\u003Cli>Return both OLS and robust estimates for comparison\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Complexity\u003C/strong>: ~200 lines. Huber IRLS ~80 lines; weight function variants (Tukey bisquare) ~40 lines; integration with existing regression ~80 lines.\u003C/p>\n\u003Cp>\u003Cstrong>Dependencies\u003C/strong>: Feature 4 recommended — weighted least squares with rapidly changing weights benefits from QR stability. Feature 5 helpful — Cook’s distance identifies points that robust regression would downweight, useful for validation.\u003C/p>\n\u003Cp>\u003Cstrong>Test strategy\u003C/strong>: Verify that injecting 10% outliers degrades OLS R² but robust R² remains stable. Validate Huber coefficients against R \u003Ccode dir=\"auto\">rlm()\u003C/code> from the MASS package.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation-priority\">Implementation Priority\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-priority\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation Priority”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Phase 1\u003C/strong> (foundation): Features 2, 4 — residuals and QR decomposition. Low effort, high value, unblock everything else.\u003C/p>\n\u003Cp>\u003Cstrong>Phase 2\u003C/strong> (diagnostics): Features 3, 5 — normality test and influence diagnostics. Immediate user value via warnings and highlights.\u003C/p>\n\u003Cp>\u003Cstrong>Phase 3\u003C/strong> (distribution): Feature 1 — distribution identification. Independent, enhances probability plot.\u003C/p>\n\u003Cp>\u003Cstrong>Phase 4\u003C/strong> (advanced): Features 6, 7 — GLM and robust regression. Significant scope expansion, lowest priority for SPC use case.\u003C/p>", + { + "headings": 8651, + "localImagePaths": 8682, + "remoteImagePaths": 8683, + "frontmatter": 8684, + "imagePaths": 8685 + }, + [8652, 8654, 8655, 8658, 8661, 8664, 8667, 8670, 8673, 8676, 8679], + { "depth": 30, "slug": 8653, "text": 8641 }, + "glm-engine-roadmap", + { "depth": 33, "slug": 1450, "text": 1451 }, + { "depth": 33, "slug": 8656, "text": 8657 }, + "dependency-graph", + "Dependency Graph", + { "depth": 33, "slug": 8659, "text": 8660 }, + "feature-1-distribution-identification", + "Feature 1: Distribution Identification", + { "depth": 33, "slug": 8662, "text": 8663 }, + "feature-2-residual-diagnostics", + "Feature 2: Residual Diagnostics", + { "depth": 33, "slug": 8665, "text": 8666 }, + "feature-3-residual-normality-test", + "Feature 3: Residual Normality Test", + { "depth": 33, "slug": 8668, "text": 8669 }, + "feature-4-qr-decomposition", + "Feature 4: QR Decomposition", + { "depth": 33, "slug": 8671, "text": 8672 }, + "feature-5-leverage--cooks-distance", + "Feature 5: Leverage + Cook’s Distance", + { "depth": 33, "slug": 8674, "text": 8675 }, + "feature-6-generalized-linear-models", + "Feature 6: Generalized Linear Models", + { "depth": 33, "slug": 8677, "text": 8678 }, + "feature-7-robustweighted-regression", + "Feature 7: Robust/Weighted Regression", + { "depth": 33, "slug": 8680, "text": 8681 }, + "implementation-priority", + "Implementation Priority", + [], + [], + { "title": 8641 }, + [], + "05-technical/implementation/ruflo", + { "id": 8686, "data": 8688, "body": 8693, "filePath": 8694, "digest": 8695, "rendered": 8696 }, + { + "title": 8689, + "editUrl": 16, + "head": 8690, + "template": 18, + "sidebar": 8691, + "pagefind": 16, + "draft": 20 + }, + "Ruflo Development Tooling", + [], + { "hidden": 20, "attrs": 8692 }, + {}, + "# Ruflo Development Tooling\n\n## What It Is\n\nruflo is an MCP-integrated AI development tooling layer for VariScout. It provides semantic codebase search, persistent cross-session memory, automated security scanning, and background workers. It is **not** a runtime dependency -- it only runs during development sessions.\n\n## Quick Commands\n\n```bash\n# System status\nnpx ruflo@latest daemon status\n\n# Semantic search\nnpx ruflo@latest memory search --query \"Cpk calculation\"\nnpx ruflo@latest memory search --query \"Azure authentication\"\n\n# Memory operations\nnpx ruflo@latest memory stats\nnpx ruflo@latest memory list --namespace architecture\nnpx ruflo@latest memory store -k \"key\" --namespace ns --value \"data\"\n\n# Security scanning\nnpx ruflo@latest security scan --depth full # OWASP Top 10\nnpx ruflo@latest security cve --check # CVE database\n\n# Daemon control\nnpx ruflo@latest daemon start\nnpx ruflo@latest daemon stop\nnpx ruflo@latest daemon trigger -w audit # Run worker manually\n\n# Reindex codebase\nnpx ruflo@latest hooks pretrain\nnpx ruflo@latest hooks build-agents\n```\n\n## Architecture\n\n```\nClaude Code ──MCP──▶ ruflo MCP Server (npx, port 3000)\n │\n ├── Memory (sql.js + HNSW vector index)\n ├── Embeddings (all-MiniLM-L6-v2, 384-dim)\n ├── Hooks (pre/post edit, session start/end)\n └── Daemon (background workers)\n```\n\n### Config Files\n\n| File | Purpose |\n| -------------------------- | -------------------------------------------------- |\n| `.mcp.json` | MCP server definition (autoStart: true) |\n| `.ruflo/config.yaml` | Runtime config (topology, memory backend, workers) |\n| `.ruflo/daemon-state.json` | Worker state and schedules |\n| `.claude/settings.json` | Hooks, model preferences, worker list |\n\n### Memory Namespaces\n\n| Namespace | Contents |\n| -------------- | --------------------------------------------------- |\n| `architecture` | Monorepo structure, product model, key files |\n| `conventions` | Coding standards, import rules, color usage |\n| `decisions` | Removed features, Azure architecture, system limits |\n| `testing` | Test counts, runner commands |\n\n### Background Workers\n\n| Worker | Interval | Purpose |\n| ------------- | -------- | -------------------------- |\n| `map` | 15min | Codebase structure mapping |\n| `audit` | 10min | Security analysis (OWASP) |\n| `optimize` | 15min | Performance hints |\n| `consolidate` | 30min | Memory dedup and cleanup |\n| `testgaps` | 20min | Test coverage analysis |\n\nWorkers are resource-throttled: max 2 concurrent, CPU load \u003C 2, free memory > 20%.\n\n## Troubleshooting\n\n### Stale daemon PID\n\n```bash\nrm .ruflo/daemon.pid\nnpx ruflo@latest daemon start\n```\n\n### Worker stuck in \"running\" state\n\nEdit `.ruflo/daemon-state.json` and set `\"isRunning\": false` for the stuck worker, then restart the daemon.\n\n### Memory empty after session\n\n```bash\nnpx ruflo@latest memory init --force\nnpx ruflo@latest hooks pretrain\n```\n\nThen re-seed memory entries (see seed commands in ADR-011).\n\n### Audit worker scanning .venv\n\nEnsure `.venv/` is in `.gitignore` and `workers.excludePaths` in `.ruflo/config.yaml` includes `.venv/**`.\n\n## What NOT To Do\n\n- **Don't add ruflo to package.json** -- It's dev tooling only, runs via npx\n- **Don't commit .ruflo/ data** -- Already gitignored; contains local state\n- **Don't rely on daemon for CI/CD** -- Workers are for local dev intelligence only\n- **Don't store secrets in memory** -- Memory DB is unencrypted local SQLite\n\n## See Also\n\n- [ADR-011: AI Development Tooling](../../07-decisions/adr-011-ai-development-tooling.md)\n- [Security Scanning](security-scanning.md)", + "src/content/docs/05-technical/implementation/ruflo.md", + "b13e72b0fb7495cf", + { "html": 8697, "metadata": 8698 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"ruflo-development-tooling\">Ruflo Development Tooling\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#ruflo-development-tooling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Ruflo Development Tooling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-it-is\">What It Is\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-it-is\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What It Is”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>ruflo is an MCP-integrated AI development tooling layer for VariScout. It provides semantic codebase search, persistent cross-session memory, automated security scanning, and background workers. It is \u003Cstrong>not\u003C/strong> a runtime dependency — it only runs during development sessions.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"quick-commands\">Quick Commands\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#quick-commands\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Commands”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># System status\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">daemon\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">status\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Semantic search\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">memory\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">search\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Cpk calculation\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">memory\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">search\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Azure authentication\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Memory operations\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">memory\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">stats\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">memory\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">list\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--namespace\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">architecture\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">memory\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">store\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-k\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">key\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--namespace\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ns\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--value\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">data\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Security scanning\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">security\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">scan\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--depth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">full\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># OWASP Top 10\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">security\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">cve\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--check\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># CVE database\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Daemon control\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">daemon\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">start\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">daemon\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">stop\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">daemon\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">trigger\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-w\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">audit\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run worker manually\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Reindex codebase\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">hooks\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">pretrain\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">hooks\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build-agents\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"npx ruflo@latest daemon statusnpx ruflo@latest memory search --query "Cpk calculation"npx ruflo@latest memory search --query "Azure authentication"npx ruflo@latest memory statsnpx ruflo@latest memory list --namespace architecturenpx ruflo@latest memory store -k "key" --namespace ns --value "data"npx ruflo@latest security scan --depth full # OWASP Top 10npx ruflo@latest security cve --check # CVE databasenpx ruflo@latest daemon startnpx ruflo@latest daemon stopnpx ruflo@latest daemon trigger -w audit # Run worker manuallynpx ruflo@latest hooks pretrainnpx ruflo@latest hooks build-agents\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"architecture\">Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Claude Code ──MCP──▶ ruflo MCP Server (npx, port 3000)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Memory (sql.js + HNSW vector index)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Embeddings (all-MiniLM-L6-v2, 384-dim)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Hooks (pre/post edit, session start/end)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Daemon (background workers)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Claude Code ──MCP──▶ ruflo MCP Server (npx, port 3000) │ ├── Memory (sql.js + HNSW vector index) ├── Embeddings (all-MiniLM-L6-v2, 384-dim) ├── Hooks (pre/post edit, session start/end) └── Daemon (background workers)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"config-files\">Config Files\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#config-files\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Config Files”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">.mcp.json\u003C/code>\u003C/td>\u003Ctd>MCP server definition (autoStart: true)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">.ruflo/config.yaml\u003C/code>\u003C/td>\u003Ctd>Runtime config (topology, memory backend, workers)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">.ruflo/daemon-state.json\u003C/code>\u003C/td>\u003Ctd>Worker state and schedules\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">.claude/settings.json\u003C/code>\u003C/td>\u003Ctd>Hooks, model preferences, worker list\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"memory-namespaces\">Memory Namespaces\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#memory-namespaces\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Memory Namespaces”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Namespace\u003C/th>\u003Cth>Contents\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">architecture\u003C/code>\u003C/td>\u003Ctd>Monorepo structure, product model, key files\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">conventions\u003C/code>\u003C/td>\u003Ctd>Coding standards, import rules, color usage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">decisions\u003C/code>\u003C/td>\u003Ctd>Removed features, Azure architecture, system limits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">testing\u003C/code>\u003C/td>\u003Ctd>Test counts, runner commands\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"background-workers\">Background Workers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#background-workers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Background Workers”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Worker\u003C/th>\u003Cth>Interval\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">map\u003C/code>\u003C/td>\u003Ctd>15min\u003C/td>\u003Ctd>Codebase structure mapping\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">audit\u003C/code>\u003C/td>\u003Ctd>10min\u003C/td>\u003Ctd>Security analysis (OWASP)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">optimize\u003C/code>\u003C/td>\u003Ctd>15min\u003C/td>\u003Ctd>Performance hints\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">consolidate\u003C/code>\u003C/td>\u003Ctd>30min\u003C/td>\u003Ctd>Memory dedup and cleanup\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">testgaps\u003C/code>\u003C/td>\u003Ctd>20min\u003C/td>\u003Ctd>Test coverage analysis\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Workers are resource-throttled: max 2 concurrent, CPU load < 2, free memory > 20%.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"troubleshooting\">Troubleshooting\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#troubleshooting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Troubleshooting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"stale-daemon-pid\">Stale daemon PID\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#stale-daemon-pid\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Stale daemon PID”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">rm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">.ruflo/daemon.pid\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">daemon\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">start\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"rm .ruflo/daemon.pidnpx ruflo@latest daemon start\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"worker-stuck-in-running-state\">Worker stuck in “running” state\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#worker-stuck-in-running-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Worker stuck in “running” state”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Edit \u003Ccode dir=\"auto\">.ruflo/daemon-state.json\u003C/code> and set \u003Ccode dir=\"auto\">\"isRunning\": false\u003C/code> for the stuck worker, then restart the daemon.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"memory-empty-after-session\">Memory empty after session\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#memory-empty-after-session\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Memory empty after session”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">memory\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">init\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--force\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">hooks\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">pretrain\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"npx ruflo@latest memory init --forcenpx ruflo@latest hooks pretrain\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Then re-seed memory entries (see seed commands in ADR-011).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"audit-worker-scanning-venv\">Audit worker scanning .venv\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#audit-worker-scanning-venv\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Audit worker scanning .venv”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Ensure \u003Ccode dir=\"auto\">.venv/\u003C/code> is in \u003Ccode dir=\"auto\">.gitignore\u003C/code> and \u003Ccode dir=\"auto\">workers.excludePaths\u003C/code> in \u003Ccode dir=\"auto\">.ruflo/config.yaml\u003C/code> includes \u003Ccode dir=\"auto\">.venv/**\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-not-to-do\">What NOT To Do\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-not-to-do\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What NOT To Do”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Don’t add ruflo to package.json\u003C/strong> — It’s dev tooling only, runs via npx\u003C/li>\n\u003Cli>\u003Cstrong>Don’t commit .ruflo/ data\u003C/strong> — Already gitignored; contains local state\u003C/li>\n\u003Cli>\u003Cstrong>Don’t rely on daemon for CI/CD\u003C/strong> — Workers are for local dev intelligence only\u003C/li>\n\u003Cli>\u003Cstrong>Don’t store secrets in memory\u003C/strong> — Memory DB is unencrypted local SQLite\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-011-ai-development-tooling.md\">ADR-011: AI Development Tooling\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"security-scanning.md\">Security Scanning\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 8699, + "localImagePaths": 8735, + "remoteImagePaths": 8736, + "frontmatter": 8737, + "imagePaths": 8738 + }, + [8700, 8702, 8705, 8708, 8709, 8712, 8715, 8718, 8719, 8722, 8725, 8728, 8731, 8734], + { "depth": 30, "slug": 8701, "text": 8689 }, + "ruflo-development-tooling", + { "depth": 33, "slug": 8703, "text": 8704 }, + "what-it-is", + "What It Is", + { "depth": 33, "slug": 8706, "text": 8707 }, + "quick-commands", + "Quick Commands", + { "depth": 33, "slug": 1819, "text": 1820 }, + { "depth": 79, "slug": 8710, "text": 8711 }, + "config-files", + "Config Files", + { "depth": 79, "slug": 8713, "text": 8714 }, + "memory-namespaces", + "Memory Namespaces", + { "depth": 79, "slug": 8716, "text": 8717 }, + "background-workers", + "Background Workers", + { "depth": 33, "slug": 3221, "text": 3222 }, + { "depth": 79, "slug": 8720, "text": 8721 }, + "stale-daemon-pid", + "Stale daemon PID", + { "depth": 79, "slug": 8723, "text": 8724 }, + "worker-stuck-in-running-state", + "Worker stuck in “running” state", + { "depth": 79, "slug": 8726, "text": 8727 }, + "memory-empty-after-session", + "Memory empty after session", + { "depth": 79, "slug": 8729, "text": 8730 }, + "audit-worker-scanning-venv", + "Audit worker scanning .venv", + { "depth": 33, "slug": 8732, "text": 8733 }, + "what-not-to-do", + "What NOT To Do", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 8689 }, + [], + "05-technical/implementation/phase2-regression-roadmap", + { "id": 8739, "data": 8741, "body": 8746, "filePath": 8747, "digest": 8748, "rendered": 8749 }, + { + "title": 8742, + "editUrl": 16, + "head": 8743, + "template": 18, + "sidebar": 8744, + "pagefind": 16, + "draft": 20 + }, + "Phase 2: Regression Re-enablement Roadmap", + [], + { "hidden": 20, "attrs": 8745 }, + {}, + "# Phase 2: Regression Re-enablement Roadmap\n\n> **Status:** Planned — not started\n> **Prerequisite:** [ADR-014](../../07-decisions/adr-014-regression-deferral.md) re-enablement criteria must be met\n> **Related:** [GLM Roadmap](glm-roadmap.md) (core math enhancements)\n\n---\n\n## A. Re-enablement Criteria\n\nAll three conditions from ADR-014 must be satisfied before starting Phase 2 work:\n\n1. **Post-marketplace certification** — Azure App is listed on Azure Marketplace and generating revenue\n2. **Customer demand signal** — At least one paying customer requests regression or the investigation workflow\n3. **UX validation** — Regression workflow tested with target persona (Green Belt Gary) for discoverability and comprehension\n\n---\n\n## B. Preserved Foundation — Inventory\n\nThe core math was preserved in commit `35339a3` (Feb 2026). All source files remain in the repository but are **unexported** from package indexes, so tree-shaking excludes them from production builds.\n\n### Core math files (internal, unexported)\n\n| File | Lines | Key Functions |\n| -------------------------------------------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `packages/core/src/stats/regression.ts` | 279 | `calculateRegression()` — linear + quadratic simple regression |\n| `packages/core/src/stats/multiRegression.ts` | 558 | `calculateMultipleRegression()` — OLS GLM with dummy coding, interactions, VIF |\n| `packages/core/src/stats/interaction.ts` | 72 | `getInteractionStrength()` — ΔR² between main-effects and full models |\n| `packages/core/src/stats/modelReduction.ts` | 59 | `suggestTermRemoval()` — guided term elimination |\n| `packages/core/src/matrix.ts` | 291 | `transpose()`, `multiply()`, `inverse()` — linear algebra primitives |\n| `packages/core/src/variation/simulation.ts` | 491 | `simulateFromModel()`, `getFactorBaselines()` — model-driven What-If (partial; `simulateDirectAdjustment` and `calculateProjectedStats` remain exported) |\n\n### Types (defined in `types.ts`, not exported from package index)\n\n`MultiRegressionResult`, `RegressionTerm`, `CoefficientResult`, `VIFWarning`, `InteractionEdge`, `TermRemovalSuggestion`, `FactorAdjustment`, `ModelSimulationResult`\n\n### Active assets (exported, usable today)\n\n| Asset | Location | Notes |\n| ----------------------------- | ------------------------------------------------- | -------------------------------------------------- |\n| ScatterPlot chart | `packages/charts/src/ScatterPlot.tsx` (371 lines) | General-purpose; exported from `@variscout/charts` |\n| WhatIfSimulator (direct mode) | `packages/ui/src/components/WhatIfSimulator/` | Standalone; no regression dependency |\n| `simulateDirectAdjustment()` | `packages/core/src/variation/simulation.ts` | Exported; supports direct What-If |\n| `calculateProjectedStats()` | `packages/core/src/variation/simulation.ts` | Exported; supports direct What-If |\n\n---\n\n## C. Re-enablement Steps\n\n### Step 1: Restore exports (~1 hour)\n\nRe-add exports to package barrel files so the preserved math becomes available to consumers:\n\n- **`packages/core/src/stats/index.ts`** — re-export `calculateRegression`, `calculateMultipleRegression`, `getInteractionStrength`, `suggestTermRemoval`\n- **`packages/core/src/index.ts`** — re-export regression types: `MultiRegressionResult`, `RegressionTerm`, `CoefficientResult`, `VIFWarning`, `InteractionEdge`, `TermRemovalSuggestion`, `FactorAdjustment`, `ModelSimulationResult`\n- **`packages/core/src/variation/index.ts`** — re-export `simulateFromModel`, `getFactorBaselines`\n\n### Step 2: Restore tests (~2 hours)\n\nRecover test files from git history (commit before `35339a3`):\n\n```bash\ngit show 35339a3^:packages/core/src/stats/__tests__/regression.test.ts\ngit show 35339a3^:packages/core/src/stats/__tests__/multiRegression.test.ts\ngit show 35339a3^:packages/core/src/stats/__tests__/modelReduction.test.ts\n```\n\nAdditional restoration:\n\n- Regression blocks in `stats.test.ts`, `stress.test.ts`, `reference-validation.test.ts`, `goldenData.test.ts`\n- Regression-specific terms in `packages/core/src/glossary/terms.ts`\n- Simulation test coverage for `simulateFromModel` and `getFactorBaselines`\n\n### Step 3: Rebuild UI components (~1–2 weeks)\n\nDecide whether to restore verbatim from git or rebuild based on UX validation feedback (re-enablement criterion 3):\n\n| Component | Package | Purpose |\n| ------------------------ | ------------------ | ------------------------------------------- |\n| `RegressionPanelBase` | `@variscout/ui` | Container with simple/advanced toggle |\n| `SimpleRegressionView` | `@variscout/ui` | Single-predictor scatter + fit line |\n| `AdvancedRegressionView` | `@variscout/ui` | Multi-predictor GLM results table |\n| `ExpandedScatterModal` | `@variscout/ui` | Full-screen scatter plot overlay |\n| `useRegressionState` | `@variscout/hooks` | Regression panel state management |\n| `ModelDrivenSimulator` | `@variscout/ui` | What-If driven by fitted model coefficients |\n\nPersistence restoration:\n\n- `RegressionPersistenceState` fields in `useProjectPersistence.ts` and `useDataState.ts`\n- `.vrs` file format backward compatibility (new fields must be optional with defaults)\n\n### Step 4: Restore Mindmap interaction mode (~2–3 days)\n\n- Re-add `'interactions'` to `MindmapMode` type union\n- Restore interaction edge computation in `useMindmapState.ts`\n- Restore `EdgeTooltip` in `packages/charts/src/mindmap/`\n- Restore `factorCount`/`dataCount` gating in `MindmapModeToggle`\n- Re-add `initialPredictors` bridge from Mindmap → Regression panel\n\n### Step 5: Restore app integration (~2–3 days)\n\n- Add Regression tab to PWA and Azure Dashboard\n- Wire toolbar buttons and bridge props (`App.tsx` / `Editor.tsx`)\n- Restore `regressionState`/`setRegressionState` in Azure `DataContext`\n- Restore `'regression'` in embed messaging `ChartId` type\n- Restore `MobileDashboard` regression tab\n\n### Step 6: Restore docs & final tests (~1–2 days)\n\n- Restore app-level test files: `RegressionPanel.test.tsx` (PWA + Azure)\n- Restore E2E regression tab tests\n- Update `variation-decomposition.md` — change Phase 2 references to present tense\n- Re-add regression to `feature-parity.md`, `pricing-tiers.md`, `submission-checklist.md`\n- Restore glossary terms\n- Update `CLAUDE.md` key files table and `MEMORY.md` exports\n\n---\n\n## D. Core Math Enhancements\n\nIndependent of re-enablement, the [GLM Roadmap](glm-roadmap.md) defines 7 enhancements to the preserved OLS engine:\n\n| Priority | Features | Purpose |\n| -------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------- |\n| **1 (Foundation)** | Residual diagnostics + QR decomposition | Return residuals/fitted values; improve numerical stability |\n| **2 (Diagnostics)** | Shapiro-Wilk normality test + leverage/Cook's distance | Warn on model violations; flag influential points |\n| **3 (Distribution)** | Distribution identification (Normal/Lognormal/Weibull/Exponential) | Correct capability analysis for non-normal data |\n| **4 (Advanced)** | Generalized Linear Models (IRLS) + robust/weighted regression | Handle non-normal responses and outliers |\n\nThese enhancements extend the existing engine and can be developed at any time — before, during, or after UI re-enablement. They do not require the UI layer.\n\n---\n\n## E. Removed Code Recovery\n\nAll removed UI code is recoverable from git history:\n\n```bash\n# UI components\ngit show 35339a3^:packages/ui/src/components/RegressionPanel/RegressionPanelBase.tsx\ngit show 35339a3^:packages/ui/src/components/RegressionPanel/SimpleRegressionView.tsx\ngit show 35339a3^:packages/ui/src/components/RegressionPanel/AdvancedRegressionView.tsx\ngit show 35339a3^:packages/ui/src/components/RegressionPanel/ExpandedScatterModal.tsx\n\n# Hooks\ngit show 35339a3^:packages/hooks/src/useRegressionState.ts\n\n# Simulation\ngit show 35339a3^:packages/ui/src/components/WhatIfSimulator/ModelDrivenSimulator.tsx\n\n# Tests\ngit show 35339a3^:packages/hooks/src/__tests__/useRegressionState.test.ts\ngit show 35339a3^:packages/ui/src/components/__tests__/RegressionPanel.test.tsx\n```\n\n**Decision gate:** Restore verbatim vs rebuild from scratch should be made after UX validation (re-enablement criterion 3). If the validation reveals discoverability or comprehension issues with the original UI, rebuilding will produce a better result than patching restored code.\n\n---\n\n## Cross-references\n\n| Topic | Document |\n| ------------------------------------------- | --------------------------------------------------------------------------------- |\n| Deferral decision and criteria | [ADR-014](../../07-decisions/adr-014-regression-deferral.md) |\n| Core math enhancement details | [GLM Roadmap](glm-roadmap.md) |\n| Variation decomposition (ANOVA, drill-down) | [Variation Decomposition](../../03-features/analysis/variation-decomposition.md) |\n| Investigation workflow | [Investigation to Action](../../03-features/workflows/investigation-to-action.md) |\n| What-If simulation (direct mode) | [What-If Simulator](../../06-design-system/components/what-if-simulator.md) |", + "src/content/docs/05-technical/implementation/phase2-regression-roadmap.md", + "9d24cd55897759cc", + { "html": 8750, "metadata": 8751 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"phase-2-regression-re-enablement-roadmap\">Phase 2: Regression Re-enablement Roadmap\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-regression-re-enablement-roadmap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2: Regression Re-enablement Roadmap”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Status:\u003C/strong> Planned — not started\n\u003Cstrong>Prerequisite:\u003C/strong> \u003Ca href=\"../../07-decisions/adr-014-regression-deferral.md\">ADR-014\u003C/a> re-enablement criteria must be met\n\u003Cstrong>Related:\u003C/strong> \u003Ca href=\"glm-roadmap.md\">GLM Roadmap\u003C/a> (core math enhancements)\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"a-re-enablement-criteria\">A. Re-enablement Criteria\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#a-re-enablement-criteria\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “A. Re-enablement Criteria”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All three conditions from ADR-014 must be satisfied before starting Phase 2 work:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Post-marketplace certification\u003C/strong> — Azure App is listed on Azure Marketplace and generating revenue\u003C/li>\n\u003Cli>\u003Cstrong>Customer demand signal\u003C/strong> — At least one paying customer requests regression or the investigation workflow\u003C/li>\n\u003Cli>\u003Cstrong>UX validation\u003C/strong> — Regression workflow tested with target persona (Green Belt Gary) for discoverability and comprehension\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"b-preserved-foundation--inventory\">B. Preserved Foundation — Inventory\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#b-preserved-foundation--inventory\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “B. Preserved Foundation — Inventory”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The core math was preserved in commit \u003Ccode dir=\"auto\">35339a3\u003C/code> (Feb 2026). All source files remain in the repository but are \u003Cstrong>unexported\u003C/strong> from package indexes, so tree-shaking excludes them from production builds.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-math-files-internal-unexported\">Core math files (internal, unexported)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-math-files-internal-unexported\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core math files (internal, unexported)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Lines\u003C/th>\u003Cth>Key Functions\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/stats/regression.ts\u003C/code>\u003C/td>\u003Ctd>279\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">calculateRegression()\u003C/code> — linear + quadratic simple regression\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/stats/multiRegression.ts\u003C/code>\u003C/td>\u003Ctd>558\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">calculateMultipleRegression()\u003C/code> — OLS GLM with dummy coding, interactions, VIF\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/stats/interaction.ts\u003C/code>\u003C/td>\u003Ctd>72\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getInteractionStrength()\u003C/code> — ΔR² between main-effects and full models\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/stats/modelReduction.ts\u003C/code>\u003C/td>\u003Ctd>59\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">suggestTermRemoval()\u003C/code> — guided term elimination\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/matrix.ts\u003C/code>\u003C/td>\u003Ctd>291\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">transpose()\u003C/code>, \u003Ccode dir=\"auto\">multiply()\u003C/code>, \u003Ccode dir=\"auto\">inverse()\u003C/code> — linear algebra primitives\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/variation/simulation.ts\u003C/code>\u003C/td>\u003Ctd>491\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">simulateFromModel()\u003C/code>, \u003Ccode dir=\"auto\">getFactorBaselines()\u003C/code> — model-driven What-If (partial; \u003Ccode dir=\"auto\">simulateDirectAdjustment\u003C/code> and \u003Ccode dir=\"auto\">calculateProjectedStats\u003C/code> remain exported)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"types-defined-in-typests-not-exported-from-package-index\">Types (defined in \u003Ccode dir=\"auto\">types.ts\u003C/code>, not exported from package index)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#types-defined-in-typests-not-exported-from-package-index\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Types (defined in types.ts, not exported from package index)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">MultiRegressionResult\u003C/code>, \u003Ccode dir=\"auto\">RegressionTerm\u003C/code>, \u003Ccode dir=\"auto\">CoefficientResult\u003C/code>, \u003Ccode dir=\"auto\">VIFWarning\u003C/code>, \u003Ccode dir=\"auto\">InteractionEdge\u003C/code>, \u003Ccode dir=\"auto\">TermRemovalSuggestion\u003C/code>, \u003Ccode dir=\"auto\">FactorAdjustment\u003C/code>, \u003Ccode dir=\"auto\">ModelSimulationResult\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"active-assets-exported-usable-today\">Active assets (exported, usable today)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#active-assets-exported-usable-today\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Active assets (exported, usable today)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Asset\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>ScatterPlot chart\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/charts/src/ScatterPlot.tsx\u003C/code> (371 lines)\u003C/td>\u003Ctd>General-purpose; exported from \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>WhatIfSimulator (direct mode)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/WhatIfSimulator/\u003C/code>\u003C/td>\u003Ctd>Standalone; no regression dependency\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">simulateDirectAdjustment()\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/variation/simulation.ts\u003C/code>\u003C/td>\u003Ctd>Exported; supports direct What-If\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">calculateProjectedStats()\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/variation/simulation.ts\u003C/code>\u003C/td>\u003Ctd>Exported; supports direct What-If\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"c-re-enablement-steps\">C. Re-enablement Steps\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#c-re-enablement-steps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “C. Re-enablement Steps”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-1-restore-exports-1-hour\">Step 1: Restore exports (~1 hour)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-restore-exports-1-hour\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Restore exports (~1 hour)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Re-add exports to package barrel files so the preserved math becomes available to consumers:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>\u003Ccode dir=\"auto\">packages/core/src/stats/index.ts\u003C/code>\u003C/strong> — re-export \u003Ccode dir=\"auto\">calculateRegression\u003C/code>, \u003Ccode dir=\"auto\">calculateMultipleRegression\u003C/code>, \u003Ccode dir=\"auto\">getInteractionStrength\u003C/code>, \u003Ccode dir=\"auto\">suggestTermRemoval\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode dir=\"auto\">packages/core/src/index.ts\u003C/code>\u003C/strong> — re-export regression types: \u003Ccode dir=\"auto\">MultiRegressionResult\u003C/code>, \u003Ccode dir=\"auto\">RegressionTerm\u003C/code>, \u003Ccode dir=\"auto\">CoefficientResult\u003C/code>, \u003Ccode dir=\"auto\">VIFWarning\u003C/code>, \u003Ccode dir=\"auto\">InteractionEdge\u003C/code>, \u003Ccode dir=\"auto\">TermRemovalSuggestion\u003C/code>, \u003Ccode dir=\"auto\">FactorAdjustment\u003C/code>, \u003Ccode dir=\"auto\">ModelSimulationResult\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode dir=\"auto\">packages/core/src/variation/index.ts\u003C/code>\u003C/strong> — re-export \u003Ccode dir=\"auto\">simulateFromModel\u003C/code>, \u003Ccode dir=\"auto\">getFactorBaselines\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-2-restore-tests-2-hours\">Step 2: Restore tests (~2 hours)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-restore-tests-2-hours\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Restore tests (~2 hours)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Recover test files from git history (commit before \u003Ccode dir=\"auto\">35339a3\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/core/src/stats/__tests__/regression.test.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/core/src/stats/__tests__/multiRegression.test.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/core/src/stats/__tests__/modelReduction.test.ts\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"git show 35339a3^:packages/core/src/stats/__tests__/regression.test.tsgit show 35339a3^:packages/core/src/stats/__tests__/multiRegression.test.tsgit show 35339a3^:packages/core/src/stats/__tests__/modelReduction.test.ts\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Additional restoration:\u003C/p>\n\u003Cul>\n\u003Cli>Regression blocks in \u003Ccode dir=\"auto\">stats.test.ts\u003C/code>, \u003Ccode dir=\"auto\">stress.test.ts\u003C/code>, \u003Ccode dir=\"auto\">reference-validation.test.ts\u003C/code>, \u003Ccode dir=\"auto\">goldenData.test.ts\u003C/code>\u003C/li>\n\u003Cli>Regression-specific terms in \u003Ccode dir=\"auto\">packages/core/src/glossary/terms.ts\u003C/code>\u003C/li>\n\u003Cli>Simulation test coverage for \u003Ccode dir=\"auto\">simulateFromModel\u003C/code> and \u003Ccode dir=\"auto\">getFactorBaselines\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-3-rebuild-ui-components-12-weeks\">Step 3: Rebuild UI components (~1–2 weeks)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-rebuild-ui-components-12-weeks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Rebuild UI components (~1–2 weeks)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Decide whether to restore verbatim from git or rebuild based on UX validation feedback (re-enablement criterion 3):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Package\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">RegressionPanelBase\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Container with simple/advanced toggle\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">SimpleRegressionView\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Single-predictor scatter + fit line\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">AdvancedRegressionView\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Multi-predictor GLM results table\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ExpandedScatterModal\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Full-screen scatter plot overlay\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useRegressionState\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003Ctd>Regression panel state management\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ModelDrivenSimulator\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>What-If driven by fitted model coefficients\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Persistence restoration:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">RegressionPersistenceState\u003C/code> fields in \u003Ccode dir=\"auto\">useProjectPersistence.ts\u003C/code> and \u003Ccode dir=\"auto\">useDataState.ts\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">.vrs\u003C/code> file format backward compatibility (new fields must be optional with defaults)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-4-restore-mindmap-interaction-mode-23-days\">Step 4: Restore Mindmap interaction mode (~2–3 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-restore-mindmap-interaction-mode-23-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Restore Mindmap interaction mode (~2–3 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Re-add \u003Ccode dir=\"auto\">'interactions'\u003C/code> to \u003Ccode dir=\"auto\">MindmapMode\u003C/code> type union\u003C/li>\n\u003Cli>Restore interaction edge computation in \u003Ccode dir=\"auto\">useMindmapState.ts\u003C/code>\u003C/li>\n\u003Cli>Restore \u003Ccode dir=\"auto\">EdgeTooltip\u003C/code> in \u003Ccode dir=\"auto\">packages/charts/src/mindmap/\u003C/code>\u003C/li>\n\u003Cli>Restore \u003Ccode dir=\"auto\">factorCount\u003C/code>/\u003Ccode dir=\"auto\">dataCount\u003C/code> gating in \u003Ccode dir=\"auto\">MindmapModeToggle\u003C/code>\u003C/li>\n\u003Cli>Re-add \u003Ccode dir=\"auto\">initialPredictors\u003C/code> bridge from Mindmap → Regression panel\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-5-restore-app-integration-23-days\">Step 5: Restore app integration (~2–3 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-restore-app-integration-23-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Restore app integration (~2–3 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Add Regression tab to PWA and Azure Dashboard\u003C/li>\n\u003Cli>Wire toolbar buttons and bridge props (\u003Ccode dir=\"auto\">App.tsx\u003C/code> / \u003Ccode dir=\"auto\">Editor.tsx\u003C/code>)\u003C/li>\n\u003Cli>Restore \u003Ccode dir=\"auto\">regressionState\u003C/code>/\u003Ccode dir=\"auto\">setRegressionState\u003C/code> in Azure \u003Ccode dir=\"auto\">DataContext\u003C/code>\u003C/li>\n\u003Cli>Restore \u003Ccode dir=\"auto\">'regression'\u003C/code> in embed messaging \u003Ccode dir=\"auto\">ChartId\u003C/code> type\u003C/li>\n\u003Cli>Restore \u003Ccode dir=\"auto\">MobileDashboard\u003C/code> regression tab\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-6-restore-docs--final-tests-12-days\">Step 6: Restore docs & final tests (~1–2 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-6-restore-docs--final-tests-12-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 6: Restore docs & final tests (~1–2 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Restore app-level test files: \u003Ccode dir=\"auto\">RegressionPanel.test.tsx\u003C/code> (PWA + Azure)\u003C/li>\n\u003Cli>Restore E2E regression tab tests\u003C/li>\n\u003Cli>Update \u003Ccode dir=\"auto\">variation-decomposition.md\u003C/code> — change Phase 2 references to present tense\u003C/li>\n\u003Cli>Re-add regression to \u003Ccode dir=\"auto\">feature-parity.md\u003C/code>, \u003Ccode dir=\"auto\">pricing-tiers.md\u003C/code>, \u003Ccode dir=\"auto\">submission-checklist.md\u003C/code>\u003C/li>\n\u003Cli>Restore glossary terms\u003C/li>\n\u003Cli>Update \u003Ccode dir=\"auto\">CLAUDE.md\u003C/code> key files table and \u003Ccode dir=\"auto\">MEMORY.md\u003C/code> exports\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"d-core-math-enhancements\">D. Core Math Enhancements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#d-core-math-enhancements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “D. Core Math Enhancements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Independent of re-enablement, the \u003Ca href=\"glm-roadmap.md\">GLM Roadmap\u003C/a> defines 7 enhancements to the preserved OLS engine:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Priority\u003C/th>\u003Cth>Features\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>1 (Foundation)\u003C/strong>\u003C/td>\u003Ctd>Residual diagnostics + QR decomposition\u003C/td>\u003Ctd>Return residuals/fitted values; improve numerical stability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>2 (Diagnostics)\u003C/strong>\u003C/td>\u003Ctd>Shapiro-Wilk normality test + leverage/Cook’s distance\u003C/td>\u003Ctd>Warn on model violations; flag influential points\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>3 (Distribution)\u003C/strong>\u003C/td>\u003Ctd>Distribution identification (Normal/Lognormal/Weibull/Exponential)\u003C/td>\u003Ctd>Correct capability analysis for non-normal data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>4 (Advanced)\u003C/strong>\u003C/td>\u003Ctd>Generalized Linear Models (IRLS) + robust/weighted regression\u003C/td>\u003Ctd>Handle non-normal responses and outliers\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>These enhancements extend the existing engine and can be developed at any time — before, during, or after UI re-enablement. They do not require the UI layer.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"e-removed-code-recovery\">E. Removed Code Recovery\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#e-removed-code-recovery\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “E. Removed Code Recovery”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All removed UI code is recoverable from git history:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># UI components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/ui/src/components/RegressionPanel/RegressionPanelBase.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/ui/src/components/RegressionPanel/SimpleRegressionView.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/ui/src/components/RegressionPanel/AdvancedRegressionView.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/ui/src/components/RegressionPanel/ExpandedScatterModal.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Hooks\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/hooks/src/useRegressionState.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Simulation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/ui/src/components/WhatIfSimulator/ModelDrivenSimulator.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/hooks/src/__tests__/useRegressionState.test.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">git\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">35339a3^:packages/ui/src/components/__tests__/RegressionPanel.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"git show 35339a3^:packages/ui/src/components/RegressionPanel/RegressionPanelBase.tsxgit show 35339a3^:packages/ui/src/components/RegressionPanel/SimpleRegressionView.tsxgit show 35339a3^:packages/ui/src/components/RegressionPanel/AdvancedRegressionView.tsxgit show 35339a3^:packages/ui/src/components/RegressionPanel/ExpandedScatterModal.tsxgit show 35339a3^:packages/hooks/src/useRegressionState.tsgit show 35339a3^:packages/ui/src/components/WhatIfSimulator/ModelDrivenSimulator.tsxgit show 35339a3^:packages/hooks/src/__tests__/useRegressionState.test.tsgit show 35339a3^:packages/ui/src/components/__tests__/RegressionPanel.test.tsx\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Decision gate:\u003C/strong> Restore verbatim vs rebuild from scratch should be made after UX validation (re-enablement criterion 3). If the validation reveals discoverability or comprehension issues with the original UI, rebuilding will produce a better result than patching restored code.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-references\">Cross-references\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-references”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Topic\u003C/th>\u003Cth>Document\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Deferral decision and criteria\u003C/td>\u003Ctd>\u003Ca href=\"../../07-decisions/adr-014-regression-deferral.md\">ADR-014\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Core math enhancement details\u003C/td>\u003Ctd>\u003Ca href=\"glm-roadmap.md\">GLM Roadmap\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Variation decomposition (ANOVA, drill-down)\u003C/td>\u003Ctd>\u003Ca href=\"../../03-features/analysis/variation-decomposition.md\">Variation Decomposition\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Investigation workflow\u003C/td>\u003Ctd>\u003Ca href=\"../../03-features/workflows/investigation-to-action.md\">Investigation to Action\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>What-If simulation (direct mode)\u003C/td>\u003Ctd>\u003Ca href=\"../../06-design-system/components/what-if-simulator.md\">What-If Simulator\u003C/a>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 8752, + "localImagePaths": 8798, + "remoteImagePaths": 8799, + "frontmatter": 8800, + "imagePaths": 8801 + }, + [8753, 8755, 8758, 8761, 8764, 8767, 8770, 8773, 8776, 8779, 8782, 8785, 8788, 8791, 8794, 8797], + { "depth": 30, "slug": 8754, "text": 8742 }, + "phase-2-regression-re-enablement-roadmap", + { "depth": 33, "slug": 8756, "text": 8757 }, + "a-re-enablement-criteria", + "A. Re-enablement Criteria", + { "depth": 33, "slug": 8759, "text": 8760 }, + "b-preserved-foundation--inventory", + "B. Preserved Foundation — Inventory", + { "depth": 79, "slug": 8762, "text": 8763 }, + "core-math-files-internal-unexported", + "Core math files (internal, unexported)", + { "depth": 79, "slug": 8765, "text": 8766 }, + "types-defined-in-typests-not-exported-from-package-index", + "Types (defined in types.ts, not exported from package index)", + { "depth": 79, "slug": 8768, "text": 8769 }, + "active-assets-exported-usable-today", + "Active assets (exported, usable today)", + { "depth": 33, "slug": 8771, "text": 8772 }, + "c-re-enablement-steps", + "C. Re-enablement Steps", + { "depth": 79, "slug": 8774, "text": 8775 }, + "step-1-restore-exports-1-hour", + "Step 1: Restore exports (~1 hour)", + { "depth": 79, "slug": 8777, "text": 8778 }, + "step-2-restore-tests-2-hours", + "Step 2: Restore tests (~2 hours)", + { "depth": 79, "slug": 8780, "text": 8781 }, + "step-3-rebuild-ui-components-12-weeks", + "Step 3: Rebuild UI components (~1–2 weeks)", + { "depth": 79, "slug": 8783, "text": 8784 }, + "step-4-restore-mindmap-interaction-mode-23-days", + "Step 4: Restore Mindmap interaction mode (~2–3 days)", + { "depth": 79, "slug": 8786, "text": 8787 }, + "step-5-restore-app-integration-23-days", + "Step 5: Restore app integration (~2–3 days)", + { "depth": 79, "slug": 8789, "text": 8790 }, + "step-6-restore-docs--final-tests-12-days", + "Step 6: Restore docs & final tests (~1–2 days)", + { "depth": 33, "slug": 8792, "text": 8793 }, + "d-core-math-enhancements", + "D. Core Math Enhancements", + { "depth": 33, "slug": 8795, "text": 8796 }, + "e-removed-code-recovery", + "E. Removed Code Recovery", + { "depth": 33, "slug": 6842, "text": 6843 }, + [], + [], + { "title": 8742 }, + [], + "05-technical/implementation/security-scanning", + { "id": 8802, "data": 8804, "body": 8809, "filePath": 8810, "digest": 8811, "rendered": 8812 }, + { + "title": 8805, + "editUrl": 16, + "head": 8806, + "template": 18, + "sidebar": 8807, + "pagefind": 16, + "draft": 20 + }, + "Security Scanning", + [], + { "hidden": 20, "attrs": 8808 }, + {}, + "# Security Scanning\n\n## Overview\n\nVariScout uses ruflo for automated OWASP security audits. As an offline-first application with no backend, the attack surface is limited, but security scanning ensures dependency safety and code quality.\n\n## Prerequisites\n\n- Node.js 18+\n- ruflo installed (runs via npx)\n\n## Running a Security Scan\n\n### Quick CVE Check\n\n```bash\nnpx ruflo@latest security cve --check\n```\n\n### Full OWASP Scan\n\n```bash\nnpx ruflo@latest security scan --depth full\n```\n\n### Auto-Fix with Agent Swarm\n\n```bash\nnpx ruflo@latest swarm init --v3-mode\nnpx ruflo@latest swarm start --objective \"Fix security issues identified in scan\"\n```\n\n## OWASP Top 10 Coverage\n\n| Category | What We Check |\n| ------------------------------ | ------------------------------------------------------------------------------------- |\n| A01: Broken Access Control | Tier feature gates, Azure Marketplace subscription |\n| A02: Cryptographic Failures | No sensitive keys (tier via ARM params) |\n| A03: Injection | CSV parser input sanitization |\n| A04: Insecure Design | Architecture review |\n| A05: Security Misconfiguration | CSP headers, Permissions-Policy, security headers on all 3 apps, CORS on OBO function |\n| A06: Vulnerable Components | npm audit, CVE database |\n| A07: Authentication Failures | Azure EasyAuth configuration (Azure app) |\n| A08: Data Integrity Failures | Data validation, import/export |\n| A09: Logging Failures | Sensitive data exposure checks |\n| A10: SSRF | External request handling |\n\n## Attack Surface\n\nVariScout is offline-first with no backend. Key security areas:\n\n### Parser Input Handling\n\n- CSV parsing via PapaParse (well-maintained, no known CVEs)\n- Text paste parsing via `parseText()` in `@variscout/core/parser.ts`\n\n### npm Dependencies\n\n- Regular `pnpm audit` for vulnerability scanning\n- ruflo CVE checks for additional coverage\n\n### Azure EasyAuth (Azure App Only)\n\n- App Service Authentication (EasyAuth) — no MSAL libraries\n- API permissions: Standard plan = `User.Read` only; Team plan adds `Files.ReadWrite`, `Files.ReadWrite.All`, `Channel.ReadBasic.All`, `People.Read`, `ChannelMessage.Send`\n- Token store via `/.auth/me` endpoint\n- Periodic background token refresh (45-minute interval) prevents session expiry\n\n### OBO Token Exchange Function (Team Plan)\n\n- Audience validation (`aud === CLIENT_ID`) before token exchange\n- Scope allowlist: only `Files.ReadWrite.All`, `ChannelMessage.Send`, `People.Read` — other scopes rejected\n- CORS with configurable `ALLOWED_ORIGIN` (defaults to `*` for dev)\n- OPTIONS preflight support\n- Optional function-key auth (`FUNCTION_KEY` env var)\n- Generic error messages — no MSAL internals leaked to clients\n- See [authentication.md](../../08-products/azure/authentication.md) for full details\n\n### Audit Scope Exclusions\n\nThe security audit worker excludes non-application paths (`.venv/`, `node_modules/`, `dist/`, `site/`, minified files) to avoid false positives from build tooling and Python MkDocs dependencies.\n\n## Security Hardening\n\n| Measure | Scope | Details |\n| ------------------------------------------------------------------------------------------------------ | ----------------------- | ------------------------------------------------------------------ |\n| Security headers (CSP, HSTS, Permissions-Policy) | Azure App, PWA, Website | See [deployment.md](deployment.md) |\n| OBO function hardening (generic errors, CORS, scope allowlist, audience validation, function-key auth) | Azure App (Team plan) | See [authentication.md](../../08-products/azure/authentication.md) |\n| Service worker (Workbox via vite-plugin-pwa) | PWA | See [PWA docs](../../08-products/pwa/index.md) |\n| Supply chain (Dependabot, SHA-pinned actions, CycloneDX SBOM) | CI/CD | See [deployment.md](deployment.md) |\n| Graceful shutdown (SIGTERM handler) | Azure App server | See [deployment.md](deployment.md) |\n| Periodic token refresh (45-min interval) | Azure App | See [authentication.md](../../08-products/azure/authentication.md) |\n| Vulnerability disclosure (`/.well-known/security.txt`) | Website | `apps/website/public/.well-known/security.txt` |\n\n## Security Backlog\n\n- [ ] PWA icons — generate `pwa-192x192.png` and `pwa-512x512.png` (requires image generation)\n- [ ] Penetration testing — engage external vendor before Marketplace GA\n- [ ] Threat model — STRIDE model covering EasyAuth, OBO, OneDrive sync, service worker\n- [ ] Incident response plan — classification, escalation paths, response procedures\n\n## When to Run\n\n- Before releases\n- After adding new dependencies\n- After significant code changes\n- Periodically (monthly recommended)\n\n## Reviewing Results\n\n| Severity | Action |\n| -------- | ------------------------------ |\n| Critical | Fix immediately, block release |\n| High | Fix before release |\n| Medium | Fix in next sprint |\n| Low | Track and prioritize |\n\n## Known Issues\n\n### Resolved: SheetJS xlsx Package (January 2026)\n\nThe xlsx package was replaced with ExcelJS to resolve CVE-2023-30533 (Prototype Pollution) and a ReDoS vulnerability. The patched xlsx versions (0.19.3+) were only available through SheetJS's commercial CDN.\n\n**Resolution:**\n\n- Replaced `xlsx` with `exceljs` in `@variscout/core`\n- Removed unused `xlsx` from `@variscout/pwa`\n- ExcelJS 4.4.0+ has no known high/critical vulnerabilities\n\n### Transitive Dependency Overrides (March 2026)\n\nTransitive dependencies (pulled in by our dev/build tooling) sometimes lag behind security patches. pnpm's `overrides` field in the root `package.json` pins these to patched versions within their declared semver ranges, so no compatibility breakage occurs.\n\n**Current overrides (9):**\n\n| Override | Pinned To | Pulled In By | Vulnerability |\n| ----------------------------- | --------- | ------------------------------------------------- | ------------------------------- |\n| `minimatch@^3.0.0` | 3.1.5 | eslint 9 → @eslint/eslintrc, @eslint/config-array | ReDoS (high) |\n| `minimatch@^10.0.0` | 10.2.4 | @typescript-eslint → typescript-estree | ReDoS (high) |\n| `rollup@^4.0.0` | 4.59.0 | vite → rollup | Path traversal (high) |\n| `serialize-javascript@^6.0.0` | 7.0.3 | workbox-build → @rollup/plugin-terser | RCE (high) |\n| `undici@>=7.0.0` | 7.24.0 | vitest → jsdom → undici | Unhandled exception (high) |\n| `svgo@^4.0.0` | 4.0.1 | astro → svgo | DoS via entity expansion (high) |\n| `flatted@^3.0.0` | 3.4.0 | eslint → file-entry-cache → flat-cache → flatted | Unbounded recursion DoS (high) |\n| `ajv@^6.0.0` | 6.14.0 | eslint 9 → @eslint/eslintrc | ReDoS (moderate) |\n| `devalue@^5.0.0` | 5.6.3 | astro → devalue | Prototype pollution (low) |\n\nAll are dev/build tooling — none affect the deployed runtime bundle.\n\n**Maintenance:**\n\n1. Run `pnpm audit` after adding or upgrading dependencies\n2. Only add overrides for packages actually in the dependency tree — verify with `pnpm --filter \u003Cpkg> why \u003Cdep>`\n3. When the patched version becomes the natural resolution, the override is harmless but can be removed for cleanliness\n\n**ESLint 10 migration path:** When `eslint-plugin-react` and `eslint-plugin-react-hooks` ship ESLint 10 support, migrating will eliminate the `minimatch@^3.0.0` and `ajv@^6.0.0` overrides (both pulled in via `@eslint/eslintrc`, which ESLint 10 drops). This reduces overrides from 9 → 7.\n\n## Running Verification\n\nAfter fixes, re-run the scan to confirm remediation:\n\n```bash\nnpx ruflo@latest security scan --depth full\n```\n\n## Integration with CI/CD\n\nAdd to your CI pipeline:\n\n```yaml\n- name: Security Scan\n run: npx ruflo@latest security scan --depth full\n```", + "src/content/docs/05-technical/implementation/security-scanning.md", + "96bb743928c2e53a", + { "html": 8813, "metadata": 8814 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"security-scanning\">Security Scanning\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#security-scanning\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Scanning”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses ruflo for automated OWASP security audits. As an offline-first application with no backend, the attack surface is limited, but security scanning ensures dependency safety and code quality.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"prerequisites\">Prerequisites\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#prerequisites\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Prerequisites”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Node.js 18+\u003C/li>\n\u003Cli>ruflo installed (runs via npx)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"running-a-security-scan\">Running a Security Scan\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#running-a-security-scan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Running a Security Scan”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"quick-cve-check\">Quick CVE Check\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#quick-cve-check\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick CVE Check”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">security\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">cve\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--check\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"npx ruflo@latest security cve --check\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"full-owasp-scan\">Full OWASP Scan\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#full-owasp-scan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Full OWASP Scan”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">security\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">scan\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--depth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">full\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"npx ruflo@latest security scan --depth full\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"auto-fix-with-agent-swarm\">Auto-Fix with Agent Swarm\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#auto-fix-with-agent-swarm\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Auto-Fix with Agent Swarm”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">swarm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">init\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--v3-mode\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">swarm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">start\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--objective\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Fix security issues identified in scan\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"npx ruflo@latest swarm init --v3-modenpx ruflo@latest swarm start --objective "Fix security issues identified in scan"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"owasp-top-10-coverage\">OWASP Top 10 Coverage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#owasp-top-10-coverage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “OWASP Top 10 Coverage”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Category\u003C/th>\u003Cth>What We Check\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>A01: Broken Access Control\u003C/td>\u003Ctd>Tier feature gates, Azure Marketplace subscription\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>A02: Cryptographic Failures\u003C/td>\u003Ctd>No sensitive keys (tier via ARM params)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>A03: Injection\u003C/td>\u003Ctd>CSV parser input sanitization\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>A04: Insecure Design\u003C/td>\u003Ctd>Architecture review\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>A05: Security Misconfiguration\u003C/td>\u003Ctd>CSP headers, Permissions-Policy, security headers on all 3 apps, CORS on OBO function\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>A06: Vulnerable Components\u003C/td>\u003Ctd>npm audit, CVE database\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>A07: Authentication Failures\u003C/td>\u003Ctd>Azure EasyAuth configuration (Azure app)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>A08: Data Integrity Failures\u003C/td>\u003Ctd>Data validation, import/export\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>A09: Logging Failures\u003C/td>\u003Ctd>Sensitive data exposure checks\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>A10: SSRF\u003C/td>\u003Ctd>External request handling\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"attack-surface\">Attack Surface\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#attack-surface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Attack Surface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout is offline-first with no backend. Key security areas:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"parser-input-handling\">Parser Input Handling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#parser-input-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Parser Input Handling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>CSV parsing via PapaParse (well-maintained, no known CVEs)\u003C/li>\n\u003Cli>Text paste parsing via \u003Ccode dir=\"auto\">parseText()\u003C/code> in \u003Ccode dir=\"auto\">@variscout/core/parser.ts\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"npm-dependencies\">npm Dependencies\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#npm-dependencies\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “npm Dependencies”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Regular \u003Ccode dir=\"auto\">pnpm audit\u003C/code> for vulnerability scanning\u003C/li>\n\u003Cli>ruflo CVE checks for additional coverage\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-easyauth-azure-app-only\">Azure EasyAuth (Azure App Only)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-easyauth-azure-app-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure EasyAuth (Azure App Only)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>App Service Authentication (EasyAuth) — no MSAL libraries\u003C/li>\n\u003Cli>API permissions: Standard plan = \u003Ccode dir=\"auto\">User.Read\u003C/code> only; Team plan adds \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code>, \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>, \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>, \u003Ccode dir=\"auto\">People.Read\u003C/code>, \u003Ccode dir=\"auto\">ChannelMessage.Send\u003C/code>\u003C/li>\n\u003Cli>Token store via \u003Ccode dir=\"auto\">/.auth/me\u003C/code> endpoint\u003C/li>\n\u003Cli>Periodic background token refresh (45-minute interval) prevents session expiry\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"obo-token-exchange-function-team-plan\">OBO Token Exchange Function (Team Plan)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#obo-token-exchange-function-team-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “OBO Token Exchange Function (Team Plan)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Audience validation (\u003Ccode dir=\"auto\">aud === CLIENT_ID\u003C/code>) before token exchange\u003C/li>\n\u003Cli>Scope allowlist: only \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>, \u003Ccode dir=\"auto\">ChannelMessage.Send\u003C/code>, \u003Ccode dir=\"auto\">People.Read\u003C/code> — other scopes rejected\u003C/li>\n\u003Cli>CORS with configurable \u003Ccode dir=\"auto\">ALLOWED_ORIGIN\u003C/code> (defaults to \u003Ccode dir=\"auto\">*\u003C/code> for dev)\u003C/li>\n\u003Cli>OPTIONS preflight support\u003C/li>\n\u003Cli>Optional function-key auth (\u003Ccode dir=\"auto\">FUNCTION_KEY\u003C/code> env var)\u003C/li>\n\u003Cli>Generic error messages — no MSAL internals leaked to clients\u003C/li>\n\u003Cli>See \u003Ca href=\"../../08-products/azure/authentication.md\">authentication.md\u003C/a> for full details\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"audit-scope-exclusions\">Audit Scope Exclusions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#audit-scope-exclusions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Audit Scope Exclusions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The security audit worker excludes non-application paths (\u003Ccode dir=\"auto\">.venv/\u003C/code>, \u003Ccode dir=\"auto\">node_modules/\u003C/code>, \u003Ccode dir=\"auto\">dist/\u003C/code>, \u003Ccode dir=\"auto\">site/\u003C/code>, minified files) to avoid false positives from build tooling and Python MkDocs dependencies.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security-hardening\">Security Hardening\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security-hardening\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Hardening”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Measure\u003C/th>\u003Cth>Scope\u003C/th>\u003Cth>Details\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Security headers (CSP, HSTS, Permissions-Policy)\u003C/td>\u003Ctd>Azure App, PWA, Website\u003C/td>\u003Ctd>See \u003Ca href=\"deployment.md\">deployment.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OBO function hardening (generic errors, CORS, scope allowlist, audience validation, function-key auth)\u003C/td>\u003Ctd>Azure App (Team plan)\u003C/td>\u003Ctd>See \u003Ca href=\"../../08-products/azure/authentication.md\">authentication.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Service worker (Workbox via vite-plugin-pwa)\u003C/td>\u003Ctd>PWA\u003C/td>\u003Ctd>See \u003Ca href=\"../../08-products/pwa/index.md\">PWA docs\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Supply chain (Dependabot, SHA-pinned actions, CycloneDX SBOM)\u003C/td>\u003Ctd>CI/CD\u003C/td>\u003Ctd>See \u003Ca href=\"deployment.md\">deployment.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Graceful shutdown (SIGTERM handler)\u003C/td>\u003Ctd>Azure App server\u003C/td>\u003Ctd>See \u003Ca href=\"deployment.md\">deployment.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Periodic token refresh (45-min interval)\u003C/td>\u003Ctd>Azure App\u003C/td>\u003Ctd>See \u003Ca href=\"../../08-products/azure/authentication.md\">authentication.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Vulnerability disclosure (\u003Ccode dir=\"auto\">/.well-known/security.txt\u003C/code>)\u003C/td>\u003Ctd>Website\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/website/public/.well-known/security.txt\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security-backlog\">Security Backlog\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security-backlog\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Backlog”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> PWA icons — generate \u003Ccode dir=\"auto\">pwa-192x192.png\u003C/code> and \u003Ccode dir=\"auto\">pwa-512x512.png\u003C/code> (requires image generation)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Penetration testing — engage external vendor before Marketplace GA\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Threat model — STRIDE model covering EasyAuth, OBO, OneDrive sync, service worker\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Incident response plan — classification, escalation paths, response procedures\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"when-to-run\">When to Run\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-run\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Run”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Before releases\u003C/li>\n\u003Cli>After adding new dependencies\u003C/li>\n\u003Cli>After significant code changes\u003C/li>\n\u003Cli>Periodically (monthly recommended)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"reviewing-results\">Reviewing Results\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#reviewing-results\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reviewing Results”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Severity\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Critical\u003C/td>\u003Ctd>Fix immediately, block release\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>High\u003C/td>\u003Ctd>Fix before release\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Medium\u003C/td>\u003Ctd>Fix in next sprint\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Low\u003C/td>\u003Ctd>Track and prioritize\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"known-issues\">Known Issues\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#known-issues\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Known Issues”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"resolved-sheetjs-xlsx-package-january-2026\">Resolved: SheetJS xlsx Package (January 2026)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#resolved-sheetjs-xlsx-package-january-2026\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Resolved: SheetJS xlsx Package (January 2026)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The xlsx package was replaced with ExcelJS to resolve CVE-2023-30533 (Prototype Pollution) and a ReDoS vulnerability. The patched xlsx versions (0.19.3+) were only available through SheetJS’s commercial CDN.\u003C/p>\n\u003Cp>\u003Cstrong>Resolution:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Replaced \u003Ccode dir=\"auto\">xlsx\u003C/code> with \u003Ccode dir=\"auto\">exceljs\u003C/code> in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/li>\n\u003Cli>Removed unused \u003Ccode dir=\"auto\">xlsx\u003C/code> from \u003Ccode dir=\"auto\">@variscout/pwa\u003C/code>\u003C/li>\n\u003Cli>ExcelJS 4.4.0+ has no known high/critical vulnerabilities\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"transitive-dependency-overrides-march-2026\">Transitive Dependency Overrides (March 2026)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#transitive-dependency-overrides-march-2026\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Transitive Dependency Overrides (March 2026)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Transitive dependencies (pulled in by our dev/build tooling) sometimes lag behind security patches. pnpm’s \u003Ccode dir=\"auto\">overrides\u003C/code> field in the root \u003Ccode dir=\"auto\">package.json\u003C/code> pins these to patched versions within their declared semver ranges, so no compatibility breakage occurs.\u003C/p>\n\u003Cp>\u003Cstrong>Current overrides (9):\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Override\u003C/th>\u003Cth>Pinned To\u003C/th>\u003Cth>Pulled In By\u003C/th>\u003Cth>Vulnerability\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">minimatch@^3.0.0\u003C/code>\u003C/td>\u003Ctd>3.1.5\u003C/td>\u003Ctd>eslint 9 → @eslint/eslintrc, @eslint/config-array\u003C/td>\u003Ctd>ReDoS (high)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">minimatch@^10.0.0\u003C/code>\u003C/td>\u003Ctd>10.2.4\u003C/td>\u003Ctd>@typescript-eslint → typescript-estree\u003C/td>\u003Ctd>ReDoS (high)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">rollup@^4.0.0\u003C/code>\u003C/td>\u003Ctd>4.59.0\u003C/td>\u003Ctd>vite → rollup\u003C/td>\u003Ctd>Path traversal (high)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">serialize-javascript@^6.0.0\u003C/code>\u003C/td>\u003Ctd>7.0.3\u003C/td>\u003Ctd>workbox-build → @rollup/plugin-terser\u003C/td>\u003Ctd>RCE (high)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">undici@>=7.0.0\u003C/code>\u003C/td>\u003Ctd>7.24.0\u003C/td>\u003Ctd>vitest → jsdom → undici\u003C/td>\u003Ctd>Unhandled exception (high)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">svgo@^4.0.0\u003C/code>\u003C/td>\u003Ctd>4.0.1\u003C/td>\u003Ctd>astro → svgo\u003C/td>\u003Ctd>DoS via entity expansion (high)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">flatted@^3.0.0\u003C/code>\u003C/td>\u003Ctd>3.4.0\u003C/td>\u003Ctd>eslint → file-entry-cache → flat-cache → flatted\u003C/td>\u003Ctd>Unbounded recursion DoS (high)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ajv@^6.0.0\u003C/code>\u003C/td>\u003Ctd>6.14.0\u003C/td>\u003Ctd>eslint 9 → @eslint/eslintrc\u003C/td>\u003Ctd>ReDoS (moderate)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">devalue@^5.0.0\u003C/code>\u003C/td>\u003Ctd>5.6.3\u003C/td>\u003Ctd>astro → devalue\u003C/td>\u003Ctd>Prototype pollution (low)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>All are dev/build tooling — none affect the deployed runtime bundle.\u003C/p>\n\u003Cp>\u003Cstrong>Maintenance:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Run \u003Ccode dir=\"auto\">pnpm audit\u003C/code> after adding or upgrading dependencies\u003C/li>\n\u003Cli>Only add overrides for packages actually in the dependency tree — verify with \u003Ccode dir=\"auto\">pnpm --filter <pkg> why <dep>\u003C/code>\u003C/li>\n\u003Cli>When the patched version becomes the natural resolution, the override is harmless but can be removed for cleanliness\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>ESLint 10 migration path:\u003C/strong> When \u003Ccode dir=\"auto\">eslint-plugin-react\u003C/code> and \u003Ccode dir=\"auto\">eslint-plugin-react-hooks\u003C/code> ship ESLint 10 support, migrating will eliminate the \u003Ccode dir=\"auto\">minimatch@^3.0.0\u003C/code> and \u003Ccode dir=\"auto\">ajv@^6.0.0\u003C/code> overrides (both pulled in via \u003Ccode dir=\"auto\">@eslint/eslintrc\u003C/code>, which ESLint 10 drops). This reduces overrides from 9 → 7.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"running-verification\">Running Verification\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#running-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Running Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After fixes, re-run the scan to confirm remediation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">npx\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">ruflo@latest\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">security\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">scan\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--depth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">full\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"npx ruflo@latest security scan --depth full\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"integration-with-cicd\">Integration with CI/CD\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#integration-with-cicd\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integration with CI/CD”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Add to your CI pipeline:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"yaml\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">- \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Security Scan\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#111111\">run\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">npx ruflo@latest security scan --depth full\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"- name: Security Scan run: npx ruflo@latest security scan --depth full\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>", + { + "headings": 8815, + "localImagePaths": 8880, + "remoteImagePaths": 8881, + "frontmatter": 8882, + "imagePaths": 8883 + }, + [ + 8816, 8818, 8819, 8820, 8823, 8826, 8829, 8832, 8835, 8838, 8841, 8844, 8847, 8850, 8853, 8856, + 8859, 8862, 8865, 8868, 8871, 8874, 8877 + ], + { "depth": 30, "slug": 8817, "text": 8805 }, + "security-scanning", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 6401, "text": 6402 }, + { "depth": 33, "slug": 8821, "text": 8822 }, + "running-a-security-scan", + "Running a Security Scan", + { "depth": 79, "slug": 8824, "text": 8825 }, + "quick-cve-check", + "Quick CVE Check", + { "depth": 79, "slug": 8827, "text": 8828 }, + "full-owasp-scan", + "Full OWASP Scan", + { "depth": 79, "slug": 8830, "text": 8831 }, + "auto-fix-with-agent-swarm", + "Auto-Fix with Agent Swarm", + { "depth": 33, "slug": 8833, "text": 8834 }, + "owasp-top-10-coverage", + "OWASP Top 10 Coverage", + { "depth": 33, "slug": 8836, "text": 8837 }, + "attack-surface", + "Attack Surface", + { "depth": 79, "slug": 8839, "text": 8840 }, + "parser-input-handling", + "Parser Input Handling", + { "depth": 79, "slug": 8842, "text": 8843 }, + "npm-dependencies", + "npm Dependencies", + { "depth": 79, "slug": 8845, "text": 8846 }, + "azure-easyauth-azure-app-only", + "Azure EasyAuth (Azure App Only)", + { "depth": 79, "slug": 8848, "text": 8849 }, + "obo-token-exchange-function-team-plan", + "OBO Token Exchange Function (Team Plan)", + { "depth": 79, "slug": 8851, "text": 8852 }, + "audit-scope-exclusions", + "Audit Scope Exclusions", + { "depth": 33, "slug": 8854, "text": 8855 }, + "security-hardening", + "Security Hardening", + { "depth": 33, "slug": 8857, "text": 8858 }, + "security-backlog", + "Security Backlog", + { "depth": 33, "slug": 8860, "text": 8861 }, + "when-to-run", + "When to Run", + { "depth": 33, "slug": 8863, "text": 8864 }, + "reviewing-results", + "Reviewing Results", + { "depth": 33, "slug": 8866, "text": 8867 }, + "known-issues", + "Known Issues", + { "depth": 79, "slug": 8869, "text": 8870 }, + "resolved-sheetjs-xlsx-package-january-2026", + "Resolved: SheetJS xlsx Package (January 2026)", + { "depth": 79, "slug": 8872, "text": 8873 }, + "transitive-dependency-overrides-march-2026", + "Transitive Dependency Overrides (March 2026)", + { "depth": 33, "slug": 8875, "text": 8876 }, + "running-verification", + "Running Verification", + { "depth": 33, "slug": 8878, "text": 8879 }, + "integration-with-cicd", + "Integration with CI/CD", + [], + [], + { "title": 8805 }, + [], + "05-technical/implementation/system-limits", + { "id": 8884, "data": 8886, "body": 8891, "filePath": 8892, "digest": 8893, "rendered": 8894 }, + { + "title": 8887, + "editUrl": 16, + "head": 8888, + "template": 18, + "sidebar": 8889, + "pagefind": 16, + "draft": 20 + }, + "System Limits", + [], + { "hidden": 20, "attrs": 8890 }, + {}, + "# System Limits\n\nComprehensive reference for VariScout's data handling limits, classification thresholds, and display boundaries. All computation runs in-browser JavaScript with no server offload.\n\n## Data Import Limits\n\n| Constraint | Value | Location | Behavior |\n| ----------------------------- | ------------------------------ | --------------------------- | -------------------------------------------------------------------------------------------- |\n| Row hard limit | 50,000 (PWA) / 100,000 (Azure) | `useDataIngestion.ts` | Alert shown, upload rejected. Configurable via `DataIngestionConfig.rowHardLimit` |\n| Row warning | 5,000 (PWA) / 10,000 (Azure) | `useDataIngestion.ts` | Confirm dialog, user can proceed. Configurable via `DataIngestionConfig.rowWarningThreshold` |\n| Column limit | None enforced | — | All columns loaded |\n| Auto-detected factors | 3 suggested | `parser.ts detectColumns()` | `.slice(0, 3)` default suggestion |\n| Max selectable factors | 3 (PWA) / 6 (Azure) | `ColumnMapping` | Configurable via `maxFactors` prop |\n| Factor change during analysis | Both (PWA 3, Azure 6) | ColumnMapping `mode='edit'` | \"Factors\" button in nav bar reopens ColumnMapping |\n\n## Categorical Classification\n\nTwo thresholds govern whether a string column becomes a selectable factor:\n\n| Threshold | Value | Location | Purpose |\n| ------------------------ | ---------------- | ----------------------------- | --------------------------------------------------------------------------- |\n| Parser categorical limit | 50 unique values | `parser.ts analyzeColumn()` | Columns with >50 unique strings classified as `'text'`, excluded as factors |\n| Hook categorical limit | 10 unique values | `useColumnClassification.ts` | Default for UI factor selection (configurable via `maxCategoricalUnique`) |\n| Stage columns limit | 10 unique values | `useAvailableStageColumns.ts` | Staged analysis column filtering |\n\n**Design intent:** The parser threshold (50) determines what _could_ be a factor. The hook threshold (10) determines what _should_ be offered by default in the UI. Columns with 11-50 unique values are loaded into the data model but not surfaced as factors unless the threshold is customized.\n\n## Analysis Display Limits\n\n| Chart | Max Items | Location | Behavior |\n| ------------------- | ------------- | ------------------------ | ---------------------------------------------------------- |\n| Performance Boxplot | 5 channels | `PerformanceBoxplot.tsx` | Shows top 5 |\n| Performance Pareto | 20 channels | `PerformancePareto.tsx` | Shows top 20 |\n| Standard Pareto | No hard limit | `ParetoChart.tsx` | All groups rendered (bounded by 50-value parser threshold) |\n| Standard Boxplot | No hard limit | `Boxplot.tsx` | All groups rendered |\n| AnovaResults groups | No hard limit | `AnovaResults.tsx` | All groups shown inline |\n\n## Performance Mode\n\n| Constraint | Value | Location |\n| ----------------------- | ----- | --------- |\n| Enterprise max channels | 1,500 | `tier.ts` |\n| Channel warning | 700 | `tier.ts` |\n| Free tier max channels | 5 | `tier.ts` |\n\n## Realistic Scenario Guidance\n\nWhat VariScout handles well vs. what requires data pre-aggregation:\n\n| Scenario | Rows | Factor Cardinality | Works? |\n| -------------------------------------------------------- | ------- | ------------------ | --------------------------------------------------------------------------------------------------------- |\n| Single production line, 3 shifts, weekly data for 1 year | ~1,000 | Shift(3), Week(52) | Yes — within all limits. Week column classified as categorical (\u003C=50 unique). |\n| Pharma fill line, 12 heads, 3 shifts, 1 month | ~10,000 | Head(12), Shift(3) | Yes — smooth. Both factors well within thresholds. |\n| Multi-SKU packaging, 200 products, daily data | ~5,000 | Product(200) | Partially — products classified as `'text'` (>50 unique). Pre-filter to top 20-50 products before import. |\n| Supplier quality, 500 suppliers | ~10,000 | Supplier(500) | No direct drill — supplier column excluded. Aggregate by supplier group/region first. |\n| High-frequency sensor data, 1 reading/sec for 8 hours | 28,800 | Time-based | Works for stats, but time column treated as numeric not categorical. |\n| Large production dataset (Azure) | 80,000 | Head(12), Shift(3) | Azure only — 100K row limit accommodates larger datasets. |\n\n## Browser Memory\n\n- IndexedDB quotas are browser-dependent (Chrome 60% of disk, Firefox 50%, Safari 1GB)\n- All computation is in-browser JavaScript — no server offload\n- PWA: 50K rows x 20 columns x ~100 bytes/cell = ~100MB working memory — well within modern browser limits\n- Azure: 100K rows x 20 columns x ~100 bytes/cell = ~200MB working memory — acceptable for desktop browsers\n- Boxplot uses iterative min/max (no spread operator) to avoid stack-overflow with large outlier arrays", + "src/content/docs/05-technical/implementation/system-limits.md", + "d9ce32c3f0145490", + { "html": 8895, "metadata": 8896 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"system-limits\">System Limits\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#system-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “System Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Comprehensive reference for VariScout’s data handling limits, classification thresholds, and display boundaries. All computation runs in-browser JavaScript with no server offload.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-import-limits\">Data Import Limits\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-import-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Import Limits”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Constraint\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Row hard limit\u003C/td>\u003Ctd>50,000 (PWA) / 100,000 (Azure)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useDataIngestion.ts\u003C/code>\u003C/td>\u003Ctd>Alert shown, upload rejected. Configurable via \u003Ccode dir=\"auto\">DataIngestionConfig.rowHardLimit\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Row warning\u003C/td>\u003Ctd>5,000 (PWA) / 10,000 (Azure)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useDataIngestion.ts\u003C/code>\u003C/td>\u003Ctd>Confirm dialog, user can proceed. Configurable via \u003Ccode dir=\"auto\">DataIngestionConfig.rowWarningThreshold\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Column limit\u003C/td>\u003Ctd>None enforced\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>All columns loaded\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Auto-detected factors\u003C/td>\u003Ctd>3 suggested\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">parser.ts detectColumns()\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">.slice(0, 3)\u003C/code> default suggestion\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Max selectable factors\u003C/td>\u003Ctd>3 (PWA) / 6 (Azure)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ColumnMapping\u003C/code>\u003C/td>\u003Ctd>Configurable via \u003Ccode dir=\"auto\">maxFactors\u003C/code> prop\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Factor change during analysis\u003C/td>\u003Ctd>Both (PWA 3, Azure 6)\u003C/td>\u003Ctd>ColumnMapping \u003Ccode dir=\"auto\">mode='edit'\u003C/code>\u003C/td>\u003Ctd>”Factors” button in nav bar reopens ColumnMapping\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"categorical-classification\">Categorical Classification\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#categorical-classification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Categorical Classification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Two thresholds govern whether a string column becomes a selectable factor:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Threshold\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Parser categorical limit\u003C/td>\u003Ctd>50 unique values\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">parser.ts analyzeColumn()\u003C/code>\u003C/td>\u003Ctd>Columns with >50 unique strings classified as \u003Ccode dir=\"auto\">'text'\u003C/code>, excluded as factors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hook categorical limit\u003C/td>\u003Ctd>10 unique values\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useColumnClassification.ts\u003C/code>\u003C/td>\u003Ctd>Default for UI factor selection (configurable via \u003Ccode dir=\"auto\">maxCategoricalUnique\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Stage columns limit\u003C/td>\u003Ctd>10 unique values\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useAvailableStageColumns.ts\u003C/code>\u003C/td>\u003Ctd>Staged analysis column filtering\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Design intent:\u003C/strong> The parser threshold (50) determines what \u003Cem>could\u003C/em> be a factor. The hook threshold (10) determines what \u003Cem>should\u003C/em> be offered by default in the UI. Columns with 11-50 unique values are loaded into the data model but not surfaced as factors unless the threshold is customized.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysis-display-limits\">Analysis Display Limits\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-display-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis Display Limits”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Max Items\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Performance Boxplot\u003C/td>\u003Ctd>5 channels\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceBoxplot.tsx\u003C/code>\u003C/td>\u003Ctd>Shows top 5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Pareto\u003C/td>\u003Ctd>20 channels\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">PerformancePareto.tsx\u003C/code>\u003C/td>\u003Ctd>Shows top 20\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Standard Pareto\u003C/td>\u003Ctd>No hard limit\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ParetoChart.tsx\u003C/code>\u003C/td>\u003Ctd>All groups rendered (bounded by 50-value parser threshold)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Standard Boxplot\u003C/td>\u003Ctd>No hard limit\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Boxplot.tsx\u003C/code>\u003C/td>\u003Ctd>All groups rendered\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>AnovaResults groups\u003C/td>\u003Ctd>No hard limit\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">AnovaResults.tsx\u003C/code>\u003C/td>\u003Ctd>All groups shown inline\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performance-mode\">Performance Mode\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performance-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Mode”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Constraint\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>Location\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Enterprise max channels\u003C/td>\u003Ctd>1,500\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">tier.ts\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Channel warning\u003C/td>\u003Ctd>700\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">tier.ts\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Free tier max channels\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">tier.ts\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"realistic-scenario-guidance\">Realistic Scenario Guidance\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#realistic-scenario-guidance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Realistic Scenario Guidance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>What VariScout handles well vs. what requires data pre-aggregation:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Scenario\u003C/th>\u003Cth>Rows\u003C/th>\u003Cth>Factor Cardinality\u003C/th>\u003Cth>Works?\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Single production line, 3 shifts, weekly data for 1 year\u003C/td>\u003Ctd>~1,000\u003C/td>\u003Ctd>Shift(3), Week(52)\u003C/td>\u003Ctd>Yes — within all limits. Week column classified as categorical (<=50 unique).\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pharma fill line, 12 heads, 3 shifts, 1 month\u003C/td>\u003Ctd>~10,000\u003C/td>\u003Ctd>Head(12), Shift(3)\u003C/td>\u003Ctd>Yes — smooth. Both factors well within thresholds.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multi-SKU packaging, 200 products, daily data\u003C/td>\u003Ctd>~5,000\u003C/td>\u003Ctd>Product(200)\u003C/td>\u003Ctd>Partially — products classified as \u003Ccode dir=\"auto\">'text'\u003C/code> (>50 unique). Pre-filter to top 20-50 products before import.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Supplier quality, 500 suppliers\u003C/td>\u003Ctd>~10,000\u003C/td>\u003Ctd>Supplier(500)\u003C/td>\u003Ctd>No direct drill — supplier column excluded. Aggregate by supplier group/region first.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>High-frequency sensor data, 1 reading/sec for 8 hours\u003C/td>\u003Ctd>28,800\u003C/td>\u003Ctd>Time-based\u003C/td>\u003Ctd>Works for stats, but time column treated as numeric not categorical.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Large production dataset (Azure)\u003C/td>\u003Ctd>80,000\u003C/td>\u003Ctd>Head(12), Shift(3)\u003C/td>\u003Ctd>Azure only — 100K row limit accommodates larger datasets.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"browser-memory\">Browser Memory\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#browser-memory\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Browser Memory”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>IndexedDB quotas are browser-dependent (Chrome 60% of disk, Firefox 50%, Safari 1GB)\u003C/li>\n\u003Cli>All computation is in-browser JavaScript — no server offload\u003C/li>\n\u003Cli>PWA: 50K rows x 20 columns x ~100 bytes/cell = ~100MB working memory — well within modern browser limits\u003C/li>\n\u003Cli>Azure: 100K rows x 20 columns x ~100 bytes/cell = ~200MB working memory — acceptable for desktop browsers\u003C/li>\n\u003Cli>Boxplot uses iterative min/max (no spread operator) to avoid stack-overflow with large outlier arrays\u003C/li>\n\u003C/ul>", + { + "headings": 8897, + "localImagePaths": 8916, + "remoteImagePaths": 8917, + "frontmatter": 8918, + "imagePaths": 8919 + }, + [8898, 8900, 8903, 8906, 8909, 8910, 8913], + { "depth": 30, "slug": 8899, "text": 8887 }, + "system-limits", + { "depth": 33, "slug": 8901, "text": 8902 }, + "data-import-limits", + "Data Import Limits", + { "depth": 33, "slug": 8904, "text": 8905 }, + "categorical-classification", + "Categorical Classification", + { "depth": 33, "slug": 8907, "text": 8908 }, + "analysis-display-limits", + "Analysis Display Limits", + { "depth": 33, "slug": 6582, "text": 6570 }, + { "depth": 33, "slug": 8911, "text": 8912 }, + "realistic-scenario-guidance", + "Realistic Scenario Guidance", + { "depth": 33, "slug": 8914, "text": 8915 }, + "browser-memory", + "Browser Memory", + [], + [], + { "title": 8887 }, + [], + "05-technical/integrations/embed-messaging", + { "id": 8920, "data": 8922, "body": 8927, "filePath": 8928, "digest": 8929, "rendered": 8930 }, + { + "title": 8923, + "editUrl": 16, + "head": 8924, + "template": 18, + "sidebar": 8925, + "pagefind": 16, + "draft": 20 + }, + "PWA Embed Messaging Protocol", + [], + { "hidden": 20, "attrs": 8926 }, + {}, + "# PWA Embed Messaging Protocol\n\nCommunication protocol for iframe-embedded PWA (when used externally).\n\n## Overview\n\nPostMessage-based bidirectional communication for when the PWA is embedded in an iframe by third parties. The protocol enables parent windows to control chart highlights and receive interaction events.\n\n> **Note:** The VariScout marketing website no longer uses iframe embedding. As of the React Islands migration, the website renders charts directly using `@variscout/charts` components with data from `@variscout/data`. This protocol remains available for third-party integrations or external documentation sites that want to embed the PWA.\n\n## Security\n\n- **Origin validation**: Only accepts messages from `variscout.com`, `*.variscout.com`, and `localhost`\n- **Message prefixing**: All messages use `variscout-embed` type prefix\n- **No sensitive data**: Only UI state (chart IDs, highlight styles) transmitted\n\n## Message Types\n\n### Parent → PWA (EmbedMessage)\n\n```typescript\ninterface EmbedMessage {\n type: 'variscout-embed';\n action: 'highlight-chart' | 'clear-highlight' | 'ping' | 'scroll-to-chart';\n payload?: {\n chartId?: ChartId;\n intensity?: HighlightIntensity;\n };\n messageId: string;\n}\n```\n\n| Action | Payload | Description |\n| ----------------- | ------------------------ | ------------------------ |\n| `highlight-chart` | `{ chartId, intensity }` | Highlight specific chart |\n| `clear-highlight` | - | Remove all highlights |\n| `ping` | - | Health check |\n| `scroll-to-chart` | `{ chartId }` | Scroll chart into view |\n\n### PWA → Parent (EmbedResponse)\n\n```typescript\ninterface EmbedResponse {\n type: 'variscout-embed-response';\n action: 'ready' | 'pong' | 'chart-clicked' | 'highlight-applied';\n payload?: {\n chartId?: ChartId;\n success?: boolean;\n };\n messageId?: string;\n}\n```\n\n| Action | Payload | Description |\n| ------------------- | ------------- | --------------------------------- |\n| `ready` | - | PWA loaded and ready for messages |\n| `pong` | - | Response to ping |\n| `chart-clicked` | `{ chartId }` | User clicked a chart |\n| `highlight-applied` | `{ success }` | Confirmation of highlight action |\n\n## Chart IDs\n\n```typescript\ntype ChartId = 'ichart' | 'boxplot' | 'pareto' | 'stats' | 'regression';\n```\n\n| ID | Chart |\n| ------------ | ----------------------------------- |\n| `ichart` | I-Chart (Individuals Control Chart) |\n| `boxplot` | Box Plot |\n| `pareto` | Pareto Chart |\n| `stats` | Statistics Panel |\n| `regression` | Regression Panel |\n\n## Highlight Intensities\n\n```typescript\ntype HighlightIntensity = 'pulse' | 'glow' | 'border';\n```\n\n| Intensity | CSS Class | Description |\n| --------- | ------------------------- | ------------------------------- |\n| `pulse` | `.chart-highlight-pulse` | Animated pulsing ring (default) |\n| `glow` | `.chart-highlight-glow` | Soft blue glow effect |\n| `border` | `.chart-highlight-border` | Simple 2px border |\n\n## PWA Integration (useEmbedMessaging hook)\n\nLocation: `apps/pwa/src/hooks/useEmbedMessaging.ts`\n\n```typescript\nimport { useEmbedMessaging } from './hooks/useEmbedMessaging';\n\nfunction App() {\n const [isEmbedMode] = useState(/* check ?embed=true */);\n\n const {\n highlightedChart, // Currently highlighted chart ID\n highlightIntensity, // Current highlight style\n isReady, // Whether messaging is initialized\n notifyChartClicked, // Callback when user clicks chart\n } = useEmbedMessaging(isEmbedMode);\n\n return (\n \u003CDashboard\n highlightedChart={highlightedChart}\n highlightIntensity={highlightIntensity}\n onChartClick={isEmbedMode ? notifyChartClicked : undefined}\n />\n );\n}\n```\n\n## Third-Party Integration Example\n\nFor external sites wanting to embed the PWA:\n\n```html\n\u003Ciframe\n id=\"variscout-embed\"\n src=\"https://app.variscout.com?embed=true&sample=coffee\"\n width=\"100%\"\n height=\"600\"\n>\u003C/iframe>\n\n\u003Cscript>\n const iframe = document.getElementById('variscout-embed');\n\n // Wait for PWA to be ready\n window.addEventListener('message', event => {\n if (event.data.type === 'variscout-embed-response') {\n if (event.data.action === 'ready') {\n console.log('PWA ready for commands');\n }\n }\n });\n\n // Send highlight command\n function highlightChart(chartId) {\n iframe.contentWindow.postMessage(\n {\n type: 'variscout-embed',\n action: 'highlight-chart',\n payload: { chartId, intensity: 'pulse' },\n messageId: crypto.randomUUID(),\n },\n '*'\n );\n }\n\u003C/script>\n```\n\n## Debugging\n\n### Console Logging\n\nMessages are logged with `[EmbedMessaging]` prefix:\n\n- `[EmbedMessaging] Rejected message from: \u003Corigin>` - Origin validation failed\n- `[EmbedMessaging] Failed to send message: \u003Cerror>` - PostMessage error\n- `[EmbedMessaging] Unknown action: \u003Caction>` - Unrecognized action\n\n### DevTools Tips\n\n1. Open iframe in separate tab to see its console\n2. Use Network tab to verify iframe loads\n3. Check Application > Frames to inspect iframe origin\n\n## Flow Diagram\n\n```\n┌─────────────┐ ┌─────────────┐\n│ Parent │ │ PWA │\n│ (embedder) │ │ (iframe) │\n└─────────────┘ └─────────────┘\n │ │\n │ iframe loads │\n │ ◄──────────────────────────────────│\n │ │\n │ { action: 'ready' } │\n │ ◄──────────────────────────────────│\n │ │\n │ { action: 'highlight-chart', │\n │ payload: { chartId: 'boxplot' │\n │ intensity: 'pulse'}}│\n │ ──────────────────────────────────►│\n │ │\n │ { action: 'highlight-applied', │\n │ payload: { success: true }} │\n │ ◄──────────────────────────────────│\n │ │\n │ User clicks chart │\n │ │\n │ { action: 'chart-clicked', │\n │ payload: { chartId: 'boxplot'}}│\n │ ◄──────────────────────────────────│\n │ │\n```\n\n## Related Files\n\n- `apps/pwa/src/hooks/useEmbedMessaging.ts` - PWA message handler\n- `apps/pwa/src/components/Dashboard.tsx` - Highlight prop consumer\n- `apps/pwa/src/index.css` - Highlight CSS classes\n\n## Marketing Website Architecture (React Islands)\n\nThe VariScout marketing website uses a different architecture that doesn't require iframe messaging:\n\n- **React Islands**: Chart components render directly on the page using Astro's `client:only=\"react\"` directive\n- **Data Package**: Pre-computed sample data from `@variscout/data`\n- **Chart Components**: Direct imports from `@variscout/charts`\n\nSee the [Website product documentation](../../08-products/website/index.md) for the current website architecture.", + "src/content/docs/05-technical/integrations/embed-messaging.md", + "abcbab489e50d234", + { "html": 8931, "metadata": 8932 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"pwa-embed-messaging-protocol\">PWA Embed Messaging Protocol\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-embed-messaging-protocol\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA Embed Messaging Protocol”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Communication protocol for iframe-embedded PWA (when used externally).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>PostMessage-based bidirectional communication for when the PWA is embedded in an iframe by third parties. The protocol enables parent windows to control chart highlights and receive interaction events.\u003C/p>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note:\u003C/strong> The VariScout marketing website no longer uses iframe embedding. As of the React Islands migration, the website renders charts directly using \u003Ccode dir=\"auto\">@variscout/charts\u003C/code> components with data from \u003Ccode dir=\"auto\">@variscout/data\u003C/code>. This protocol remains available for third-party integrations or external documentation sites that want to embed the PWA.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security\">Security\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Origin validation\u003C/strong>: Only accepts messages from \u003Ccode dir=\"auto\">variscout.com\u003C/code>, \u003Ccode dir=\"auto\">*.variscout.com\u003C/code>, and \u003Ccode dir=\"auto\">localhost\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Message prefixing\u003C/strong>: All messages use \u003Ccode dir=\"auto\">variscout-embed\u003C/code> type prefix\u003C/li>\n\u003Cli>\u003Cstrong>No sensitive data\u003C/strong>: Only UI state (chart IDs, highlight styles) transmitted\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"message-types\">Message Types\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#message-types\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Message Types”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"parent--pwa-embedmessage\">Parent → PWA (EmbedMessage)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#parent--pwa-embedmessage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Parent → PWA (EmbedMessage)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> EmbedMessage {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">type\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">variscout-embed\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">action\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">highlight-chart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">clear-highlight\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ping\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">scroll-to-chart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">payload\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">intensity\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">HighlightIntensity\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">messageId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface EmbedMessage { type: 'variscout-embed'; action: 'highlight-chart' | 'clear-highlight' | 'ping' | 'scroll-to-chart'; payload?: { chartId?: ChartId; intensity?: HighlightIntensity; }; messageId: string;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>Payload\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">highlight-chart\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{ chartId, intensity }\u003C/code>\u003C/td>\u003Ctd>Highlight specific chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">clear-highlight\u003C/code>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Remove all highlights\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ping\u003C/code>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Health check\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">scroll-to-chart\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{ chartId }\u003C/code>\u003C/td>\u003Ctd>Scroll chart into view\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa--parent-embedresponse\">PWA → Parent (EmbedResponse)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa--parent-embedresponse\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA → Parent (EmbedResponse)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> EmbedResponse {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">type\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">variscout-embed-response\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">action\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ready\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pong\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">chart-clicked\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">highlight-applied\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">payload\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartId\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">success\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">messageId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface EmbedResponse { type: 'variscout-embed-response'; action: 'ready' | 'pong' | 'chart-clicked' | 'highlight-applied'; payload?: { chartId?: ChartId; success?: boolean; }; messageId?: string;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>Payload\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ready\u003C/code>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>PWA loaded and ready for messages\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">pong\u003C/code>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Response to ping\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">chart-clicked\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{ chartId }\u003C/code>\u003C/td>\u003Ctd>User clicked a chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">highlight-applied\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">{ success }\u003C/code>\u003C/td>\u003Ctd>Confirmation of highlight action\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-ids\">Chart IDs\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-ids\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart IDs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChartId \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ichart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">stats\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">regression\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"type ChartId = 'ichart' | 'boxplot' | 'pareto' | 'stats' | 'regression';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>ID\u003C/th>\u003Cth>Chart\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ichart\u003C/code>\u003C/td>\u003Ctd>I-Chart (Individuals Control Chart)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">boxplot\u003C/code>\u003C/td>\u003Ctd>Box Plot\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">pareto\u003C/code>\u003C/td>\u003Ctd>Pareto Chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stats\u003C/code>\u003C/td>\u003Ctd>Statistics Panel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">regression\u003C/code>\u003C/td>\u003Ctd>Regression Panel\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"highlight-intensities\">Highlight Intensities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#highlight-intensities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Highlight Intensities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> HighlightIntensity \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pulse\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">glow\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">border\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"type HighlightIntensity = 'pulse' | 'glow' | 'border';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Intensity\u003C/th>\u003Cth>CSS Class\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">pulse\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">.chart-highlight-pulse\u003C/code>\u003C/td>\u003Ctd>Animated pulsing ring (default)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">glow\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">.chart-highlight-glow\u003C/code>\u003C/td>\u003Ctd>Soft blue glow effect\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">border\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">.chart-highlight-border\u003C/code>\u003C/td>\u003Ctd>Simple 2px border\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pwa-integration-useembedmessaging-hook\">PWA Integration (useEmbedMessaging hook)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-integration-useembedmessaging-hook\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA Integration (useEmbedMessaging hook)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Location: \u003Ccode dir=\"auto\">apps/pwa/src/hooks/useEmbedMessaging.ts\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useEmbedMessaging } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./hooks/useEmbedMessaging\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">App\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const [\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isEmbedMode\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">] = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useState\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* check ?embed=true */\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">highlightedChart\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Currently highlighted chart ID\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">highlightIntensity\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Current highlight style\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isReady\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Whether messaging is initialized\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">notifyChartClicked\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Callback when user clicks chart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">} = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useEmbedMessaging\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(isEmbedMode);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">Dashboard\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">highlightedChart\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{highlightedChart}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">highlightIntensity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{highlightIntensity}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onChartClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{isEmbedMode ? notifyChartClicked : \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useEmbedMessaging } from './hooks/useEmbedMessaging';function App() { const [isEmbedMode] = useState(/* check ?embed=true */); const { highlightedChart, // Currently highlighted chart ID highlightIntensity, // Current highlight style isReady, // Whether messaging is initialized notifyChartClicked, // Callback when user clicks chart } = useEmbedMessaging(isEmbedMode); return ( \u003CDashboard highlightedChart={highlightedChart} highlightIntensity={highlightIntensity} onChartClick={isEmbedMode ? notifyChartClicked : undefined} /> );}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"third-party-integration-example\">Third-Party Integration Example\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#third-party-integration-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Third-Party Integration Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For external sites wanting to embed the PWA:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">iframe\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">variscout-embed\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">src\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://app.variscout.com?embed=true&sample=coffee\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">100%\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">600\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\">></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">iframe\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">script\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">iframe\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">document\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getElementById\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">variscout-embed\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Wait for PWA to be ready\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">window\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addEventListener\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">message\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">event\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">event\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">variscout-embed-response\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">event\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">action\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ready\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">PWA ready for commands\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Send highlight command\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">highlightChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">chartId\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">iframe\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">contentWindow\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">postMessage\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">type: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">variscout-embed\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">action: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">highlight-chart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">payload: { \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">chartId\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> intensity: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pulse\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">messageId: \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">crypto\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">randomUUID\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003Cspan style=\"--0:#889FB2;--1:#4D667B\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">*\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">script\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ciframe id="variscout-embed" src="https://app.variscout.com?embed=true&sample=coffee" width="100%" height="600">\u003C/iframe>\u003Cscript> const iframe = document.getElementById('variscout-embed'); // Wait for PWA to be ready window.addEventListener('message', event => { if (event.data.type === 'variscout-embed-response') { if (event.data.action === 'ready') { console.log('PWA ready for commands'); } } }); // Send highlight command function highlightChart(chartId) { iframe.contentWindow.postMessage( { type: 'variscout-embed', action: 'highlight-chart', payload: { chartId, intensity: 'pulse' }, messageId: crypto.randomUUID(), }, '*' ); }\u003C/script>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"debugging\">Debugging\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#debugging\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Debugging”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"console-logging\">Console Logging\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#console-logging\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Console Logging”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Messages are logged with \u003Ccode dir=\"auto\">[EmbedMessaging]\u003C/code> prefix:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">[EmbedMessaging] Rejected message from: <origin>\u003C/code> - Origin validation failed\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">[EmbedMessaging] Failed to send message: <error>\u003C/code> - PostMessage error\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">[EmbedMessaging] Unknown action: <action>\u003C/code> - Unrecognized action\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"devtools-tips\">DevTools Tips\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#devtools-tips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “DevTools Tips”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Open iframe in separate tab to see its console\u003C/li>\n\u003Cli>Use Network tab to verify iframe loads\u003C/li>\n\u003Cli>Check Application > Frames to inspect iframe origin\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"flow-diagram\">Flow Diagram\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#flow-diagram\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flow Diagram”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────┐ ┌─────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Parent │ │ PWA │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (embedder) │ │ (iframe) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────┘ └─────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ iframe loads │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ◄──────────────────────────────────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ { action: 'ready' } │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ◄──────────────────────────────────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ { action: 'highlight-chart', │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ payload: { chartId: 'boxplot' │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ intensity: 'pulse'}}│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ──────────────────────────────────►│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ { action: 'highlight-applied', │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ payload: { success: true }} │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ◄──────────────────────────────────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ User clicks chart │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ { action: 'chart-clicked', │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ payload: { chartId: 'boxplot'}}│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ◄──────────────────────────────────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────┐ ┌─────────────┐│ Parent │ │ PWA ││ (embedder) │ │ (iframe) │└─────────────┘ └─────────────┘ │ │ │ iframe loads │ │ ◄──────────────────────────────────│ │ │ │ { action: 'ready' } │ │ ◄──────────────────────────────────│ │ │ │ { action: 'highlight-chart', │ │ payload: { chartId: 'boxplot' │ │ intensity: 'pulse'}}│ │ ──────────────────────────────────►│ │ │ │ { action: 'highlight-applied', │ │ payload: { success: true }} │ │ ◄──────────────────────────────────│ │ │ │ User clicks chart │ │ │ │ { action: 'chart-clicked', │ │ payload: { chartId: 'boxplot'}}│ │ ◄──────────────────────────────────│ │ │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-files\">Related Files\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-files\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Files”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">apps/pwa/src/hooks/useEmbedMessaging.ts\u003C/code> - PWA message handler\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">apps/pwa/src/components/Dashboard.tsx\u003C/code> - Highlight prop consumer\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">apps/pwa/src/index.css\u003C/code> - Highlight CSS classes\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"marketing-website-architecture-react-islands\">Marketing Website Architecture (React Islands)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#marketing-website-architecture-react-islands\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Marketing Website Architecture (React Islands)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The VariScout marketing website uses a different architecture that doesn’t require iframe messaging:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>React Islands\u003C/strong>: Chart components render directly on the page using Astro’s \u003Ccode dir=\"auto\">client:only=\"react\"\u003C/code> directive\u003C/li>\n\u003Cli>\u003Cstrong>Data Package\u003C/strong>: Pre-computed sample data from \u003Ccode dir=\"auto\">@variscout/data\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Chart Components\u003C/strong>: Direct imports from \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>See the \u003Ca href=\"../../08-products/website/index.md\">Website product documentation\u003C/a> for the current website architecture.\u003C/p>", + { + "headings": 8933, + "localImagePaths": 8975, + "remoteImagePaths": 8976, + "frontmatter": 8977, + "imagePaths": 8978 + }, + [8934, 8936, 8937, 8938, 8941, 8944, 8947, 8950, 8953, 8956, 8959, 8962, 8965, 8968, 8969, 8972], + { "depth": 30, "slug": 8935, "text": 8923 }, + "pwa-embed-messaging-protocol", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 3083, "text": 3084 }, + { "depth": 33, "slug": 8939, "text": 8940 }, + "message-types", + "Message Types", + { "depth": 79, "slug": 8942, "text": 8943 }, + "parent--pwa-embedmessage", + "Parent → PWA (EmbedMessage)", + { "depth": 79, "slug": 8945, "text": 8946 }, + "pwa--parent-embedresponse", + "PWA → Parent (EmbedResponse)", + { "depth": 33, "slug": 8948, "text": 8949 }, + "chart-ids", + "Chart IDs", + { "depth": 33, "slug": 8951, "text": 8952 }, + "highlight-intensities", + "Highlight Intensities", + { "depth": 33, "slug": 8954, "text": 8955 }, + "pwa-integration-useembedmessaging-hook", + "PWA Integration (useEmbedMessaging hook)", + { "depth": 33, "slug": 8957, "text": 8958 }, + "third-party-integration-example", + "Third-Party Integration Example", + { "depth": 33, "slug": 8960, "text": 8961 }, + "debugging", + "Debugging", + { "depth": 79, "slug": 8963, "text": 8964 }, + "console-logging", + "Console Logging", + { "depth": 79, "slug": 8966, "text": 8967 }, + "devtools-tips", + "DevTools Tips", + { "depth": 33, "slug": 4250, "text": 4251 }, + { "depth": 33, "slug": 8970, "text": 8971 }, + "related-files", + "Related Files", + { "depth": 33, "slug": 8973, "text": 8974 }, + "marketing-website-architecture-react-islands", + "Marketing Website Architecture (React Islands)", + [], + [], + { "title": 8923 }, + [], + "05-technical/implementation/testing", + { "id": 8979, "data": 8981, "body": 8986, "filePath": 8987, "digest": 8988, "rendered": 8989 }, + { + "title": 8982, + "editUrl": 16, + "head": 8983, + "template": 18, + "sidebar": 8984, + "pagefind": 16, + "draft": 20 + }, + "Testing Strategy", + [], + { "hidden": 20, "attrs": 8985 }, + {}, + "# Testing Strategy\n\n**Status:** Active\n**Last Updated:** February 2026\n\n---\n\n## Philosophy\n\nVariScout Lite testing follows these principles:\n\n1. **Test critical paths first** - Statistical accuracy is business-critical\n2. **Behavior over implementation** - Test what the code does, not how it does it\n3. **Local-first** - All tests run locally without CI/CD dependencies\n4. **Agent-Augmented & Chrome-Verified** — Leverage AI agents (\"Antigravity\") and Claude Code Chrome browser integration for complex E2E, visual, and regression testing\n\n---\n\n## Framework\n\n| Tool | Purpose |\n| :---------------------------- | :------------------------------------------------------------- |\n| **Vitest** | Test runner (Vite-native, fast) |\n| **Playwright** | E2E browser testing (Chromium) |\n| **React Testing Library** | Component testing (PWA, Azure) |\n| **@testing-library/jest-dom** | DOM assertions |\n| **Antigravity (Agent)** | Visual verification, E2E flows, manual QA automation |\n| **Claude Code Chrome** | Interactive browser testing, visual checks, protocol execution |\n\n### Running Tests\n\n```bash\n# Run all vitest tests across monorepo\npnpm test\n\n# Run tests in specific package\npnpm --filter @variscout/core test\npnpm --filter @variscout/pwa test\npnpm --filter @variscout/azure-app test\npnpm --filter @variscout/hooks test\npnpm --filter @variscout/charts test\npnpm --filter @variscout/ui test\n\n# Watch mode (during development)\npnpm --filter @variscout/core test -- --watch\n\n# Coverage report\npnpm --filter @variscout/core test -- --coverage\n\n# Chrome Browser Testing\nclaude --chrome # Enable Chrome browser access\n# Then use prompts like: \"Run the staged analysis verification protocol\"\n\n# Playwright E2E (automated regression)\npnpm --filter @variscout/pwa test:e2e\npnpm --filter @variscout/azure-app test:e2e\n```\n\n### Agentic & Chrome Browser Testing\n\n**Antigravity (Agent)** — Issue a prompt to the AI agent for autonomous verification:\n\n> \"Run the smoke test protocol on the PWA\"\n> \"Verify the StatsPanel visualization matches the data\"\n\n**Claude Code Chrome** — Interactive browser testing via Claude Code's native Chrome integration:\n\n**Prerequisites:**\n\n- Claude Code CLI v2.0.73+ with Chrome extension v1.0.36+\n- Enable with `claude --chrome` to launch a visible Chrome window\n\n**Usage examples:**\n\n> \"Open localhost:5173, load the Coffee sample, and verify the I-Chart renders with control limits\"\n> \"Run the staged analysis verification protocol\"\n> \"Switch to the Azure app at localhost:5174 and verify the theme toggle works\"\n\n**When to use each:**\n\n| Method | Best For |\n| :---------- | :-------------------------------------------------------------------- |\n| Antigravity | AI-driven verification, complex multi-step flows, batch QA runs |\n| Chrome | Interactive visual checks, debugging, authenticated session testing |\n| Playwright | Automated CI regression, headless pipelines, deterministic assertions |\n\n---\n\n## Test Ownership by Package\n\n| Package | Test Type | What to Test |\n| :--------------------- | :----------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `@variscout/core` | **Unit** | Statistics (calculateStats, calculateAnova, calculateRegression), parser, license validation, export utilities |\n| `@variscout/charts` | **Unit** | Color constants, accessibility utilities, multi-selection hook |\n| `@variscout/hooks` | **Unit** | Hooks (useTier, useChartScale, useColumnClassification, useDrillPath, useMindmapState, useVariationTracking, useDataTablePagination, useHighlightFade, useResizablePanel, useAnnotationMode, useBoxplotData, useChartCopy, useControlViolations, useDataIngestion, useDataState, useFilterNavigation, useFocusedChartNav, useIChartData, useKeyboardNavigation, useResponsiveChartMargins, useThemeState), pipeline integration, filter state transitions, stress tests |\n| `@variscout/ui` | **Unit** | UpgradePrompt, HelpTooltip, DataQualityBanner, ColumnMapping, BoxplotDisplayToggle, DataTableBase |\n| `@variscout/pwa` | **Component** | UI components (StatsPanel, Dashboard, DataTableModal, AnovaResults, MindmapPanel, WhatIfPage, WhatIfSimulator), hooks (useFilterNavigation), export utilities |\n| `@variscout/pwa` | **Playwright E2E** | Critical workflow, drill-down, samples, analysis views, stats/ANOVA |\n| `@variscout/azure-app` | **Component** | UI components (Dashboard, StatsPanel, AnovaResults, MindmapWindow, WhatIfPage, FilterBreadcrumb, Editor, SettingsPanel), auth (easyAuth), storage |\n| `@variscout/azure-app` | **Playwright E2E** | Editor workflow, samples, analysis views, stats/ANOVA |\n\n---\n\n## Priority Tiers\n\n| Priority | Category | Rationale |\n| :------- | :---------------- | :----------------------------------------------------------------- |\n| **P0** | Statistics engine | Business-critical accuracy - wrong Cpk could lead to bad decisions |\n| **P1** | Data persistence | User data integrity - losing projects is unacceptable |\n| **P2** | Export/Import | Data portability - .vrs files must work reliably |\n| **P3** | UI & Visuals | **Agent/Chrome-verified** visuals and interactions |\n\n---\n\n## Reference Validation (NIST StRD + R)\n\nVariScout's statistics engine is validated against **NIST Statistical Reference Datasets** (StRD) and **R statistical software** reference values. This provides independent, externally certified ground truth for statistical accuracy.\n\n### Why NIST StRD?\n\nThe National Institute of Standards and Technology publishes datasets with certified statistical values computed to 15+ significant digits. Software that produces correct results on these datasets is unlikely to have systematic numerical errors. Several datasets are specifically designed to expose flaws in naive algorithms (e.g., catastrophic cancellation in variance computation).\n\n### Datasets Used\n\n| Dataset | NIST Category | What It Validates | Difficulty |\n| :------ | :---------------- | :------------------------------------------------------------------- | :--------- |\n| NumAcc1 | Univariate | `calculateStats` mean/stdDev with large offset | Lower |\n| NumAcc4 | Univariate | `calculateStats` mean/stdDev — catastrophic cancellation stress test | Higher |\n| SiRstv | ANOVA | `calculateAnova` F-statistic, eta-squared, residual SD, p-value | Average |\n| Norris | Linear Regression | `calculateRegression` slope, intercept, R² | Lower |\n| Pontius | Linear Regression | `calculateRegression` quadratic R² with large x values | Average |\n\n### Indirect Validation Strategy\n\nPrivate helper functions (`normalPDF`, `incompleteBeta`, `lnGamma`, `fDistributionPValue`, `tDistributionPValue`) are not exported and cannot be tested directly. They are validated **indirectly** through end-to-end chains:\n\n- **F-distribution chain:** ANOVA p-value = `fDistributionPValue(F, df1, df2)` → `incompleteBeta()` → `lnGamma()`. If the SiRstv p-value matches R's `pf()` output, the entire chain is correct.\n- **t-distribution chain:** Regression p-value = `tDistributionPValue(t, df)` → `fDistributionPValue()` → `incompleteBeta()`. If the Norris slope p-value is \u003C 1e-10 (matching R), the chain is correct.\n- **Normal quantile:** `normalQuantile()` is validated against R's `qnorm()` at 11 standard percentile points to 8 decimal places.\n\n### Achieved Tolerances\n\n| Section | Function | Tolerance | Notes |\n| :-------------- | :----------------------------------------- | :------------------ | :---------------------------------- |\n| Normal quantile | `normalQuantile` vs R `qnorm()` | 8 decimal places | Acklam's algorithm |\n| NumAcc1 | `calculateStats` mean, stdDev | 9 decimal places | Well-conditioned |\n| NumAcc4 | `calculateStats` mean | 7 decimal places | d3.mean loses ~2 digits at 10^7 |\n| NumAcc4 | `calculateStats` stdDev | 8 decimal places | Welford's algorithm in d3.deviation |\n| SiRstv | `calculateAnova` F, eta², residual SD | 6 decimal places | Standard conditioning |\n| Norris | `calculateRegression` slope, intercept, R² | 10 decimal places | Well-conditioned OLS |\n| Pontius | `calculateRegression` quadratic R² | 6 decimal places | Large x values (up to 3×10^6) |\n| Boxplot | `calculateBoxplotStats` Q1, median, Q3 | 10 decimal places | R type=7 linear interpolation |\n| Matrix | `inverse`, `multiply`, `solve` | 6–10 decimal places | Depends on condition number |\n\n### Cross-Validation with Minitab\n\nCSV reference data files are available in `packages/core/reference-data/` for independent verification in Minitab or any statistics package. See the `packages/core/reference-data/README.md` in that directory for certified values and step-by-step Minitab instructions.\n\n---\n\n## Current Coverage\n\n**Total: 90 vitest files, 1,475 test cases + 19 Playwright E2E spec files**\n\n### @variscout/core (26 files, 739 test cases)\n\n| Function/Module | Tested | Cases |\n| :-------------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------ |\n| `calculateStats()` | ✅ | Basic stats, Cp/Cpk, one-sided specs, empty data, sigma within (MR/d2) |\n| `calculateAnova()` | ✅ | Significant/non-significant, group stats, eta-squared |\n| `calculateRegression()` | ✅ | Linear, quadratic, weak relationships, optimum detection, column selection |\n| `calculateMultipleRegression()` | ✅ | GLM, categorical predictors, interaction terms, model reduction |\n| `getNelsonRule2ViolationPoints()` | ✅ | Run detection, edge cases (8 vs 9 points), mean breaks run, staged mode |\n| Reference validation (NIST/R) | ✅ | normalQuantile, mean/stdDev, ANOVA F, regression coefficients, boxplot quantiles, matrix ops, KDE, probability plot |\n| Golden data tests | ✅ | Static CSV cases (coffee, packaging, avocado) with known expected values |\n| `tier.ts` | ✅ | Tier configuration, channel limits, validation |\n| `parser.ts` | ✅ | CSV/Excel parsing, auto-mapping, validation, data types |\n| `export.ts` | ✅ | CSV generation, special characters, escaping |\n| `performance.ts` | ✅ | Multi-channel analysis, performance metrics |\n\n### @variscout/charts (4 files, 59 test cases)\n\n| Module | Tested | Focus |\n| :------------------ | :----- | :------------------------------------------- |\n| `colors.ts` | ✅ | Chart color constants, theme color functions |\n| `accessibility.ts` | ✅ | Accessible color generation, contrast ratios |\n| `useMultiSelection` | ✅ | Multi-selection hook for Performance charts |\n\n### @variscout/hooks (29 files, 317 test cases)\n\n| Hook/Module | Tested | Focus |\n| :------------------------------- | :----- | :----------------------------------------------------------- |\n| `useAnnotationMode` | ✅ | Chart annotation state, highlights, text notes, context menu |\n| `useBoxplotData` | ✅ | Shared d3 boxplot computation (quartiles, outliers) |\n| `useChartCopy` | ✅ | Chart copy-to-clipboard, PNG/SVG download, style restore |\n| `useChartScale` | ✅ | Y-axis scale calculation, locked vs dynamic ranges |\n| `useColumnClassification` | ✅ | Numeric vs categorical column detection, threshold tuning |\n| `useControlViolations` | ✅ | Control/spec violation computation, violation counts |\n| `useDataIngestion` | ✅ | File upload, data parsing, sample loading |\n| `useDataState` | ✅ | Shared DataContext state management, display options |\n| `useDataTablePagination` | ✅ | Page state, row slicing, boundary conditions |\n| `useDrillPath` | ✅ | DrillStep computation from filterStack, node contributions |\n| `useFilterNavigation` | ✅ | Multi-select, updateFilterValues, removeFilter, breadcrumbs |\n| `useFocusedChartNav` | ✅ | Focused chart keyboard navigation, chart order |\n| `useHighlightFade` | ✅ | Highlight timeout, fade animation state |\n| `useIChartData` | ✅ | Shared I-Chart data transform (control limits, points) |\n| `useKeyboardNavigation` | ✅ | Arrow key navigation, focus management |\n| `useBoxplotWrapperData` | ✅ | Shared boxplot wrapper data prep (quartiles, groups) |\n| `useIChartWrapperData` | ✅ | Shared I-Chart wrapper data prep (points, limits) |\n| `useParetoChartData` | ✅ | Shared Pareto chart data prep (rankings, Cpk) |\n| `useDashboardComputedData` | ✅ | Shared dashboard computed stats and chart data |\n| `useResizablePanel` | ✅ | Panel size state, drag interaction, constraints |\n| `useResponsiveChartMargins` | ✅ | Dynamic chart margins based on container width |\n| `useThemeState` | ✅ | Theme state (light/dark/system), themingEnabled parameter |\n| `useTier` | ✅ | Tier info, channel validation, warning messages |\n| `useVariationTracking` | ✅ | Cumulative eta-squared, filter chip data with contribution % |\n| `filterStateTransitions` | ✅ | Filter add/remove/clear state machine transitions |\n| `stress` | ✅ | Performance/stress tests for hooks under load |\n| `index.ts` (exports) | ✅ | All public exports resolve correctly |\n| Integration: filterStatsPipeline | ✅ | End-to-end: CSV parse → filter → stats → ANOVA pipeline |\n\n### @variscout/ui (10 files, 136 test cases)\n\n| Component | Tested | Focus |\n| :--------------------- | :----- | :-------------------------------------------------------------------------------------------------------------- |\n| `UpgradePrompt` | ✅ | Variants (inline/banner/card), tier messaging |\n| `HelpTooltip` | ✅ | Tooltip rendering, glossary term display, icons |\n| `DataQualityBanner` | ✅ | Validation summary, warning/error states |\n| `ColumnMapping` | ✅ | maxFactors enforcement, spec entry, column selection |\n| `BoxplotDisplayToggle` | ✅ | Violin mode toggle, contribution label toggle, sort criterion selection, sort direction toggle, popover |\n| `DataTableBase` | ✅ | Inline cell editing, multi-cell paste, arrow-key navigation, row status indicators, spec violation highlighting |\n\n### @variscout/pwa (10 vitest files, 100 test cases)\n\n| Component/Module | Tested | Focus |\n| :-------------------- | :----- | :------------------------------------------------- |\n| `StatsPanel` | ✅ | Conditional display, Cp/Cpk formatting, tabs |\n| `Dashboard` | ✅ | View switching, chart rendering, ANOVA integration |\n| `DataTableModal` | ✅ | Cell editing, row operations, paste handling |\n| `AnovaResults` | ✅ | Null state, F-stat display, p-value format |\n| `MindmapPanel` | ✅ | Panel open/close, backdrop, slide-in animation |\n| `WhatIfPage` | ✅ | Simulator rendering, navigation, spec limits |\n| `WhatIfSimulator` | ✅ | Slider interaction, predicted values, reset |\n| `PasteScreen` | ✅ | Paste input, parseText integration, column mapping |\n| `useFilterNavigation` | ✅ | Multi-select, updateFilterValues, removeFilter |\n| `export.ts` | ✅ | CSV generation, special characters |\n\n### @variscout/azure-app (15 vitest files, 171 test cases)\n\n| Component/Module | Tested | Focus |\n| :---------------------- | :----- | :----------------------------------------------------------------------------- |\n| `AnovaResults` | ✅ | Null state, F-stat display, p-value format |\n| `Dashboard` | ✅ | Tab switching (Analysis/Performance), stats |\n| `StatsPanel` | ✅ | Conditional display, Cp/Cpk, sigma within |\n| `MindmapWindow` | ✅ | Window rendering, popout behavior, localStorage sync |\n| `WhatIfPage` | ✅ | Simulator integration, navigation, predictions |\n| `FilterBreadcrumb` | ✅ | Chip rendering, remove button, contribution % |\n| `Editor` | ✅ | Empty state, sample loading, navigation |\n| `SettingsPanel` | ✅ | Theme toggle, display options, panel open/close |\n| ColumnMapping (re-edit) | ✅ | Factor add/remove via ColumnMapping mode='edit', safe cancel |\n| `PasteScreen` | ✅ | Paste input, parseText integration, column mapping |\n| `easyAuth` | ✅ | Mock user on localhost, AuthError codes, proactive token refresh, login/logout |\n| `storage` | ✅ | Offline-first storage, IndexedDB operations |\n| `PresentationView` | ✅ | Full-screen chart grid, focused chart navigation |\n| `SyncToast` | ✅ | Toast notifications, auto-dismiss, action buttons |\n\n---\n\n## Playwright E2E Coverage\n\n### PWA (10 spec files)\n\n| Spec File | Tests |\n| :------------------------------------ | :---------------------------------------------------------------- |\n| `critical-workflow.spec.ts` | App load, home screen, sample load, stats display, SVG rendering |\n| `drill-down.spec.ts` | Boxplot click → filter chip, stats update, chip remove, clear all |\n| `samples.spec.ts` | All sample datasets load, chart rendering, expected stats values |\n| `analysis-views.spec.ts` | Dashboard view switching via Settings, SVG rendering |\n| `stats-anova.spec.ts` | Cp/Cpk display, mean/sigma/samples, ANOVA F-stat/p-value/eta² |\n| `user-flows.spec.ts` | End-to-end user journeys, navigation flows, multi-step workflows |\n| `edge-cases.spec.ts` | Boundary conditions, empty states, error handling, edge scenarios |\n| `bottleneck-investigation.spec.ts` | Bottleneck case study drill-down investigation |\n| `hospital-ward-investigation.spec.ts` | Hospital ward case study investigation |\n| `mindmap-evaluation.spec.ts` | Mindmap panel rendering and interaction |\n\n```bash\n# Run PWA E2E tests\npnpm --filter @variscout/pwa test:e2e\n```\n\n### Azure App (9 spec files)\n\n| Spec File | Tests |\n| :------------------------- | :----------------------------------------------------------------- |\n| `editor-workflow.spec.ts` | Auth, empty state, sample load, chart rendering, filter drill-down |\n| `samples.spec.ts` | Sample dataset loading, chart rendering, expected values |\n| `analysis-views.spec.ts` | Analysis view switching, SVG rendering |\n| `stats-anova.spec.ts` | Mean/sigma/samples display, ANOVA F-stat/p-value/eta² |\n| `user-flows.spec.ts` | End-to-end user journeys, editor navigation, multi-step workflows |\n| `edge-cases.spec.ts` | Boundary conditions, empty states, error handling, edge scenarios |\n| `editor-features.spec.ts` | CSV export, data panel, save, What-If, mindmap toggle |\n| `performance-mode.spec.ts` | Performance tab, Cp/Cpk toggle, spec limits, channel count |\n| `settings-theme.spec.ts` | Settings panel, light/dark theme, accent colors, chart text size |\n\n```bash\n# Run Azure E2E tests\npnpm --filter @variscout/azure-app test:e2e\n```\n\n### Azure E2E Patterns\n\nAzure E2E tests share a helper module at `apps/azure/e2e/helpers.ts` with three exported functions:\n\n| Function | Purpose |\n| :---------------------- | :---------------------------------------------------------------------- |\n| `confirmColumnMapping` | Click \"Start Analysis\" on the ColumnMapping screen |\n| `loadSampleInEditor` | Navigate to editor, load first sample, confirm mapping, wait for charts |\n| `loadPerformanceSample` | Load the large-scale performance sample and confirm mapping |\n\n**Key patterns for Azure E2E tests:**\n\n- **ColumnMapping flow:** Every sample load, paste, or file upload triggers the \"Map Your Data\" ColumnMapping screen. Tests must call `confirmColumnMapping(page)` (or use `loadSampleInEditor`) to click \"Start Analysis\" before asserting on charts.\n- **Clean state between samples:** Use `page.goto('/')` between sequential sample loads to reset persisted IndexedDB state. Without this, the second sample load may skip the empty-state editor.\n- **ANOVA location:** ANOVA results are only visible in the FocusedChartView (boxplot focused view). Tests must maximize the boxplot card first (click the expand button on `[data-testid=\"chart-boxplot\"]`).\n- **Paste vs Manual Entry:** \"Paste Data\" button opens a textarea for pasting tabular text. \"Manual Entry\" opens the setup form for creating columns and entering values row by row.\n\n---\n\n## Playwright vs Agentic/Chrome Testing\n\nVariScout uses three complementary E2E verification methods:\n\n| Aspect | Antigravity (Agent) | Claude Code Chrome | Playwright |\n| :---------------- | :--------------------------------- | :------------------------------------ | :---------------------------------- |\n| **Execution** | AI-driven, autonomous | Interactive, human-guided | Automated, headless |\n| **Best for** | Complex multi-step flows, batch QA | Visual debugging, authenticated flows | CI regression, deterministic checks |\n| **Speed** | Medium (AI reasoning overhead) | Slow (interactive) | Fast (scripted) |\n| **Flakiness** | Low (adaptive) | None (human-observed) | Medium (timing-sensitive) |\n| **CI/CD** | No | No | Yes |\n| **Visual checks** | Yes (screenshot analysis) | Yes (live observation) | Limited (snapshot comparison) |\n\n**Why three methods coexist:**\n\n- **Playwright** catches regressions automatically in CI — deterministic, fast, scriptable\n- **Antigravity** handles complex verification that's hard to script — AI adapts to UI changes\n- **Chrome** enables interactive debugging and visual spot-checks during development\n\n**When they disagree:** Playwright is the source of truth for CI gates. If Antigravity or Chrome finds an issue Playwright misses, add a Playwright test to cover it.\n\n---\n\n## Testing Patterns\n\n### Float Comparisons (Statistics)\n\n```typescript\n// Use toBeCloseTo for floating-point math\nexpect(stats.mean).toBeCloseTo(11.2, 1); // 1 decimal precision\nexpect(stats.cpk).toBeCloseTo(0.33, 2); // 2 decimal precision\n\n// NIST-grade: 10 decimal places for well-conditioned OLS\nexpect(result.linear.slope).toBeCloseTo(1.00211681802045, 10);\n// Stress test: 7-8 decimal places for large-offset data\nexpect(stats.mean).toBeCloseTo(10000000.2, 7);\n```\n\n### Component Testing with Context\n\n```typescript\nimport { vi } from 'vitest';\nimport * as DataContextModule from '../context/DataContext';\n\nbeforeEach(() => {\n vi.restoreAllMocks();\n});\n\nit('displays Cpk when showCpk is true', () => {\n vi.spyOn(DataContextModule, 'useData').mockReturnValue({\n displayOptions: { showCpk: true },\n // ... other context values\n });\n\n render(\u003CStatsPanel stats={mockStats} />);\n expect(screen.getByText('Cpk')).toBeInTheDocument();\n});\n```\n\n### Mocking External Libraries\n\n```typescript\n// Mock libraries with CSS/DOM issues\nvi.mock('react-resizable-panels', () => ({\n Group: ({ children }) => \u003Cdiv data-testid=\"panel-group\">{children}\u003C/div>,\n Panel: ({ children }) => \u003Cdiv data-testid=\"panel\">{children}\u003C/div>,\n}));\n\n// Mock child components to isolate tests\nvi.mock('../charts/IChart', () => ({\n default: () => \u003Cdiv data-testid=\"i-chart\">Mock\u003C/div>,\n}));\n```\n\n### Common Pitfalls\n\n**Mock ordering (OOM prevention):** When mocking dependencies of imported components, place `vi.mock()` calls **before** the component import. This ensures stable mock references and prevents infinite re-render loops in `useEffect` dependency arrays.\n\n```typescript\n// ✅ Correct: mock BEFORE import\nvi.mock('../context/DataContext', () => ({\n useData: vi.fn(() => mockDataValue),\n}));\n\nimport { SettingsPanel } from '../components/SettingsPanel';\n\n// ❌ Wrong: import before mock — can cause OOM (infinite re-renders)\nimport { SettingsPanel } from '../components/SettingsPanel';\n\nvi.mock('../context/DataContext', () => ({\n useData: vi.fn(() => mockDataValue),\n}));\n```\n\nThis pattern was identified fixing the Azure `SettingsPanel` test (165s OOM → 1s).\n\n### Verification Pattern\n\nWhen asking the agent (or using Chrome) to verify a feature:\n\n1. **State the Goal**: \"Verify the new Pareto Chart rendering.\"\n2. **Define Success**: \"It should show bars sorted by frequency and a cumulative line.\"\n3. **Provide Context**: \"Open the PWA, load the sample data, and navigate to the Dashboard.\"\n\n---\n\n## Test File Organization\n\n```\npackages/core/\n├── reference-data/ # NIST StRD CSV files for Minitab cross-validation\n│ ├── README.md\n│ ├── nist-numacc1.csv\n│ ├── nist-numacc4.csv\n│ ├── nist-sirstv.csv\n│ ├── nist-norris.csv\n│ └── nist-pontius.csv\n├── src/\n│ ├── stats.ts\n│ ├── parser.ts\n│ ├── performance.ts\n│ └── __tests__/\n│ ├── stats.test.ts # Core statistics engine\n│ ├── regression.test.ts # Simple regression\n│ ├── multiRegression.test.ts # GLM / multiple regression\n│ ├── modelReduction.test.ts # Term removal suggestions\n│ ├── reference-validation.test.ts # NIST StRD + R reference values\n│ ├── goldenData.test.ts # Static CSV golden data tests\n│ ├── performance.test.ts # Multi-channel performance\n│ ├── projectedStats.test.ts # Projected what-if stats\n│ ├── directAdjustment.test.ts # Direct adjustment calculations\n│ ├── simulation.test.ts # Model-driven simulation\n│ ├── nelson.test.ts # Nelson rules violation detection\n│ ├── categoryStats.test.ts # Category-level statistics\n│ ├── sortBoxplotData.test.ts # Boxplot sorting by mean/spread/name\n│ ├── parser.test.ts # CSV/Excel parsing\n│ ├── stressParser.test.ts # Parser stress/performance tests\n│ ├── export.test.ts # CSV export\n│ ├── navigation.test.ts # Navigation utilities\n│ ├── variation.test.ts # Variation tracking\n│ ├── tier.test.ts # Tier configuration\n│ ├── time.test.ts # Time utilities\n│ ├── edgeCases.test.ts # Edge case handling\n│ ├── stress.test.ts # Performance stress tests\n│ └── urlParams.test.ts # URL parameter parsing\n\npackages/charts/\n└── src/\n ├── __tests__/\n │ └── colors.test.ts # Chart color constants\n ├── hooks/__tests__/\n │ └── useMultiSelection.test.ts # Multi-selection hook\n └── utils/__tests__/\n └── accessibility.test.ts # Accessible color generation\n\npackages/hooks/\n└── src/\n └── __tests__/\n ├── index.test.ts # Export verification\n ├── useAnnotationMode.test.ts # Chart annotation state\n ├── useBoxplotData.test.ts # Shared boxplot computation\n ├── useChartCopy.test.ts # Chart copy/export\n ├── useChartScale.test.ts # Y-axis scale\n ├── useColumnClassification.test.ts # Column type detection\n ├── useControlViolations.test.ts # Control/spec violations\n ├── useDataIngestion.test.ts # File upload, data parsing\n ├── useDataState.test.ts # DataContext state management\n ├── useDataTablePagination.test.ts # Pagination state\n ├── useDrillPath.test.ts # Drill path computation\n ├── useFilterNavigation.test.ts # Filter navigation, multi-select\n ├── useFocusedChartNav.test.ts # Focused chart keyboard nav\n ├── useHighlightFade.test.ts # Highlight fade animation\n ├── useIChartData.test.ts # Shared I-Chart data transform\n ├── useKeyboardNavigation.test.ts # Arrow key navigation\n ├── useBoxplotWrapperData.test.ts # Boxplot wrapper data prep\n ├── useIChartWrapperData.test.ts # I-Chart wrapper data prep\n ├── useParetoChartData.test.ts # Pareto chart data prep\n ├── useDashboardComputedData.test.ts # Dashboard computed data\n ├── useResizablePanel.test.ts # Resizable panel state\n ├── useResponsiveChartMargins.test.ts # Dynamic chart margins\n ├── useThemeState.test.ts # Theme state management\n ├── useTier.test.ts # Tier hook\n ├── useVariationTracking.test.ts # Cumulative eta-squared\n ├── filterStateTransitions.test.ts # Filter state machine\n ├── stress.test.ts # Performance stress tests\n └── integration/\n └── filterStatsPipeline.test.ts # End-to-end pipeline\n\npackages/ui/\n└── src/components/\n ├── UpgradePrompt/__tests__/\n │ └── UpgradePrompt.test.tsx\n ├── HelpTooltip/__tests__/\n │ └── HelpTooltip.test.tsx\n ├── DataQualityBanner/__tests__/\n │ └── DataQualityBanner.test.tsx\n ├── ColumnMapping/__tests__/\n │ └── ColumnMapping.test.tsx\n ├── BoxplotDisplayToggle/__tests__/\n │ └── BoxplotDisplayToggle.test.tsx\n └── DataTable/__tests__/\n └── DataTableBase.test.tsx\n\napps/pwa/\n├── e2e/ # Playwright E2E tests\n│ ├── critical-workflow.spec.ts\n│ ├── drill-down.spec.ts\n│ ├── samples.spec.ts\n│ ├── analysis-views.spec.ts\n│ ├── stats-anova.spec.ts\n│ ├── user-flows.spec.ts\n│ └── edge-cases.spec.ts\n├── src/\n│ ├── components/__tests__/\n│ │ ├── StatsPanel.test.tsx\n│ │ ├── Dashboard.test.tsx\n│ │ ├── AnovaResults.test.tsx\n│ │ ├── MindmapPanel.test.tsx\n│ │ ├── WhatIfPage.test.tsx\n│ │ ├── WhatIfSimulator.test.tsx\n│ │ ├── DataTableModal.test.tsx\n│ │ └── PasteScreen.test.tsx\n│ ├── hooks/__tests__/\n│ │ └── useFilterNavigation.test.tsx\n│ └── lib/__tests__/\n│ └── export.test.ts\n\napps/azure/\n├── e2e/ # Playwright E2E tests\n│ ├── editor-workflow.spec.ts\n│ ├── samples.spec.ts\n│ ├── analysis-views.spec.ts\n│ ├── stats-anova.spec.ts\n│ ├── user-flows.spec.ts\n│ └── edge-cases.spec.ts\n├── vitest.config.ts # Excludes e2e/** and api/**\n├── src/\n│ ├── setupTests.ts\n│ ├── auth/__tests__/\n│ │ └── easyAuth.test.ts\n│ ├── services/__tests__/\n│ │ └── storage.test.ts\n│ ├── components/__tests__/\n│ │ ├── AnovaResults.test.tsx\n│ │ ├── Dashboard.test.tsx\n│ │ ├── StatsPanel.test.tsx\n│ │ ├── MindmapWindow.test.tsx\n│ │ ├── WhatIfPage.test.tsx\n│ │ ├── FilterBreadcrumb.test.tsx\n│ │ ├── (removed: FactorManagerPopover — replaced by ColumnMapping re-edit)\n│ │ ├── PasteScreen.test.tsx\n│ │ ├── PresentationView.test.tsx\n│ │ └── SyncToast.test.tsx\n│ ├── components/settings/__tests__/\n│ │ └── SettingsPanel.test.tsx\n│ └── pages/__tests__/\n│ └── Editor.test.tsx\n```\n\n---\n\n## Feature Verification Protocols\n\nSpecific prompts for verifying complex features. These protocols can be executed via Antigravity agents or interactively with `claude --chrome`.\n\n### 1. Staged Analysis Verification\n\n**Goal:** Verify the Staged I-Chart correctly calculates and displays separate control limits for each phase.\n\n**Agent Prompt:**\n\n> \"Load the 'Process Changes' sample (or any dataset with a categorical column). In the Dashboard header, select the categorical column (e.g., 'Phase' or 'Machine') in the 'Stage' dropdown. Verify that the I-Chart updates to show vertical dashed dividers between stages, and that the UCL, Mean, and LCL lines change values at each stage boundary. Confirm that points are colored according to their specific stage's limits.\"\n\n**Success Criteria:**\n\n- [ ] Vertical dashed lines separate stages\n- [ ] Control limit steps (changes in level) at boundaries\n- [ ] Stage labels visible at top of chart\n\n### 2. PWA Embed Mode Verification\n\n**Goal:** Verify the PWA renders correctly when embedded (hidden chrome, message listening).\n\n**Agent Prompt:**\n\n> \"Open the PWA with the URL parameters `?embed=true&sample=coffee`. Verify that the application header (navigation) and footer are completely hidden. Check that the chart area maximizes to fill the viewport. Verify that clicking the chart still works (though it might not trigger internal navigation if in pure embed mode).\"\n\n**Success Criteria:**\n\n- [ ] No header/toolbar visible\n- [ ] No footer visible\n- [ ] Charts render full-width/height\n- [ ] No console errors related to missing context\n\n### 3. Performance Module Verification\n\n**Goal:** Verify the Multi-Channel Performance Dashboard loads and displays all relevant charts.\n\n**Agent Prompt:**\n\n> \"Load a dataset with multiple numeric columns (e.g., 'Coffee Moisture'). Ensure at least 3 numeric columns are selected for analysis in the setup panel (or via 'New Analysis' -> 'Performance Analysis'). Verify that the Dashboard displays the Performance View, containing a Summary Bar, an I-Chart with multiple series (or selectable series), a Boxplot comparing channels, and a Pareto chart ranking them. Click on a specific channel in the Boxplot and verify the other charts update to focus on that channel.\"\n\n**Success Criteria:**\n\n- [ ] Performance Dashboard layout (Summary + 3-chart grid)\n- [ ] I-Chart showing Cpk/Cp values\n- [ ] Boxplot showing distribution comparison\n- [ ] Pareto showing ranking\n- [ ] Interactive cross-filtering between charts\n\n### 4. Capability Chart Verification\n\n**Goal:** Verify the capability histogram renders correctly with spec limit indicators.\n\n**Agent Prompt:**\n\n> \"Load the 'Packaging' sample (it has spec limits defined). Navigate to the Stats panel and look for the histogram/capability view. Verify that the histogram shows the data distribution, spec limit lines (USL/LSL) are drawn as vertical markers, bars are colored green (in-spec) vs red (out-of-spec), and Cp/Cpk values are displayed numerically.\"\n\n**Success Criteria:**\n\n- [ ] Histogram renders with data distribution bars\n- [ ] Spec limit lines visible (USL and/or LSL)\n- [ ] Pass/fail coloring on histogram bars\n- [ ] Cp and Cpk values displayed\n\n### 5. ANOVA Results Verification\n\n**Goal:** Verify ANOVA results display correctly below boxplot with all statistical values.\n\n**Agent Prompt:**\n\n> \"Load the 'Coffee Moisture' sample. Scroll to the boxplot chart area. Below the boxplot, verify the ANOVA results section appears. Check that it shows the factor name (e.g., 'Drying_Bed'), the F-statistic and p-value on the significance line, and the eta-squared (η²) value. Verify the p-value formats correctly (e.g., '\u003C 0.001' for very small values). Check that group means and sample sizes (n=) are listed for each category.\"\n\n**Success Criteria:**\n\n- [ ] ANOVA section visible below boxplot (`data-testid=\"anova-results\"`)\n- [ ] F-statistic displayed with 2 decimal places\n- [ ] p-value displayed (formatted, e.g., `\u003C 0.001`)\n- [ ] Eta-squared (η²) shown with percentage\n- [ ] Factor name mentioned in header\n- [ ] Group means and n= values listed\n\n### 6. Multi-Level Drill-Down Verification\n\n**Goal:** Verify drilling through 2+ filter levels with cumulative filter chips and stats updates.\n\n**Agent Prompt:**\n\n> \"Load a sample with multiple categorical columns (e.g., 'Bottleneck' or 'Oven Zones'). Click a boxplot category to apply the first filter — verify a filter chip appears and stats update. Then click another category in the boxplot at the second level — verify a second filter chip appears alongside the first. Confirm that cumulative contribution percentages update. Click 'Clear All' and verify all filters are removed and stats revert to the original values.\"\n\n**Success Criteria:**\n\n- [ ] First filter chip appears after boxplot click\n- [ ] Stats (mean, sigma) update to reflect filtered subset\n- [ ] Second filter chip appears at second drill level\n- [ ] Both chips visible simultaneously\n- [ ] Cumulative contribution % updates\n- [ ] Clear All removes all chips and reverts stats\n\n### 7. Manual Data Entry Verification\n\n**Goal:** Verify the manual data entry workflow from setup to analysis.\n\n**Agent Prompt:**\n\n> \"Click 'Manual Entry' on the home screen (or 'Paste from Excel' for the PWA). In the setup modal, enter a column name and configure measurement type. Verify the data entry grid appears. Type values into cells, press Enter/Tab to navigate. After entering 10+ values, click 'Analyze' and verify the dashboard renders with charts based on the entered data. Test paste mode by pasting a column of numbers from clipboard.\"\n\n**Success Criteria:**\n\n- [ ] Setup modal renders with column name input\n- [ ] Data grid appears after setup\n- [ ] Cell editing works (type, Enter, Tab navigation)\n- [ ] 'Analyze' button triggers dashboard rendering\n- [ ] Pasting multi-line data populates grid\n\n### 8. What-If Simulation Verification\n\n**Goal:** Verify the What-If Simulator sliders, predicted values, and real-time updates.\n\n**Agent Prompt:**\n\n> \"Load a sample dataset, then open Settings and select 'What-If Simulator'. Verify that the simulator page renders with sliders for each predictor variable. Move a slider and verify the predicted outcome value updates in real-time. If spec limits exist, verify the predicted value is colored according to pass/fail status. Click 'Reset' and verify all sliders return to their default positions.\"\n\n**Success Criteria:**\n\n- [ ] Simulator page renders with predictor sliders\n- [ ] Predicted outcome value shown\n- [ ] Moving slider updates prediction in real-time\n- [ ] Spec limit pass/fail coloring on predicted value (if applicable)\n- [ ] Reset returns sliders to defaults\n\n### 9. Mindmap Panel Verification\n\n**Goal:** Verify the Investigation Mindmap renders with correct structure and interaction.\n\n**Agent Prompt:**\n\n> \"Load a sample with multiple categorical columns. Apply a drill-down filter by clicking a boxplot category. Open the Mindmap panel (look for a tree/mindmap icon). Verify that a radial tree renders with the root node (outcome variable) at center and child nodes for each factor. Check that nodes show eta-squared (η²) labels. Verify the drill trail highlights the path taken. Check the progress bar at the bottom. If available, test the 'Open in new window' popout button.\"\n\n**Success Criteria:**\n\n- [ ] Radial tree SVG renders with nodes\n- [ ] Root node at center shows outcome variable name\n- [ ] Child nodes labeled with factor names\n- [ ] Eta-squared (η²) values on nodes\n- [ ] Drill trail highlighted for active path\n- [ ] Progress bar visible\n\n### 10. Theme Switching (Azure) Verification\n\n**Goal:** Verify light/dark/system theme switching with chart color updates and persistence.\n\n**Agent Prompt:**\n\n> \"In the Azure app, click the Settings gear icon. Find the theme toggle and switch from Dark to Light mode. Verify that the entire UI updates: backgrounds become light, text becomes dark, and chart chrome (axes, grid lines, labels) changes to light-theme colors. Switch to System mode and verify it follows the OS preference. Close and reopen the app — verify the theme persists.\"\n\n**Success Criteria:**\n\n- [ ] Theme toggle visible in Settings\n- [ ] Light mode: white/light backgrounds, dark text\n- [ ] Dark mode: dark backgrounds, light text\n- [ ] Chart colors update (grid lines, axis labels, tooltip backgrounds)\n- [ ] System mode follows OS preference\n- [ ] Theme persists across page reload\n\n---\n\n## QA Verification Checklist\n\nAssign the following tasks to an Antigravity agent or execute interactively via `claude --chrome` for release verification:\n\n### PWA\n\n- [ ] **Smoke Test**: Launch PWA, ensuring it loads without console errors.\n- [ ] **Data Flow**: Load sample data, edit a cell, verify stats update.\n- [ ] **Staged Analysis**: Enable staging on a sample dataset, verify control limit split.\n- [ ] **Performance Analysis**: Enable multi-channel analysis, verify I-Chart/Boxplot/Pareto grid.\n- [ ] **Embed Mode**: Load `?embed=true`, verify UI chrome is removed.\n- [ ] **Visual Check**: Take screenshots of I-Charts and generic charts; check for layout shifts.\n- [ ] **Persistence**: Reload page, ensure data remains.\n- [ ] **Export**: Generate a PDF/CSV and verify file existence (if environment permits).\n\n### Azure Team App\n\n- [ ] **Auth Flow**: Verify EasyAuth login/logout works correctly.\n- [ ] **Tab Navigation**: Switch between Analysis and Performance tabs.\n- [ ] **Chart Rendering**: Verify I-Chart, Boxplot, Pareto, and ScatterPlot charts render.\n- [ ] **ANOVA Integration**: Confirm ANOVA results display below Boxplot.\n- [ ] **Sync Status**: Verify offline/online sync indicator updates.\n\n---\n\n## Related Documentation\n\n- `.claude/rules/testing.md` - Quick reference testing rules (in project root)\n- [Technical Overview](../index.md) - Technical section index", + "src/content/docs/05-technical/implementation/testing.md", + "40e8d17168665d33", + { "html": 8990, "metadata": 8991 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"testing-strategy\">Testing Strategy\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#testing-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Testing Strategy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Status:\u003C/strong> Active\n\u003Cstrong>Last Updated:\u003C/strong> February 2026\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy\">Philosophy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout Lite testing follows these principles:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Test critical paths first\u003C/strong> - Statistical accuracy is business-critical\u003C/li>\n\u003Cli>\u003Cstrong>Behavior over implementation\u003C/strong> - Test what the code does, not how it does it\u003C/li>\n\u003Cli>\u003Cstrong>Local-first\u003C/strong> - All tests run locally without CI/CD dependencies\u003C/li>\n\u003Cli>\u003Cstrong>Agent-Augmented & Chrome-Verified\u003C/strong> — Leverage AI agents (“Antigravity”) and Claude Code Chrome browser integration for complex E2E, visual, and regression testing\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"framework\">Framework\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#framework\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Framework”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Tool\u003C/th>\u003Cth align=\"left\">Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Vitest\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Test runner (Vite-native, fast)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Playwright\u003C/strong>\u003C/td>\u003Ctd align=\"left\">E2E browser testing (Chromium)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>React Testing Library\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Component testing (PWA, Azure)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>@testing-library/jest-dom\u003C/strong>\u003C/td>\u003Ctd align=\"left\">DOM assertions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Antigravity (Agent)\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Visual verification, E2E flows, manual QA automation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Claude Code Chrome\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Interactive browser testing, visual checks, protocol execution\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"running-tests\">Running Tests\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#running-tests\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Running Tests”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run all vitest tests across monorepo\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run tests in specific package\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/pwa\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/hooks\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Watch mode (during development)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--watch\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Coverage report\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--coverage\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Chrome Browser Testing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">claude\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--chrome\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Enable Chrome browser access\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Then use prompts like: \"Run the staged analysis verification protocol\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Playwright E2E (automated regression)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/pwa\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test:e2e\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test:e2e\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm testpnpm --filter @variscout/core testpnpm --filter @variscout/pwa testpnpm --filter @variscout/azure-app testpnpm --filter @variscout/hooks testpnpm --filter @variscout/charts testpnpm --filter @variscout/ui testpnpm --filter @variscout/core test -- --watchpnpm --filter @variscout/core test -- --coverageclaude --chrome # Enable Chrome browser accesspnpm --filter @variscout/pwa test:e2epnpm --filter @variscout/azure-app test:e2e\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"agentic--chrome-browser-testing\">Agentic & Chrome Browser Testing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#agentic--chrome-browser-testing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Agentic & Chrome Browser Testing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Antigravity (Agent)\u003C/strong> — Issue a prompt to the AI agent for autonomous verification:\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Run the smoke test protocol on the PWA”\n“Verify the StatsPanel visualization matches the data”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Claude Code Chrome\u003C/strong> — Interactive browser testing via Claude Code’s native Chrome integration:\u003C/p>\n\u003Cp>\u003Cstrong>Prerequisites:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Claude Code CLI v2.0.73+ with Chrome extension v1.0.36+\u003C/li>\n\u003Cli>Enable with \u003Ccode dir=\"auto\">claude --chrome\u003C/code> to launch a visible Chrome window\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Usage examples:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Open localhost:5173, load the Coffee sample, and verify the I-Chart renders with control limits”\n“Run the staged analysis verification protocol”\n“Switch to the Azure app at localhost:5174 and verify the theme toggle works”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>When to use each:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Method\u003C/th>\u003Cth align=\"left\">Best For\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">Antigravity\u003C/td>\u003Ctd align=\"left\">AI-driven verification, complex multi-step flows, batch QA runs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Chrome\u003C/td>\u003Ctd align=\"left\">Interactive visual checks, debugging, authenticated session testing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Playwright\u003C/td>\u003Ctd align=\"left\">Automated CI regression, headless pipelines, deterministic assertions\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"test-ownership-by-package\">Test Ownership by Package\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#test-ownership-by-package\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Test Ownership by Package”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Package\u003C/th>\u003Cth align=\"left\">Test Type\u003C/th>\u003Cth align=\"left\">What to Test\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/td>\u003Ctd align=\"left\">\u003Cstrong>Unit\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Statistics (calculateStats, calculateAnova, calculateRegression), parser, license validation, export utilities\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/td>\u003Ctd align=\"left\">\u003Cstrong>Unit\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Color constants, accessibility utilities, multi-selection hook\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>\u003C/td>\u003Ctd align=\"left\">\u003Cstrong>Unit\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Hooks (useTier, useChartScale, useColumnClassification, useDrillPath, useMindmapState, useVariationTracking, useDataTablePagination, useHighlightFade, useResizablePanel, useAnnotationMode, useBoxplotData, useChartCopy, useControlViolations, useDataIngestion, useDataState, useFilterNavigation, useFocusedChartNav, useIChartData, useKeyboardNavigation, useResponsiveChartMargins, useThemeState), pipeline integration, filter state transitions, stress tests\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd align=\"left\">\u003Cstrong>Unit\u003C/strong>\u003C/td>\u003Ctd align=\"left\">UpgradePrompt, HelpTooltip, DataQualityBanner, ColumnMapping, BoxplotDisplayToggle, DataTableBase\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">@variscout/pwa\u003C/code>\u003C/td>\u003Ctd align=\"left\">\u003Cstrong>Component\u003C/strong>\u003C/td>\u003Ctd align=\"left\">UI components (StatsPanel, Dashboard, DataTableModal, AnovaResults, MindmapPanel, WhatIfPage, WhatIfSimulator), hooks (useFilterNavigation), export utilities\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">@variscout/pwa\u003C/code>\u003C/td>\u003Ctd align=\"left\">\u003Cstrong>Playwright E2E\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Critical workflow, drill-down, samples, analysis views, stats/ANOVA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">@variscout/azure-app\u003C/code>\u003C/td>\u003Ctd align=\"left\">\u003Cstrong>Component\u003C/strong>\u003C/td>\u003Ctd align=\"left\">UI components (Dashboard, StatsPanel, AnovaResults, MindmapWindow, WhatIfPage, FilterBreadcrumb, Editor, SettingsPanel), auth (easyAuth), storage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">@variscout/azure-app\u003C/code>\u003C/td>\u003Ctd align=\"left\">\u003Cstrong>Playwright E2E\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Editor workflow, samples, analysis views, stats/ANOVA\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"priority-tiers\">Priority Tiers\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#priority-tiers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Priority Tiers”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Priority\u003C/th>\u003Cth align=\"left\">Category\u003C/th>\u003Cth align=\"left\">Rationale\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>P0\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Statistics engine\u003C/td>\u003Ctd align=\"left\">Business-critical accuracy - wrong Cpk could lead to bad decisions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>P1\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Data persistence\u003C/td>\u003Ctd align=\"left\">User data integrity - losing projects is unacceptable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>P2\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Export/Import\u003C/td>\u003Ctd align=\"left\">Data portability - .vrs files must work reliably\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>P3\u003C/strong>\u003C/td>\u003Ctd align=\"left\">UI & Visuals\u003C/td>\u003Ctd align=\"left\">\u003Cstrong>Agent/Chrome-verified\u003C/strong> visuals and interactions\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"reference-validation-nist-strd--r\">Reference Validation (NIST StRD + R)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#reference-validation-nist-strd--r\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reference Validation (NIST StRD + R)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s statistics engine is validated against \u003Cstrong>NIST Statistical Reference Datasets\u003C/strong> (StRD) and \u003Cstrong>R statistical software\u003C/strong> reference values. This provides independent, externally certified ground truth for statistical accuracy.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-nist-strd\">Why NIST StRD?\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-nist-strd\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why NIST StRD?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The National Institute of Standards and Technology publishes datasets with certified statistical values computed to 15+ significant digits. Software that produces correct results on these datasets is unlikely to have systematic numerical errors. Several datasets are specifically designed to expose flaws in naive algorithms (e.g., catastrophic cancellation in variance computation).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"datasets-used\">Datasets Used\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#datasets-used\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Datasets Used”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Dataset\u003C/th>\u003Cth align=\"left\">NIST Category\u003C/th>\u003Cth align=\"left\">What It Validates\u003C/th>\u003Cth align=\"left\">Difficulty\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">NumAcc1\u003C/td>\u003Ctd align=\"left\">Univariate\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateStats\u003C/code> mean/stdDev with large offset\u003C/td>\u003Ctd align=\"left\">Lower\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">NumAcc4\u003C/td>\u003Ctd align=\"left\">Univariate\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateStats\u003C/code> mean/stdDev — catastrophic cancellation stress test\u003C/td>\u003Ctd align=\"left\">Higher\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">SiRstv\u003C/td>\u003Ctd align=\"left\">ANOVA\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateAnova\u003C/code> F-statistic, eta-squared, residual SD, p-value\u003C/td>\u003Ctd align=\"left\">Average\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Norris\u003C/td>\u003Ctd align=\"left\">Linear Regression\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateRegression\u003C/code> slope, intercept, R²\u003C/td>\u003Ctd align=\"left\">Lower\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Pontius\u003C/td>\u003Ctd align=\"left\">Linear Regression\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateRegression\u003C/code> quadratic R² with large x values\u003C/td>\u003Ctd align=\"left\">Average\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"indirect-validation-strategy\">Indirect Validation Strategy\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#indirect-validation-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Indirect Validation Strategy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Private helper functions (\u003Ccode dir=\"auto\">normalPDF\u003C/code>, \u003Ccode dir=\"auto\">incompleteBeta\u003C/code>, \u003Ccode dir=\"auto\">lnGamma\u003C/code>, \u003Ccode dir=\"auto\">fDistributionPValue\u003C/code>, \u003Ccode dir=\"auto\">tDistributionPValue\u003C/code>) are not exported and cannot be tested directly. They are validated \u003Cstrong>indirectly\u003C/strong> through end-to-end chains:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>F-distribution chain:\u003C/strong> ANOVA p-value = \u003Ccode dir=\"auto\">fDistributionPValue(F, df1, df2)\u003C/code> → \u003Ccode dir=\"auto\">incompleteBeta()\u003C/code> → \u003Ccode dir=\"auto\">lnGamma()\u003C/code>. If the SiRstv p-value matches R’s \u003Ccode dir=\"auto\">pf()\u003C/code> output, the entire chain is correct.\u003C/li>\n\u003Cli>\u003Cstrong>t-distribution chain:\u003C/strong> Regression p-value = \u003Ccode dir=\"auto\">tDistributionPValue(t, df)\u003C/code> → \u003Ccode dir=\"auto\">fDistributionPValue()\u003C/code> → \u003Ccode dir=\"auto\">incompleteBeta()\u003C/code>. If the Norris slope p-value is < 1e-10 (matching R), the chain is correct.\u003C/li>\n\u003Cli>\u003Cstrong>Normal quantile:\u003C/strong> \u003Ccode dir=\"auto\">normalQuantile()\u003C/code> is validated against R’s \u003Ccode dir=\"auto\">qnorm()\u003C/code> at 11 standard percentile points to 8 decimal places.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"achieved-tolerances\">Achieved Tolerances\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#achieved-tolerances\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Achieved Tolerances”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Section\u003C/th>\u003Cth align=\"left\">Function\u003C/th>\u003Cth align=\"left\">Tolerance\u003C/th>\u003Cth align=\"left\">Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">Normal quantile\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">normalQuantile\u003C/code> vs R \u003Ccode dir=\"auto\">qnorm()\u003C/code>\u003C/td>\u003Ctd align=\"left\">8 decimal places\u003C/td>\u003Ctd align=\"left\">Acklam’s algorithm\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">NumAcc1\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateStats\u003C/code> mean, stdDev\u003C/td>\u003Ctd align=\"left\">9 decimal places\u003C/td>\u003Ctd align=\"left\">Well-conditioned\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">NumAcc4\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateStats\u003C/code> mean\u003C/td>\u003Ctd align=\"left\">7 decimal places\u003C/td>\u003Ctd align=\"left\">d3.mean loses ~2 digits at 10^7\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">NumAcc4\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateStats\u003C/code> stdDev\u003C/td>\u003Ctd align=\"left\">8 decimal places\u003C/td>\u003Ctd align=\"left\">Welford’s algorithm in d3.deviation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">SiRstv\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateAnova\u003C/code> F, eta², residual SD\u003C/td>\u003Ctd align=\"left\">6 decimal places\u003C/td>\u003Ctd align=\"left\">Standard conditioning\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Norris\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateRegression\u003C/code> slope, intercept, R²\u003C/td>\u003Ctd align=\"left\">10 decimal places\u003C/td>\u003Ctd align=\"left\">Well-conditioned OLS\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Pontius\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateRegression\u003C/code> quadratic R²\u003C/td>\u003Ctd align=\"left\">6 decimal places\u003C/td>\u003Ctd align=\"left\">Large x values (up to 3×10^6)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Boxplot\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateBoxplotStats\u003C/code> Q1, median, Q3\u003C/td>\u003Ctd align=\"left\">10 decimal places\u003C/td>\u003Ctd align=\"left\">R type=7 linear interpolation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Matrix\u003C/td>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">inverse\u003C/code>, \u003Ccode dir=\"auto\">multiply\u003C/code>, \u003Ccode dir=\"auto\">solve\u003C/code>\u003C/td>\u003Ctd align=\"left\">6–10 decimal places\u003C/td>\u003Ctd align=\"left\">Depends on condition number\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cross-validation-with-minitab\">Cross-Validation with Minitab\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cross-validation-with-minitab\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Validation with Minitab”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>CSV reference data files are available in \u003Ccode dir=\"auto\">packages/core/reference-data/\u003C/code> for independent verification in Minitab or any statistics package. See the \u003Ccode dir=\"auto\">packages/core/reference-data/README.md\u003C/code> in that directory for certified values and step-by-step Minitab instructions.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"current-coverage\">Current Coverage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#current-coverage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Current Coverage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Total: 90 vitest files, 1,475 test cases + 19 Playwright E2E spec files\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutcore-26-files-739-test-cases\">@variscout/core (26 files, 739 test cases)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutcore-26-files-739-test-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/core (26 files, 739 test cases)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Function/Module\u003C/th>\u003Cth align=\"left\">Tested\u003C/th>\u003Cth align=\"left\">Cases\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateStats()\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Basic stats, Cp/Cpk, one-sided specs, empty data, sigma within (MR/d2)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateAnova()\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Significant/non-significant, group stats, eta-squared\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateRegression()\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Linear, quadratic, weak relationships, optimum detection, column selection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">calculateMultipleRegression()\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">GLM, categorical predictors, interaction terms, model reduction\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">getNelsonRule2ViolationPoints()\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Run detection, edge cases (8 vs 9 points), mean breaks run, staged mode\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Reference validation (NIST/R)\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">normalQuantile, mean/stdDev, ANOVA F, regression coefficients, boxplot quantiles, matrix ops, KDE, probability plot\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Golden data tests\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Static CSV cases (coffee, packaging, avocado) with known expected values\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">tier.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Tier configuration, channel limits, validation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">parser.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">CSV/Excel parsing, auto-mapping, validation, data types\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">export.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">CSV generation, special characters, escaping\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">performance.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Multi-channel analysis, performance metrics\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutcharts-4-files-59-test-cases\">@variscout/charts (4 files, 59 test cases)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutcharts-4-files-59-test-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/charts (4 files, 59 test cases)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Module\u003C/th>\u003Cth align=\"left\">Tested\u003C/th>\u003Cth align=\"left\">Focus\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">colors.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Chart color constants, theme color functions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">accessibility.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Accessible color generation, contrast ratios\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useMultiSelection\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Multi-selection hook for Performance charts\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscouthooks-29-files-317-test-cases\">@variscout/hooks (29 files, 317 test cases)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscouthooks-29-files-317-test-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/hooks (29 files, 317 test cases)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Hook/Module\u003C/th>\u003Cth align=\"left\">Tested\u003C/th>\u003Cth align=\"left\">Focus\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useAnnotationMode\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Chart annotation state, highlights, text notes, context menu\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useBoxplotData\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Shared d3 boxplot computation (quartiles, outliers)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useChartCopy\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Chart copy-to-clipboard, PNG/SVG download, style restore\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useChartScale\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Y-axis scale calculation, locked vs dynamic ranges\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useColumnClassification\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Numeric vs categorical column detection, threshold tuning\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useControlViolations\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Control/spec violation computation, violation counts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useDataIngestion\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">File upload, data parsing, sample loading\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useDataState\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Shared DataContext state management, display options\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useDataTablePagination\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Page state, row slicing, boundary conditions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useDrillPath\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">DrillStep computation from filterStack, node contributions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useFilterNavigation\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Multi-select, updateFilterValues, removeFilter, breadcrumbs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useFocusedChartNav\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Focused chart keyboard navigation, chart order\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useHighlightFade\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Highlight timeout, fade animation state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useIChartData\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Shared I-Chart data transform (control limits, points)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useKeyboardNavigation\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Arrow key navigation, focus management\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useBoxplotWrapperData\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Shared boxplot wrapper data prep (quartiles, groups)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useIChartWrapperData\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Shared I-Chart wrapper data prep (points, limits)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useParetoChartData\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Shared Pareto chart data prep (rankings, Cpk)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useDashboardComputedData\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Shared dashboard computed stats and chart data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useResizablePanel\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Panel size state, drag interaction, constraints\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useResponsiveChartMargins\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Dynamic chart margins based on container width\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useThemeState\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Theme state (light/dark/system), themingEnabled parameter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useTier\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Tier info, channel validation, warning messages\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useVariationTracking\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Cumulative eta-squared, filter chip data with contribution %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">filterStateTransitions\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Filter add/remove/clear state machine transitions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">stress\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Performance/stress tests for hooks under load\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">index.ts\u003C/code> (exports)\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">All public exports resolve correctly\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">Integration: filterStatsPipeline\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">End-to-end: CSV parse → filter → stats → ANOVA pipeline\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutui-10-files-136-test-cases\">@variscout/ui (10 files, 136 test cases)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutui-10-files-136-test-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/ui (10 files, 136 test cases)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Component\u003C/th>\u003Cth align=\"left\">Tested\u003C/th>\u003Cth align=\"left\">Focus\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">UpgradePrompt\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Variants (inline/banner/card), tier messaging\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">HelpTooltip\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Tooltip rendering, glossary term display, icons\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">DataQualityBanner\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Validation summary, warning/error states\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">ColumnMapping\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">maxFactors enforcement, spec entry, column selection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">BoxplotDisplayToggle\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Violin mode toggle, contribution label toggle, sort criterion selection, sort direction toggle, popover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">DataTableBase\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Inline cell editing, multi-cell paste, arrow-key navigation, row status indicators, spec violation highlighting\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutpwa-10-vitest-files-100-test-cases\">@variscout/pwa (10 vitest files, 100 test cases)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutpwa-10-vitest-files-100-test-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/pwa (10 vitest files, 100 test cases)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Component/Module\u003C/th>\u003Cth align=\"left\">Tested\u003C/th>\u003Cth align=\"left\">Focus\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">StatsPanel\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Conditional display, Cp/Cpk formatting, tabs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">Dashboard\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">View switching, chart rendering, ANOVA integration\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">DataTableModal\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Cell editing, row operations, paste handling\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">AnovaResults\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Null state, F-stat display, p-value format\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">MindmapPanel\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Panel open/close, backdrop, slide-in animation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">WhatIfPage\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Simulator rendering, navigation, spec limits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">WhatIfSimulator\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Slider interaction, predicted values, reset\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">PasteScreen\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Paste input, parseText integration, column mapping\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">useFilterNavigation\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Multi-select, updateFilterValues, removeFilter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">export.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">CSV generation, special characters\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscoutazure-app-15-vitest-files-171-test-cases\">@variscout/azure-app (15 vitest files, 171 test cases)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscoutazure-app-15-vitest-files-171-test-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “@variscout/azure-app (15 vitest files, 171 test cases)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Component/Module\u003C/th>\u003Cth align=\"left\">Tested\u003C/th>\u003Cth align=\"left\">Focus\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">AnovaResults\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Null state, F-stat display, p-value format\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">Dashboard\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Tab switching (Analysis/Performance), stats\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">StatsPanel\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Conditional display, Cp/Cpk, sigma within\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">MindmapWindow\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Window rendering, popout behavior, localStorage sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">WhatIfPage\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Simulator integration, navigation, predictions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">FilterBreadcrumb\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Chip rendering, remove button, contribution %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">Editor\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Empty state, sample loading, navigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">SettingsPanel\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Theme toggle, display options, panel open/close\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">ColumnMapping (re-edit)\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Factor add/remove via ColumnMapping mode=‘edit’, safe cancel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">PasteScreen\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Paste input, parseText integration, column mapping\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">easyAuth\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Mock user on localhost, AuthError codes, proactive token refresh, login/logout\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">storage\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Offline-first storage, IndexedDB operations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">PresentationView\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Full-screen chart grid, focused chart navigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">SyncToast\u003C/code>\u003C/td>\u003Ctd align=\"left\">✅\u003C/td>\u003Ctd align=\"left\">Toast notifications, auto-dismiss, action buttons\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"playwright-e2e-coverage\">Playwright E2E Coverage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#playwright-e2e-coverage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Playwright E2E Coverage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-10-spec-files\">PWA (10 spec files)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-10-spec-files\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA (10 spec files)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Spec File\u003C/th>\u003Cth align=\"left\">Tests\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">critical-workflow.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">App load, home screen, sample load, stats display, SVG rendering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">drill-down.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Boxplot click → filter chip, stats update, chip remove, clear all\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">samples.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">All sample datasets load, chart rendering, expected stats values\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">analysis-views.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Dashboard view switching via Settings, SVG rendering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">stats-anova.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Cp/Cpk display, mean/sigma/samples, ANOVA F-stat/p-value/eta²\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">user-flows.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">End-to-end user journeys, navigation flows, multi-step workflows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">edge-cases.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Boundary conditions, empty states, error handling, edge scenarios\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">bottleneck-investigation.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Bottleneck case study drill-down investigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">hospital-ward-investigation.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Hospital ward case study investigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">mindmap-evaluation.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Mindmap panel rendering and interaction\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run PWA E2E tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/pwa\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test:e2e\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm --filter @variscout/pwa test:e2e\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-app-9-spec-files\">Azure App (9 spec files)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-9-spec-files\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App (9 spec files)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Spec File\u003C/th>\u003Cth align=\"left\">Tests\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">editor-workflow.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Auth, empty state, sample load, chart rendering, filter drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">samples.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Sample dataset loading, chart rendering, expected values\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">analysis-views.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Analysis view switching, SVG rendering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">stats-anova.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Mean/sigma/samples display, ANOVA F-stat/p-value/eta²\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">user-flows.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">End-to-end user journeys, editor navigation, multi-step workflows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">edge-cases.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Boundary conditions, empty states, error handling, edge scenarios\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">editor-features.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">CSV export, data panel, save, What-If, mindmap toggle\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">performance-mode.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Performance tab, Cp/Cpk toggle, spec limits, channel count\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">settings-theme.spec.ts\u003C/code>\u003C/td>\u003Ctd align=\"left\">Settings panel, light/dark theme, accent colors, chart text size\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run Azure E2E tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test:e2e\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm --filter @variscout/azure-app test:e2e\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-e2e-patterns\">Azure E2E Patterns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-e2e-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure E2E Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Azure E2E tests share a helper module at \u003Ccode dir=\"auto\">apps/azure/e2e/helpers.ts\u003C/code> with three exported functions:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Function\u003C/th>\u003Cth align=\"left\">Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">confirmColumnMapping\u003C/code>\u003C/td>\u003Ctd align=\"left\">Click “Start Analysis” on the ColumnMapping screen\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">loadSampleInEditor\u003C/code>\u003C/td>\u003Ctd align=\"left\">Navigate to editor, load first sample, confirm mapping, wait for charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Ccode dir=\"auto\">loadPerformanceSample\u003C/code>\u003C/td>\u003Ctd align=\"left\">Load the large-scale performance sample and confirm mapping\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key patterns for Azure E2E tests:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>ColumnMapping flow:\u003C/strong> Every sample load, paste, or file upload triggers the “Map Your Data” ColumnMapping screen. Tests must call \u003Ccode dir=\"auto\">confirmColumnMapping(page)\u003C/code> (or use \u003Ccode dir=\"auto\">loadSampleInEditor\u003C/code>) to click “Start Analysis” before asserting on charts.\u003C/li>\n\u003Cli>\u003Cstrong>Clean state between samples:\u003C/strong> Use \u003Ccode dir=\"auto\">page.goto('/')\u003C/code> between sequential sample loads to reset persisted IndexedDB state. Without this, the second sample load may skip the empty-state editor.\u003C/li>\n\u003Cli>\u003Cstrong>ANOVA location:\u003C/strong> ANOVA results are only visible in the FocusedChartView (boxplot focused view). Tests must maximize the boxplot card first (click the expand button on \u003Ccode dir=\"auto\">[data-testid=\"chart-boxplot\"]\u003C/code>).\u003C/li>\n\u003Cli>\u003Cstrong>Paste vs Manual Entry:\u003C/strong> “Paste Data” button opens a textarea for pasting tabular text. “Manual Entry” opens the setup form for creating columns and entering values row by row.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"playwright-vs-agenticchrome-testing\">Playwright vs Agentic/Chrome Testing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#playwright-vs-agenticchrome-testing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Playwright vs Agentic/Chrome Testing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses three complementary E2E verification methods:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">Aspect\u003C/th>\u003Cth align=\"left\">Antigravity (Agent)\u003C/th>\u003Cth align=\"left\">Claude Code Chrome\u003C/th>\u003Cth align=\"left\">Playwright\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Execution\u003C/strong>\u003C/td>\u003Ctd align=\"left\">AI-driven, autonomous\u003C/td>\u003Ctd align=\"left\">Interactive, human-guided\u003C/td>\u003Ctd align=\"left\">Automated, headless\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Best for\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Complex multi-step flows, batch QA\u003C/td>\u003Ctd align=\"left\">Visual debugging, authenticated flows\u003C/td>\u003Ctd align=\"left\">CI regression, deterministic checks\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Speed\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Medium (AI reasoning overhead)\u003C/td>\u003Ctd align=\"left\">Slow (interactive)\u003C/td>\u003Ctd align=\"left\">Fast (scripted)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Flakiness\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Low (adaptive)\u003C/td>\u003Ctd align=\"left\">None (human-observed)\u003C/td>\u003Ctd align=\"left\">Medium (timing-sensitive)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>CI/CD\u003C/strong>\u003C/td>\u003Ctd align=\"left\">No\u003C/td>\u003Ctd align=\"left\">No\u003C/td>\u003Ctd align=\"left\">Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Visual checks\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Yes (screenshot analysis)\u003C/td>\u003Ctd align=\"left\">Yes (live observation)\u003C/td>\u003Ctd align=\"left\">Limited (snapshot comparison)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Why three methods coexist:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Playwright\u003C/strong> catches regressions automatically in CI — deterministic, fast, scriptable\u003C/li>\n\u003Cli>\u003Cstrong>Antigravity\u003C/strong> handles complex verification that’s hard to script — AI adapts to UI changes\u003C/li>\n\u003Cli>\u003Cstrong>Chrome\u003C/strong> enables interactive debugging and visual spot-checks during development\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>When they disagree:\u003C/strong> Playwright is the source of truth for CI gates. If Antigravity or Chrome finds an issue Playwright misses, add a Playwright test to cover it.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"testing-patterns\">Testing Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#testing-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Testing Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"float-comparisons-statistics\">Float Comparisons (Statistics)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#float-comparisons-statistics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Float Comparisons (Statistics)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Use toBeCloseTo for floating-point math\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">expect\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toBeCloseTo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">11.2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1 decimal precision\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">expect\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">cpk\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toBeCloseTo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.33\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2 decimal precision\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// NIST-grade: 10 decimal places for well-conditioned OLS\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">expect\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(result\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">linear\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">slope\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toBeCloseTo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.00211681802045\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">10\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Stress test: 7-8 decimal places for large-offset data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">expect\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toBeCloseTo\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">10000000.2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">7\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Use toBeCloseTo for floating-point mathexpect(stats.mean).toBeCloseTo(11.2, 1); // 1 decimal precisionexpect(stats.cpk).toBeCloseTo(0.33, 2); // 2 decimal precision// NIST-grade: 10 decimal places for well-conditioned OLSexpect(result.linear.slope).toBeCloseTo(1.00211681802045, 10);// Stress test: 7-8 decimal places for large-offset dataexpect(stats.mean).toBeCloseTo(10000000.2, 7);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"component-testing-with-context\">Component Testing with Context\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#component-testing-with-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Component Testing with Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { vi } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">vitest\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">*\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">as\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> DataContextModule \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">../context/DataContext\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">beforeEach\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">vi\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">restoreAllMocks\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">it\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">displays Cpk when showCpk is true\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">vi\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">spyOn\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(DataContextModule, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">useData\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mockReturnValue\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">displayOptions: { showCpk: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ... other context values\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">render\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(<\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">StatsPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">stats\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">={mockStats} />);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">expect\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(screen\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getByText\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toBeInTheDocument\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { vi } from 'vitest';import * as DataContextModule from '../context/DataContext';beforeEach(() => { vi.restoreAllMocks();});it('displays Cpk when showCpk is true', () => { vi.spyOn(DataContextModule, 'useData').mockReturnValue({ displayOptions: { showCpk: true }, // ... other context values }); render(\u003CStatsPanel stats={mockStats} />); expect(screen.getByText('Cpk')).toBeInTheDocument();});\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mocking-external-libraries\">Mocking External Libraries\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mocking-external-libraries\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mocking External Libraries”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mock libraries with CSS/DOM issues\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">vi\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mock\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">react-resizable-panels\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">{ \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">children\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> }\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> <\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">div\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">data\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">-\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">testid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">panel-group\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>{children}\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">div\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Panel\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">{ \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">children\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> }\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> <\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">div\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">data\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">-\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">testid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">panel\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>{children}\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">div\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}));\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mock child components to isolate tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">vi\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mock\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">../charts/IChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">default\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> <\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">div\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">data\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">-\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">testid\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">i-chart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>Mock\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">div\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}));\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Mock libraries with CSS/DOM issuesvi.mock('react-resizable-panels', () => ({ Group: ({ children }) => \u003Cdiv data-testid="panel-group">{children}\u003C/div>, Panel: ({ children }) => \u003Cdiv data-testid="panel">{children}\u003C/div>,}));// Mock child components to isolate testsvi.mock('../charts/IChart', () => ({ default: () => \u003Cdiv data-testid="i-chart">Mock\u003C/div>,}));\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"common-pitfalls\">Common Pitfalls\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#common-pitfalls\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Pitfalls”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Mock ordering (OOM prevention):\u003C/strong> When mocking dependencies of imported components, place \u003Ccode dir=\"auto\">vi.mock()\u003C/code> calls \u003Cstrong>before\u003C/strong> the component import. This ensures stable mock references and prevents infinite re-render loops in \u003Ccode dir=\"auto\">useEffect\u003C/code> dependency arrays.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ✅ Correct: mock BEFORE import\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">vi\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mock\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">../context/DataContext\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useData: vi\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fn\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> mockDataValue),\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}));\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { SettingsPanel } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">../components/SettingsPanel\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ❌ Wrong: import before mock — can cause OOM (infinite re-renders)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { SettingsPanel } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">../components/SettingsPanel\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">vi\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mock\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">../context/DataContext\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ({\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useData: vi\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fn\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> mockDataValue),\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}));\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// ✅ Correct: mock BEFORE importvi.mock('../context/DataContext', () => ({ useData: vi.fn(() => mockDataValue),}));import { SettingsPanel } from '../components/SettingsPanel';// ❌ Wrong: import before mock — can cause OOM (infinite re-renders)import { SettingsPanel } from '../components/SettingsPanel';vi.mock('../context/DataContext', () => ({ useData: vi.fn(() => mockDataValue),}));\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This pattern was identified fixing the Azure \u003Ccode dir=\"auto\">SettingsPanel\u003C/code> test (165s OOM → 1s).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"verification-pattern\">Verification Pattern\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#verification-pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Verification Pattern”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When asking the agent (or using Chrome) to verify a feature:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>State the Goal\u003C/strong>: “Verify the new Pareto Chart rendering.”\u003C/li>\n\u003Cli>\u003Cstrong>Define Success\u003C/strong>: “It should show bars sorted by frequency and a cumulative line.”\u003C/li>\n\u003Cli>\u003Cstrong>Provide Context\u003C/strong>: “Open the PWA, load the sample data, and navigate to the Dashboard.”\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"test-file-organization\">Test File Organization\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#test-file-organization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Test File Organization”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">packages/core/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── reference-data/ # NIST StRD CSV files for Minitab cross-validation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── README.md\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── nist-numacc1.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── nist-numacc4.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── nist-sirstv.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── nist-norris.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── nist-pontius.csv\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── stats.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── parser.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── performance.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── __tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── stats.test.ts # Core statistics engine\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── regression.test.ts # Simple regression\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── multiRegression.test.ts # GLM / multiple regression\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── modelReduction.test.ts # Term removal suggestions\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── reference-validation.test.ts # NIST StRD + R reference values\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── goldenData.test.ts # Static CSV golden data tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── performance.test.ts # Multi-channel performance\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── projectedStats.test.ts # Projected what-if stats\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── directAdjustment.test.ts # Direct adjustment calculations\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── simulation.test.ts # Model-driven simulation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── nelson.test.ts # Nelson rules violation detection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── categoryStats.test.ts # Category-level statistics\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── sortBoxplotData.test.ts # Boxplot sorting by mean/spread/name\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── parser.test.ts # CSV/Excel parsing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── stressParser.test.ts # Parser stress/performance tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── export.test.ts # CSV export\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── navigation.test.ts # Navigation utilities\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── variation.test.ts # Variation tracking\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── tier.test.ts # Tier configuration\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── time.test.ts # Time utilities\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── edgeCases.test.ts # Edge case handling\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── stress.test.ts # Performance stress tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── urlParams.test.ts # URL parameter parsing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">packages/charts/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── __tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── colors.test.ts # Chart color constants\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── hooks/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── useMultiSelection.test.ts # Multi-selection hook\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── utils/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── accessibility.test.ts # Accessible color generation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">packages/hooks/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── __tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── index.test.ts # Export verification\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useAnnotationMode.test.ts # Chart annotation state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useBoxplotData.test.ts # Shared boxplot computation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useChartCopy.test.ts # Chart copy/export\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useChartScale.test.ts # Y-axis scale\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useColumnClassification.test.ts # Column type detection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useControlViolations.test.ts # Control/spec violations\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useDataIngestion.test.ts # File upload, data parsing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useDataState.test.ts # DataContext state management\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useDataTablePagination.test.ts # Pagination state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useDrillPath.test.ts # Drill path computation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useFilterNavigation.test.ts # Filter navigation, multi-select\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useFocusedChartNav.test.ts # Focused chart keyboard nav\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useHighlightFade.test.ts # Highlight fade animation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useIChartData.test.ts # Shared I-Chart data transform\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useKeyboardNavigation.test.ts # Arrow key navigation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useBoxplotWrapperData.test.ts # Boxplot wrapper data prep\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useIChartWrapperData.test.ts # I-Chart wrapper data prep\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useParetoChartData.test.ts # Pareto chart data prep\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useDashboardComputedData.test.ts # Dashboard computed data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useResizablePanel.test.ts # Resizable panel state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useResponsiveChartMargins.test.ts # Dynamic chart margins\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useThemeState.test.ts # Theme state management\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useTier.test.ts # Tier hook\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── useVariationTracking.test.ts # Cumulative eta-squared\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── filterStateTransitions.test.ts # Filter state machine\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── stress.test.ts # Performance stress tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── integration/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── filterStatsPipeline.test.ts # End-to-end pipeline\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">packages/ui/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── src/components/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── UpgradePrompt/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── UpgradePrompt.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── HelpTooltip/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── HelpTooltip.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── DataQualityBanner/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── DataQualityBanner.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── ColumnMapping/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── ColumnMapping.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── BoxplotDisplayToggle/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── BoxplotDisplayToggle.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── DataTable/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── DataTableBase.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">apps/pwa/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── e2e/ # Playwright E2E tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── critical-workflow.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── drill-down.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── samples.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── analysis-views.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── stats-anova.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── user-flows.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── edge-cases.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── components/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── StatsPanel.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── Dashboard.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── AnovaResults.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── MindmapPanel.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── WhatIfPage.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── WhatIfSimulator.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── DataTableModal.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── PasteScreen.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── hooks/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── useFilterNavigation.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── lib/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── export.test.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">apps/azure/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── e2e/ # Playwright E2E tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── editor-workflow.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── samples.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── analysis-views.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── stats-anova.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── user-flows.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── edge-cases.spec.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── vitest.config.ts # Excludes e2e/** and api/**\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── src/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── setupTests.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── auth/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── easyAuth.test.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── services/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── storage.test.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── components/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── AnovaResults.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── Dashboard.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── StatsPanel.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── MindmapWindow.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── WhatIfPage.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── FilterBreadcrumb.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── (removed: FactorManagerPopover — replaced by ColumnMapping re-edit)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── PasteScreen.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ├── PresentationView.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── SyncToast.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── components/settings/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └── SettingsPanel.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── pages/__tests__/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Editor.test.tsx\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"packages/core/├── reference-data/ # NIST StRD CSV files for Minitab cross-validation│ ├── README.md│ ├── nist-numacc1.csv│ ├── nist-numacc4.csv│ ├── nist-sirstv.csv│ ├── nist-norris.csv│ └── nist-pontius.csv├── src/│ ├── stats.ts│ ├── parser.ts│ ├── performance.ts│ └── __tests__/│ ├── stats.test.ts # Core statistics engine│ ├── regression.test.ts # Simple regression│ ├── multiRegression.test.ts # GLM / multiple regression│ ├── modelReduction.test.ts # Term removal suggestions│ ├── reference-validation.test.ts # NIST StRD + R reference values│ ├── goldenData.test.ts # Static CSV golden data tests│ ├── performance.test.ts # Multi-channel performance│ ├── projectedStats.test.ts # Projected what-if stats│ ├── directAdjustment.test.ts # Direct adjustment calculations│ ├── simulation.test.ts # Model-driven simulation│ ├── nelson.test.ts # Nelson rules violation detection│ ├── categoryStats.test.ts # Category-level statistics│ ├── sortBoxplotData.test.ts # Boxplot sorting by mean/spread/name│ ├── parser.test.ts # CSV/Excel parsing│ ├── stressParser.test.ts # Parser stress/performance tests│ ├── export.test.ts # CSV export│ ├── navigation.test.ts # Navigation utilities│ ├── variation.test.ts # Variation tracking│ ├── tier.test.ts # Tier configuration│ ├── time.test.ts # Time utilities│ ├── edgeCases.test.ts # Edge case handling│ ├── stress.test.ts # Performance stress tests│ └── urlParams.test.ts # URL parameter parsingpackages/charts/└── src/ ├── __tests__/ │ └── colors.test.ts # Chart color constants ├── hooks/__tests__/ │ └── useMultiSelection.test.ts # Multi-selection hook └── utils/__tests__/ └── accessibility.test.ts # Accessible color generationpackages/hooks/└── src/ └── __tests__/ ├── index.test.ts # Export verification ├── useAnnotationMode.test.ts # Chart annotation state ├── useBoxplotData.test.ts # Shared boxplot computation ├── useChartCopy.test.ts # Chart copy/export ├── useChartScale.test.ts # Y-axis scale ├── useColumnClassification.test.ts # Column type detection ├── useControlViolations.test.ts # Control/spec violations ├── useDataIngestion.test.ts # File upload, data parsing ├── useDataState.test.ts # DataContext state management ├── useDataTablePagination.test.ts # Pagination state ├── useDrillPath.test.ts # Drill path computation ├── useFilterNavigation.test.ts # Filter navigation, multi-select ├── useFocusedChartNav.test.ts # Focused chart keyboard nav ├── useHighlightFade.test.ts # Highlight fade animation ├── useIChartData.test.ts # Shared I-Chart data transform ├── useKeyboardNavigation.test.ts # Arrow key navigation ├── useBoxplotWrapperData.test.ts # Boxplot wrapper data prep ├── useIChartWrapperData.test.ts # I-Chart wrapper data prep ├── useParetoChartData.test.ts # Pareto chart data prep ├── useDashboardComputedData.test.ts # Dashboard computed data ├── useResizablePanel.test.ts # Resizable panel state ├── useResponsiveChartMargins.test.ts # Dynamic chart margins ├── useThemeState.test.ts # Theme state management ├── useTier.test.ts # Tier hook ├── useVariationTracking.test.ts # Cumulative eta-squared ├── filterStateTransitions.test.ts # Filter state machine ├── stress.test.ts # Performance stress tests └── integration/ └── filterStatsPipeline.test.ts # End-to-end pipelinepackages/ui/└── src/components/ ├── UpgradePrompt/__tests__/ │ └── UpgradePrompt.test.tsx ├── HelpTooltip/__tests__/ │ └── HelpTooltip.test.tsx ├── DataQualityBanner/__tests__/ │ └── DataQualityBanner.test.tsx ├── ColumnMapping/__tests__/ │ └── ColumnMapping.test.tsx ├── BoxplotDisplayToggle/__tests__/ │ └── BoxplotDisplayToggle.test.tsx └── DataTable/__tests__/ └── DataTableBase.test.tsxapps/pwa/├── e2e/ # Playwright E2E tests│ ├── critical-workflow.spec.ts│ ├── drill-down.spec.ts│ ├── samples.spec.ts│ ├── analysis-views.spec.ts│ ├── stats-anova.spec.ts│ ├── user-flows.spec.ts│ └── edge-cases.spec.ts├── src/│ ├── components/__tests__/│ │ ├── StatsPanel.test.tsx│ │ ├── Dashboard.test.tsx│ │ ├── AnovaResults.test.tsx│ │ ├── MindmapPanel.test.tsx│ │ ├── WhatIfPage.test.tsx│ │ ├── WhatIfSimulator.test.tsx│ │ ├── DataTableModal.test.tsx│ │ └── PasteScreen.test.tsx│ ├── hooks/__tests__/│ │ └── useFilterNavigation.test.tsx│ └── lib/__tests__/│ └── export.test.tsapps/azure/├── e2e/ # Playwright E2E tests│ ├── editor-workflow.spec.ts│ ├── samples.spec.ts│ ├── analysis-views.spec.ts│ ├── stats-anova.spec.ts│ ├── user-flows.spec.ts│ └── edge-cases.spec.ts├── vitest.config.ts # Excludes e2e/** and api/**├── src/│ ├── setupTests.ts│ ├── auth/__tests__/│ │ └── easyAuth.test.ts│ ├── services/__tests__/│ │ └── storage.test.ts│ ├── components/__tests__/│ │ ├── AnovaResults.test.tsx│ │ ├── Dashboard.test.tsx│ │ ├── StatsPanel.test.tsx│ │ ├── MindmapWindow.test.tsx│ │ ├── WhatIfPage.test.tsx│ │ ├── FilterBreadcrumb.test.tsx│ │ ├── (removed: FactorManagerPopover — replaced by ColumnMapping re-edit)│ │ ├── PasteScreen.test.tsx│ │ ├── PresentationView.test.tsx│ │ └── SyncToast.test.tsx│ ├── components/settings/__tests__/│ │ └── SettingsPanel.test.tsx│ └── pages/__tests__/│ └── Editor.test.tsx\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-verification-protocols\">Feature Verification Protocols\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-verification-protocols\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Verification Protocols”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Specific prompts for verifying complex features. These protocols can be executed via Antigravity agents or interactively with \u003Ccode dir=\"auto\">claude --chrome\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-staged-analysis-verification\">1. Staged Analysis Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-staged-analysis-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Staged Analysis Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Verify the Staged I-Chart correctly calculates and displays separate control limits for each phase.\u003C/p>\n\u003Cp>\u003Cstrong>Agent Prompt:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Load the ‘Process Changes’ sample (or any dataset with a categorical column). In the Dashboard header, select the categorical column (e.g., ‘Phase’ or ‘Machine’) in the ‘Stage’ dropdown. Verify that the I-Chart updates to show vertical dashed dividers between stages, and that the UCL, Mean, and LCL lines change values at each stage boundary. Confirm that points are colored according to their specific stage’s limits.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Criteria:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Vertical dashed lines separate stages\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Control limit steps (changes in level) at boundaries\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Stage labels visible at top of chart\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-pwa-embed-mode-verification\">2. PWA Embed Mode Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-pwa-embed-mode-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. PWA Embed Mode Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Verify the PWA renders correctly when embedded (hidden chrome, message listening).\u003C/p>\n\u003Cp>\u003Cstrong>Agent Prompt:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Open the PWA with the URL parameters \u003Ccode dir=\"auto\">?embed=true&sample=coffee\u003C/code>. Verify that the application header (navigation) and footer are completely hidden. Check that the chart area maximizes to fill the viewport. Verify that clicking the chart still works (though it might not trigger internal navigation if in pure embed mode).”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Criteria:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> No header/toolbar visible\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> No footer visible\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Charts render full-width/height\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> No console errors related to missing context\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-performance-module-verification\">3. Performance Module Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-performance-module-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Performance Module Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Verify the Multi-Channel Performance Dashboard loads and displays all relevant charts.\u003C/p>\n\u003Cp>\u003Cstrong>Agent Prompt:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Load a dataset with multiple numeric columns (e.g., ‘Coffee Moisture’). Ensure at least 3 numeric columns are selected for analysis in the setup panel (or via ‘New Analysis’ -> ‘Performance Analysis’). Verify that the Dashboard displays the Performance View, containing a Summary Bar, an I-Chart with multiple series (or selectable series), a Boxplot comparing channels, and a Pareto chart ranking them. Click on a specific channel in the Boxplot and verify the other charts update to focus on that channel.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Criteria:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Performance Dashboard layout (Summary + 3-chart grid)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> I-Chart showing Cpk/Cp values\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Boxplot showing distribution comparison\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Pareto showing ranking\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Interactive cross-filtering between charts\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-capability-chart-verification\">4. Capability Chart Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-capability-chart-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Capability Chart Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Verify the capability histogram renders correctly with spec limit indicators.\u003C/p>\n\u003Cp>\u003Cstrong>Agent Prompt:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Load the ‘Packaging’ sample (it has spec limits defined). Navigate to the Stats panel and look for the histogram/capability view. Verify that the histogram shows the data distribution, spec limit lines (USL/LSL) are drawn as vertical markers, bars are colored green (in-spec) vs red (out-of-spec), and Cp/Cpk values are displayed numerically.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Criteria:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Histogram renders with data distribution bars\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Spec limit lines visible (USL and/or LSL)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Pass/fail coloring on histogram bars\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Cp and Cpk values displayed\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"5-anova-results-verification\">5. ANOVA Results Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#5-anova-results-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. ANOVA Results Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Verify ANOVA results display correctly below boxplot with all statistical values.\u003C/p>\n\u003Cp>\u003Cstrong>Agent Prompt:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Load the ‘Coffee Moisture’ sample. Scroll to the boxplot chart area. Below the boxplot, verify the ANOVA results section appears. Check that it shows the factor name (e.g., ‘Drying_Bed’), the F-statistic and p-value on the significance line, and the eta-squared (η²) value. Verify the p-value formats correctly (e.g., ’< 0.001’ for very small values). Check that group means and sample sizes (n=) are listed for each category.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Criteria:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> ANOVA section visible below boxplot (\u003Ccode dir=\"auto\">data-testid=\"anova-results\"\u003C/code>)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> F-statistic displayed with 2 decimal places\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> p-value displayed (formatted, e.g., \u003Ccode dir=\"auto\">< 0.001\u003C/code>)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Eta-squared (η²) shown with percentage\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Factor name mentioned in header\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Group means and n= values listed\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"6-multi-level-drill-down-verification\">6. Multi-Level Drill-Down Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#6-multi-level-drill-down-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Multi-Level Drill-Down Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Verify drilling through 2+ filter levels with cumulative filter chips and stats updates.\u003C/p>\n\u003Cp>\u003Cstrong>Agent Prompt:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Load a sample with multiple categorical columns (e.g., ‘Bottleneck’ or ‘Oven Zones’). Click a boxplot category to apply the first filter — verify a filter chip appears and stats update. Then click another category in the boxplot at the second level — verify a second filter chip appears alongside the first. Confirm that cumulative contribution percentages update. Click ‘Clear All’ and verify all filters are removed and stats revert to the original values.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Criteria:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> First filter chip appears after boxplot click\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Stats (mean, sigma) update to reflect filtered subset\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Second filter chip appears at second drill level\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Both chips visible simultaneously\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Cumulative contribution % updates\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Clear All removes all chips and reverts stats\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"7-manual-data-entry-verification\">7. Manual Data Entry Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#7-manual-data-entry-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “7. Manual Data Entry Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Verify the manual data entry workflow from setup to analysis.\u003C/p>\n\u003Cp>\u003Cstrong>Agent Prompt:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Click ‘Manual Entry’ on the home screen (or ‘Paste from Excel’ for the PWA). In the setup modal, enter a column name and configure measurement type. Verify the data entry grid appears. Type values into cells, press Enter/Tab to navigate. After entering 10+ values, click ‘Analyze’ and verify the dashboard renders with charts based on the entered data. Test paste mode by pasting a column of numbers from clipboard.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Criteria:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Setup modal renders with column name input\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Data grid appears after setup\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Cell editing works (type, Enter, Tab navigation)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> ‘Analyze’ button triggers dashboard rendering\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Pasting multi-line data populates grid\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"8-what-if-simulation-verification\">8. What-If Simulation Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#8-what-if-simulation-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “8. What-If Simulation Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Verify the What-If Simulator sliders, predicted values, and real-time updates.\u003C/p>\n\u003Cp>\u003Cstrong>Agent Prompt:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Load a sample dataset, then open Settings and select ‘What-If Simulator’. Verify that the simulator page renders with sliders for each predictor variable. Move a slider and verify the predicted outcome value updates in real-time. If spec limits exist, verify the predicted value is colored according to pass/fail status. Click ‘Reset’ and verify all sliders return to their default positions.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Criteria:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Simulator page renders with predictor sliders\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Predicted outcome value shown\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Moving slider updates prediction in real-time\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Spec limit pass/fail coloring on predicted value (if applicable)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Reset returns sliders to defaults\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"9-mindmap-panel-verification\">9. Mindmap Panel Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#9-mindmap-panel-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “9. Mindmap Panel Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Verify the Investigation Mindmap renders with correct structure and interaction.\u003C/p>\n\u003Cp>\u003Cstrong>Agent Prompt:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Load a sample with multiple categorical columns. Apply a drill-down filter by clicking a boxplot category. Open the Mindmap panel (look for a tree/mindmap icon). Verify that a radial tree renders with the root node (outcome variable) at center and child nodes for each factor. Check that nodes show eta-squared (η²) labels. Verify the drill trail highlights the path taken. Check the progress bar at the bottom. If available, test the ‘Open in new window’ popout button.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Criteria:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Radial tree SVG renders with nodes\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Root node at center shows outcome variable name\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Child nodes labeled with factor names\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Eta-squared (η²) values on nodes\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Drill trail highlighted for active path\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Progress bar visible\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"10-theme-switching-azure-verification\">10. Theme Switching (Azure) Verification\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#10-theme-switching-azure-verification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “10. Theme Switching (Azure) Verification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Goal:\u003C/strong> Verify light/dark/system theme switching with chart color updates and persistence.\u003C/p>\n\u003Cp>\u003Cstrong>Agent Prompt:\u003C/strong>\u003C/p>\n\u003Cblockquote>\n\u003Cp>“In the Azure app, click the Settings gear icon. Find the theme toggle and switch from Dark to Light mode. Verify that the entire UI updates: backgrounds become light, text becomes dark, and chart chrome (axes, grid lines, labels) changes to light-theme colors. Switch to System mode and verify it follows the OS preference. Close and reopen the app — verify the theme persists.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>\u003Cstrong>Success Criteria:\u003C/strong>\u003C/p>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Theme toggle visible in Settings\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Light mode: white/light backgrounds, dark text\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Dark mode: dark backgrounds, light text\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Chart colors update (grid lines, axis labels, tooltip backgrounds)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> System mode follows OS preference\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Theme persists across page reload\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"qa-verification-checklist\">QA Verification Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#qa-verification-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “QA Verification Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Assign the following tasks to an Antigravity agent or execute interactively via \u003Ccode dir=\"auto\">claude --chrome\u003C/code> for release verification:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa\">PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Smoke Test\u003C/strong>: Launch PWA, ensuring it loads without console errors.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Data Flow\u003C/strong>: Load sample data, edit a cell, verify stats update.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Staged Analysis\u003C/strong>: Enable staging on a sample dataset, verify control limit split.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Performance Analysis\u003C/strong>: Enable multi-channel analysis, verify I-Chart/Boxplot/Pareto grid.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Embed Mode\u003C/strong>: Load \u003Ccode dir=\"auto\">?embed=true\u003C/code>, verify UI chrome is removed.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Visual Check\u003C/strong>: Take screenshots of I-Charts and generic charts; check for layout shifts.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Persistence\u003C/strong>: Reload page, ensure data remains.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Export\u003C/strong>: Generate a PDF/CSV and verify file existence (if environment permits).\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-team-app\">Azure Team App\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-team-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Team App”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Auth Flow\u003C/strong>: Verify EasyAuth login/logout works correctly.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Tab Navigation\u003C/strong>: Switch between Analysis and Performance tabs.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Chart Rendering\u003C/strong>: Verify I-Chart, Boxplot, Pareto, and ScatterPlot charts render.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>ANOVA Integration\u003C/strong>: Confirm ANOVA results display below Boxplot.\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> \u003Cstrong>Sync Status\u003C/strong>: Verify offline/online sync indicator updates.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-documentation\">Related Documentation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">.claude/rules/testing.md\u003C/code> - Quick reference testing rules (in project root)\u003C/li>\n\u003Cli>\u003Ca href=\"../index.md\">Technical Overview\u003C/a> - Technical section index\u003C/li>\n\u003C/ul>", + { + "headings": 8992, + "localImagePaths": 9127, + "remoteImagePaths": 9128, + "frontmatter": 9129, + "imagePaths": 9130 + }, + [ + 8993, 8995, 8996, 8999, 9002, 9005, 9008, 9011, 9014, 9017, 9020, 9023, 9026, 9029, 9032, 9035, + 9038, 9041, 9044, 9047, 9050, 9053, 9056, 9059, 9062, 9065, 9068, 9071, 9074, 9077, 9080, 9083, + 9086, 9089, 9092, 9095, 9098, 9101, 9104, 9107, 9110, 9113, 9116, 9119, 9122, 9123, 9126 + ], + { "depth": 30, "slug": 8994, "text": 8982 }, + "testing-strategy", + { "depth": 33, "slug": 965, "text": 966 }, + { "depth": 33, "slug": 8997, "text": 8998 }, + "framework", + "Framework", + { "depth": 79, "slug": 9000, "text": 9001 }, + "running-tests", + "Running Tests", + { "depth": 79, "slug": 9003, "text": 9004 }, + "agentic--chrome-browser-testing", + "Agentic & Chrome Browser Testing", + { "depth": 33, "slug": 9006, "text": 9007 }, + "test-ownership-by-package", + "Test Ownership by Package", + { "depth": 33, "slug": 9009, "text": 9010 }, + "priority-tiers", + "Priority Tiers", + { "depth": 33, "slug": 9012, "text": 9013 }, + "reference-validation-nist-strd--r", + "Reference Validation (NIST StRD + R)", + { "depth": 79, "slug": 9015, "text": 9016 }, + "why-nist-strd", + "Why NIST StRD?", + { "depth": 79, "slug": 9018, "text": 9019 }, + "datasets-used", + "Datasets Used", + { "depth": 79, "slug": 9021, "text": 9022 }, + "indirect-validation-strategy", + "Indirect Validation Strategy", + { "depth": 79, "slug": 9024, "text": 9025 }, + "achieved-tolerances", + "Achieved Tolerances", + { "depth": 79, "slug": 9027, "text": 9028 }, + "cross-validation-with-minitab", + "Cross-Validation with Minitab", + { "depth": 33, "slug": 9030, "text": 9031 }, + "current-coverage", + "Current Coverage", + { "depth": 79, "slug": 9033, "text": 9034 }, + "variscoutcore-26-files-739-test-cases", + "@variscout/core (26 files, 739 test cases)", + { "depth": 79, "slug": 9036, "text": 9037 }, + "variscoutcharts-4-files-59-test-cases", + "@variscout/charts (4 files, 59 test cases)", + { "depth": 79, "slug": 9039, "text": 9040 }, + "variscouthooks-29-files-317-test-cases", + "@variscout/hooks (29 files, 317 test cases)", + { "depth": 79, "slug": 9042, "text": 9043 }, + "variscoutui-10-files-136-test-cases", + "@variscout/ui (10 files, 136 test cases)", + { "depth": 79, "slug": 9045, "text": 9046 }, + "variscoutpwa-10-vitest-files-100-test-cases", + "@variscout/pwa (10 vitest files, 100 test cases)", + { "depth": 79, "slug": 9048, "text": 9049 }, + "variscoutazure-app-15-vitest-files-171-test-cases", + "@variscout/azure-app (15 vitest files, 171 test cases)", + { "depth": 33, "slug": 9051, "text": 9052 }, + "playwright-e2e-coverage", + "Playwright E2E Coverage", + { "depth": 79, "slug": 9054, "text": 9055 }, + "pwa-10-spec-files", + "PWA (10 spec files)", + { "depth": 79, "slug": 9057, "text": 9058 }, + "azure-app-9-spec-files", + "Azure App (9 spec files)", + { "depth": 79, "slug": 9060, "text": 9061 }, + "azure-e2e-patterns", + "Azure E2E Patterns", + { "depth": 33, "slug": 9063, "text": 9064 }, + "playwright-vs-agenticchrome-testing", + "Playwright vs Agentic/Chrome Testing", + { "depth": 33, "slug": 9066, "text": 9067 }, + "testing-patterns", + "Testing Patterns", + { "depth": 79, "slug": 9069, "text": 9070 }, + "float-comparisons-statistics", + "Float Comparisons (Statistics)", + { "depth": 79, "slug": 9072, "text": 9073 }, + "component-testing-with-context", + "Component Testing with Context", + { "depth": 79, "slug": 9075, "text": 9076 }, + "mocking-external-libraries", + "Mocking External Libraries", + { "depth": 79, "slug": 9078, "text": 9079 }, + "common-pitfalls", + "Common Pitfalls", + { "depth": 79, "slug": 9081, "text": 9082 }, + "verification-pattern", + "Verification Pattern", + { "depth": 33, "slug": 9084, "text": 9085 }, + "test-file-organization", + "Test File Organization", + { "depth": 33, "slug": 9087, "text": 9088 }, + "feature-verification-protocols", + "Feature Verification Protocols", + { "depth": 79, "slug": 9090, "text": 9091 }, + "1-staged-analysis-verification", + "1. Staged Analysis Verification", + { "depth": 79, "slug": 9093, "text": 9094 }, + "2-pwa-embed-mode-verification", + "2. PWA Embed Mode Verification", + { "depth": 79, "slug": 9096, "text": 9097 }, + "3-performance-module-verification", + "3. Performance Module Verification", + { "depth": 79, "slug": 9099, "text": 9100 }, + "4-capability-chart-verification", + "4. Capability Chart Verification", + { "depth": 79, "slug": 9102, "text": 9103 }, + "5-anova-results-verification", + "5. ANOVA Results Verification", + { "depth": 79, "slug": 9105, "text": 9106 }, + "6-multi-level-drill-down-verification", + "6. Multi-Level Drill-Down Verification", + { "depth": 79, "slug": 9108, "text": 9109 }, + "7-manual-data-entry-verification", + "7. Manual Data Entry Verification", + { "depth": 79, "slug": 9111, "text": 9112 }, + "8-what-if-simulation-verification", + "8. What-If Simulation Verification", + { "depth": 79, "slug": 9114, "text": 9115 }, + "9-mindmap-panel-verification", + "9. Mindmap Panel Verification", + { "depth": 79, "slug": 9117, "text": 9118 }, + "10-theme-switching-azure-verification", + "10. Theme Switching (Azure) Verification", + { "depth": 33, "slug": 9120, "text": 9121 }, + "qa-verification-checklist", + "QA Verification Checklist", + { "depth": 79, "slug": 5545, "text": 5546 }, + { "depth": 79, "slug": 9124, "text": 9125 }, + "azure-team-app", + "Azure Team App", + { "depth": 33, "slug": 422, "text": 423 }, + [], + [], + { "title": 8982 }, + [], + "05-technical/integrations/shared-ui", + { "id": 9131, "data": 9133, "body": 9138, "filePath": 9139, "digest": 9140, "rendered": 9141 }, + { + "title": 9134, + "editUrl": 16, + "head": 9135, + "template": 18, + "sidebar": 9136, + "pagefind": 16, + "draft": 20 + }, + "Shared UI Library Strategy", + [], + { "hidden": 20, "attrs": 9137 }, + {}, + "# Shared UI Library Strategy\n\n> [!NOTE]\n> **Status**: Implemented (Jan 2026)\n> **Package**: `@variscout/ui`\n\nThis document outlines the architectural strategy for implementing a Shared UI Library within the VariScout monorepo.\n\n## 1. Current State Assessment\n\n- **Existing Shared Packages**: `packages/core` (logic), `packages/charts` (visualization).\n- **Missing**: No shared UI component library.\n- **PWA (`apps/pwa`)** & **Azure App (`apps/azure`)**: Use **Tailwind CSS** + Headless components (e.g., Radix, Lucide icons) for a custom, modern web aesthetic.\n\n## 2. Architectural Recommendation\n\nWould a shared UI library make sense? **YES**, but with a split strategy.\n\n### The \"Web\" UI Kit (`@variscout/ui`)\n\nA shared UI package for the **PWA** and **Azure App** (and any future web portals). Since they share a tech stack (Tailwind), they share components.\n\n- **Goal**: Ensure `apps/azure` and `apps/pwa` look identical and share the same buttons, inputs, cards, and layouts.\n- **Contents**: Buttons, Forms, Modals, Layouts (Sidebar/Header), Typography.\n\n## 3. Implementation Plan\n\n### 3.1 Create `@variscout/ui`\n\n1. **Location**: `packages/ui`\n2. **Dependencies**: `react`, `react-dom`, `tailwindcss`, `lucide-react`, `class-variance-authority` (helper for component variants).\n3. **Build Tool**: Vite (Library Mode) or tsup.\n\n### 3.2 Shared Tailwind Configuration\n\nTo ensure colors and fonts are consistent, move the Tailwind config to a shared preset.\n\n- **Location**: `packages/ui/tailwind.config.js` (or a specific configuration package like `packages/config-tailwind`).\n- **Usage**: In apps, `import sharedConfig from '@variscout/ui/tailwind.config';`\n\n### 3.3 Component Development (Storybook)\n\nDevelop components in isolation using **Storybook**. This forces components to be pure and decoupled from app-specific state.\n\n## 4. Best Practices\n\n1. **Headless Approach**: For complex interactive components (Tabs, Dropdowns), use a \"Headless\" library (e.g., Radix UI or Headless UI) in the shared package and style it with Tailwind. This provides accessibility out of the box.\n2. **Export Pattern**: Use \"Barrel files\" (`index.ts`) carefully.\n - Good: `export * from './Button';`\n - Ensure tree-shaking works so apps don't bundle unused components.\n3. **Versioning**: Since this is a monorepo, we typically version packages together or use \"workspace:\\*\" protocols.\n4. **Styles**: Ship the CCS with the package or ensuring the consuming app processes the convenient utility classes.\n - _Recommended_: Add the package source paths to the consuming app's `tailwind.config.js` `content` array. This allows the app to generate only the CSS needed.\n\n ```javascript\n // apps/pwa/tailwind.config.js\n export default {\n content: [\n './index.html',\n './src/**/*.{js,ts,jsx,tsx}',\n '../../packages/ui/src/**/*.{js,ts,jsx,tsx}', // \u003C-- Scan shared UI\n ],\n // ...\n };\n ```\n\n## 5. Summary Recommendation\n\n| App | UI Strategy | Action |\n| :------------ | :---------------- | :----------------------------------------------------------- |\n| **PWA** | Custom (Tailwind) | Consume `@variscout/ui` |\n| **Azure App** | Custom (Tailwind) | Consume `@variscout/ui` |\n| **Marketing** | Astro (Tailwind) | SSG for performance, embeds PWA for interactive case studies |\n\n## 6. Cross-App Embedding (iframe strategy)\n\nThe PWA supports a specialized **Embed Mode** to allow its charts and analysis features to be reused as interactive components within other sites (like the marketing website).\n\n### Implementation\n\n- **URL Parameter**: `?embed=true` hides the PWA header, footer, and navigation.\n- **Sample Data**: `?sample=\u003Ckey>` auto-loads a specific dataset for the context.\n- **Security**: Content Security Policy (CSP) should allow framing from `variscout.com`.\n\n### Usage in Marketing Website\n\nThe marketing site uses React Islands with pre-computed data from `@variscout/data` to showcase interactive charts on case study and tool pages. This ensures fast page loads while maintaining interactivity.\n\n**Implementation**: Chart islands import directly from `@variscout/charts` and render with Astro's `client:only=\"react\"` directive.\n\n**Next Step**: Initialize `packages/ui` when you are ready to align the PWA and Azure App designs.", + "src/content/docs/05-technical/integrations/shared-ui.md", + "93b2d82cbf02b5f1", + { "html": 9142, "metadata": 9143 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"shared-ui-library-strategy\">Shared UI Library Strategy\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#shared-ui-library-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Shared UI Library Strategy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>[!NOTE]\n\u003Cstrong>Status\u003C/strong>: Implemented (Jan 2026)\n\u003Cstrong>Package\u003C/strong>: \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/p>\n\u003C/blockquote>\n\u003Cp>This document outlines the architectural strategy for implementing a Shared UI Library within the VariScout monorepo.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"1-current-state-assessment\">1. Current State Assessment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#1-current-state-assessment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Current State Assessment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Existing Shared Packages\u003C/strong>: \u003Ccode dir=\"auto\">packages/core\u003C/code> (logic), \u003Ccode dir=\"auto\">packages/charts\u003C/code> (visualization).\u003C/li>\n\u003Cli>\u003Cstrong>Missing\u003C/strong>: No shared UI component library.\u003C/li>\n\u003Cli>\u003Cstrong>PWA (\u003Ccode dir=\"auto\">apps/pwa\u003C/code>)\u003C/strong> & \u003Cstrong>Azure App (\u003Ccode dir=\"auto\">apps/azure\u003C/code>)\u003C/strong>: Use \u003Cstrong>Tailwind CSS\u003C/strong> + Headless components (e.g., Radix, Lucide icons) for a custom, modern web aesthetic.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"2-architectural-recommendation\">2. Architectural Recommendation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#2-architectural-recommendation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Architectural Recommendation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Would a shared UI library make sense? \u003Cstrong>YES\u003C/strong>, but with a split strategy.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-web-ui-kit-variscoutui\">The “Web” UI Kit (\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-web-ui-kit-variscoutui\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The “Web” UI Kit (@variscout/ui)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A shared UI package for the \u003Cstrong>PWA\u003C/strong> and \u003Cstrong>Azure App\u003C/strong> (and any future web portals). Since they share a tech stack (Tailwind), they share components.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Goal\u003C/strong>: Ensure \u003Ccode dir=\"auto\">apps/azure\u003C/code> and \u003Ccode dir=\"auto\">apps/pwa\u003C/code> look identical and share the same buttons, inputs, cards, and layouts.\u003C/li>\n\u003Cli>\u003Cstrong>Contents\u003C/strong>: Buttons, Forms, Modals, Layouts (Sidebar/Header), Typography.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"3-implementation-plan\">3. Implementation Plan\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#3-implementation-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Implementation Plan”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"31-create-variscoutui\">3.1 Create \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#31-create-variscoutui\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3.1 Create @variscout/ui”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Location\u003C/strong>: \u003Ccode dir=\"auto\">packages/ui\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Dependencies\u003C/strong>: \u003Ccode dir=\"auto\">react\u003C/code>, \u003Ccode dir=\"auto\">react-dom\u003C/code>, \u003Ccode dir=\"auto\">tailwindcss\u003C/code>, \u003Ccode dir=\"auto\">lucide-react\u003C/code>, \u003Ccode dir=\"auto\">class-variance-authority\u003C/code> (helper for component variants).\u003C/li>\n\u003Cli>\u003Cstrong>Build Tool\u003C/strong>: Vite (Library Mode) or tsup.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"32-shared-tailwind-configuration\">3.2 Shared Tailwind Configuration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#32-shared-tailwind-configuration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3.2 Shared Tailwind Configuration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>To ensure colors and fonts are consistent, move the Tailwind config to a shared preset.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Location\u003C/strong>: \u003Ccode dir=\"auto\">packages/ui/tailwind.config.js\u003C/code> (or a specific configuration package like \u003Ccode dir=\"auto\">packages/config-tailwind\u003C/code>).\u003C/li>\n\u003Cli>\u003Cstrong>Usage\u003C/strong>: In apps, \u003Ccode dir=\"auto\">import sharedConfig from '@variscout/ui/tailwind.config';\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"33-component-development-storybook\">3.3 Component Development (Storybook)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#33-component-development-storybook\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3.3 Component Development (Storybook)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Develop components in isolation using \u003Cstrong>Storybook\u003C/strong>. This forces components to be pure and decoupled from app-specific state.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-best-practices\">4. Best Practices\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-best-practices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Best Practices”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Headless Approach\u003C/strong>: For complex interactive components (Tabs, Dropdowns), use a “Headless” library (e.g., Radix UI or Headless UI) in the shared package and style it with Tailwind. This provides accessibility out of the box.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Export Pattern\u003C/strong>: Use “Barrel files” (\u003Ccode dir=\"auto\">index.ts\u003C/code>) carefully.\u003C/p>\n\u003Cul>\n\u003Cli>Good: \u003Ccode dir=\"auto\">export * from './Button';\u003C/code>\u003C/li>\n\u003Cli>Ensure tree-shaking works so apps don’t bundle unused components.\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Versioning\u003C/strong>: Since this is a monorepo, we typically version packages together or use “workspace:*” protocols.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Styles\u003C/strong>: Ship the CCS with the package or ensuring the consuming app processes the convenient utility classes.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cem>Recommended\u003C/em>: Add the package source paths to the consuming app’s \u003Ccode dir=\"auto\">tailwind.config.js\u003C/code> \u003Ccode dir=\"auto\">content\u003C/code> array. This allows the app to generate only the CSS needed.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">apps/pwa/tailwind.config.js\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"javascript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">default\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">content: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./index.html\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./src/**/*.{js,ts,jsx,tsx}\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">../../packages/ui/src/**/*.{js,ts,jsx,tsx}\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// <-- Scan shared UI\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export default { content: [ './index.html', './src/**/*.{js,ts,jsx,tsx}', '../../packages/ui/src/**/*.{js,ts,jsx,tsx}', // \u003C-- Scan shared UI ], // ...};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"5-summary-recommendation\">5. Summary Recommendation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#5-summary-recommendation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Summary Recommendation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth align=\"left\">App\u003C/th>\u003Cth align=\"left\">UI Strategy\u003C/th>\u003Cth align=\"left\">Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>PWA\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Custom (Tailwind)\u003C/td>\u003Ctd align=\"left\">Consume \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Azure App\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Custom (Tailwind)\u003C/td>\u003Ctd align=\"left\">Consume \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd align=\"left\">\u003Cstrong>Marketing\u003C/strong>\u003C/td>\u003Ctd align=\"left\">Astro (Tailwind)\u003C/td>\u003Ctd align=\"left\">SSG for performance, embeds PWA for interactive case studies\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"6-cross-app-embedding-iframe-strategy\">6. Cross-App Embedding (iframe strategy)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#6-cross-app-embedding-iframe-strategy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Cross-App Embedding (iframe strategy)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA supports a specialized \u003Cstrong>Embed Mode\u003C/strong> to allow its charts and analysis features to be reused as interactive components within other sites (like the marketing website).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"implementation\">Implementation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>URL Parameter\u003C/strong>: \u003Ccode dir=\"auto\">?embed=true\u003C/code> hides the PWA header, footer, and navigation.\u003C/li>\n\u003Cli>\u003Cstrong>Sample Data\u003C/strong>: \u003Ccode dir=\"auto\">?sample=<key>\u003C/code> auto-loads a specific dataset for the context.\u003C/li>\n\u003Cli>\u003Cstrong>Security\u003C/strong>: Content Security Policy (CSP) should allow framing from \u003Ccode dir=\"auto\">variscout.com\u003C/code>.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-in-marketing-website\">Usage in Marketing Website\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-in-marketing-website\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage in Marketing Website”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The marketing site uses React Islands with pre-computed data from \u003Ccode dir=\"auto\">@variscout/data\u003C/code> to showcase interactive charts on case study and tool pages. This ensures fast page loads while maintaining interactivity.\u003C/p>\n\u003Cp>\u003Cstrong>Implementation\u003C/strong>: Chart islands import directly from \u003Ccode dir=\"auto\">@variscout/charts\u003C/code> and render with Astro’s \u003Ccode dir=\"auto\">client:only=\"react\"\u003C/code> directive.\u003C/p>\n\u003Cp>\u003Cstrong>Next Step\u003C/strong>: Initialize \u003Ccode dir=\"auto\">packages/ui\u003C/code> when you are ready to align the PWA and Azure App designs.\u003C/p>", + { + "headings": 9144, + "localImagePaths": 9181, + "remoteImagePaths": 9182, + "frontmatter": 9183, + "imagePaths": 9184 + }, + [9145, 9147, 9150, 9153, 9156, 9159, 9162, 9165, 9168, 9171, 9174, 9177, 9178], + { "depth": 30, "slug": 9146, "text": 9134 }, + "shared-ui-library-strategy", + { "depth": 33, "slug": 9148, "text": 9149 }, + "1-current-state-assessment", + "1. Current State Assessment", + { "depth": 33, "slug": 9151, "text": 9152 }, + "2-architectural-recommendation", + "2. Architectural Recommendation", + { "depth": 79, "slug": 9154, "text": 9155 }, + "the-web-ui-kit-variscoutui", + "The “Web” UI Kit (@variscout/ui)", + { "depth": 33, "slug": 9157, "text": 9158 }, + "3-implementation-plan", + "3. Implementation Plan", + { "depth": 79, "slug": 9160, "text": 9161 }, + "31-create-variscoutui", + "3.1 Create @variscout/ui", + { "depth": 79, "slug": 9163, "text": 9164 }, + "32-shared-tailwind-configuration", + "3.2 Shared Tailwind Configuration", + { "depth": 79, "slug": 9166, "text": 9167 }, + "33-component-development-storybook", + "3.3 Component Development (Storybook)", + { "depth": 33, "slug": 9169, "text": 9170 }, + "4-best-practices", + "4. Best Practices", + { "depth": 33, "slug": 9172, "text": 9173 }, + "5-summary-recommendation", + "5. Summary Recommendation", + { "depth": 33, "slug": 9175, "text": 9176 }, + "6-cross-app-embedding-iframe-strategy", + "6. Cross-App Embedding (iframe strategy)", + { "depth": 79, "slug": 1885, "text": 1886 }, + { "depth": 79, "slug": 9179, "text": 9180 }, + "usage-in-marketing-website", + "Usage in Marketing Website", + [], + [], + { "title": 9134 }, + [], + "04-cases/avocado", + { "id": 9185, "data": 9187, "body": 9192, "filePath": 9193, "digest": 9194, "rendered": 9195 }, + { + "title": 9188, + "editUrl": 16, + "head": 9189, + "template": 18, + "sidebar": 9190, + "pagefind": 16, + "draft": 20 + }, + "Avocado Coating Case", + [], + { "hidden": 20, "attrs": 9191 }, + {}, + "# Avocado Coating Case\n\n**Location:** Post-harvest processing facility\n**Context:** Process parameter optimization, agricultural quality\n**Campaign Week:** 12 (Phase 3 - AI Comparison)\n**Website:** /cases/avocado\n\n---\n\n## Overview\n\nA research-based case demonstrating regression analysis for process optimization.\n\n**Analysis module:** Regression Analysis — Coating amount vs. shelf life and weight loss\n\n---\n\n## The Story\n\n### Part 1: \"Finding the Optimal Coating Level\"\n\n**The setup:**\nAvocados are coated with wax to extend shelf life and reduce moisture loss. More coating should help... but does it? And is there an optimal level?\n\n**The analysis:**\nRegression shows a clear positive relationship between coating amount and shelf life (R² ~ 0.72). But at higher coating levels, returns diminish and over-coating risks emerge.\n\n**The insights:**\n\n- Coating amount explains ~72% of shelf life variation\n- Optimal range appears to be 1.5-2.5 ml/kg\n- Dip method gives +1.5 days vs. Spray method\n- Carnauba has lower optimal point than Polyethylene\n\n---\n\n## Teaching Points\n\n| Concept | What VaRiScout Shows |\n| ---------------------- | -------------------------------------------------------- |\n| Basic regression | Slope interpretation: each ml/kg adds ~3 days shelf life |\n| R² interpretation | 72% of variation explained by coating amount |\n| Prediction | At 1.5 ml/kg, expect ~14 days shelf life |\n| Categorical predictors | Process (Spray/Dip) and Material as factors |\n| Trade-off analysis | Shelf life vs. weight loss optimization |\n\n---\n\n## Datasets\n\n### 1. Coating Regression Data (`coating-regression.csv`)\n\n| Column | Type | Description |\n| --------------- | ------- | -------------------------------- |\n| Sample_ID | Integer | 1-120 |\n| Coating_ml_kg | Float | Coating amount (0.5 - 3.0 ml/kg) |\n| Process | Factor | Spray, Dip |\n| Material | Factor | Carnauba, Polyethylene |\n| Shelf_Life_Days | Float | Days to unacceptable quality |\n| Weight_Loss_Pct | Float | Percentage weight loss at day 14 |\n\n**Study design:**\n\n- 4 combinations × 6 coating levels × 5 replicates = 120 observations\n- Linear relationship: ~3-4 days per ml/kg increase\n- Plateau/decline above 2.5 ml/kg (over-coating effect)\n\n**Built-in patterns:**\n\n- Dip method: +1.5 days vs. Spray\n- Carnauba: Better weight retention, lower optimal point\n- Polyethylene: Longer shelf life, higher optimal point\n\n---\n\n## Industry Context\n\n### How Coating is Applied\n\n**Standard application rate:** ~0.4 ml wax per 250g fruit (~1.6 ml/kg)\n\n**Application methods:**\n\n1. **Spray:** Traversing nozzle, horse-hair brushes to spread\n2. **Dip:** Full submersion, more even coverage, uses more wax\n3. **Manual:** Small operations, higher variation\n\n### Coating Effects (Research-Based)\n\n| Outcome | Effect of Coating | Evidence |\n| --------------------- | ------------------------- | --------------------------- |\n| Weight loss reduction | 30-58% vs. uncoated | Aguirre et al., 2017 |\n| Shelf life extension | +8-21 days (refrigerated) | Multiple studies |\n| Firmness retention | Up to 50% better | Aguilar-Mendez et al., 2008 |\n\n### Over-Coating Risks\n\n| Issue | Cause | Symptom |\n| ------------- | ------------------------------- | ------------------- |\n| Off-flavors | Blocked gas exchange | Fermentation |\n| Wax whitening | Excessive coating + temp change | White deposits |\n| Anaerobiosis | Too thick barrier | Quality degradation |\n\n**Key finding:** Optimal coating exists — more is NOT always better.\n\n---\n\n## Key Visuals\n\n1. **Scatter Plot** - Coating amount vs. shelf life with regression line\n2. **Multiple Regression Lines** - By Process (Spray vs. Dip)\n3. **Residual Plot** - Checking regression assumptions\n\n---\n\n## VaRiScout Demo Flow\n\n### Module 1: Regression Analysis\n\n1. Load `coating-regression.csv`\n2. Create scatter plot: Coating_ml_kg (X) vs. Shelf_Life_Days (Y)\n3. Fit regression line\n4. View R² (~0.72) and equation\n5. Add Process as factor → see two parallel lines\n6. Identify optimal range: 1.5-2.5 ml/kg\n\n---\n\n## The Key Insight\n\n**Regression finding:** Coating amount strongly predicts shelf life (R² = 0.72), but 28% remains unexplained — factors like application method, environmental conditions, and fruit variability all contribute.\n\n**Business decision:** Standardize application technique and control environmental factors, then re-run regression for tighter predictions.\n\n---\n\n## Core Message\n\n_\"The equation is easy. The insight is in the pattern.\"_\n\n---\n\n## AI Comparison (Week 12)\n\nThis case is featured in the AI comparison video:\n\n| Tool | What It Does | What It Misses |\n| ------------- | ----------------------------------- | ------------------------------------------------------ |\n| Copilot | Calculates regression equation | May not suggest checking assumptions |\n| Analyst Agent | Fits model, provides interpretation | May miss non-linearity at high coating |\n| VaRiScout | Shows relationship visually | Clicking outliers → \"What's special about this point?\" |\n\n**The visual advantage:**\n\n- See if relationship is actually linear\n- Identify outliers affecting the fit\n- Filter by factor: \"Does relationship hold for all groups?\"\n\n---\n\n## References\n\n- Aguirre-Joya, J.A. et al. (2017). Effects of coating on avocado quality. _Food Packaging and Shelf Life_\n- Blakey, R.J. (2012). Avocado post-harvest operations. University of KwaZulu-Natal.\n- Maftoonazad, N. & Ramaswamy, H.S. (2005). Postharvest shelf-life extension of avocados. _LWT_\n- Tesfay, S.Z. et al. (2017). Carboxymethyl cellulose coating. _South African Journal of Botany_\n\n---\n\n_Case developed for VaRiScout Lite demonstration_\n_Target audience: Lean Six Sigma Green Belt trainees_", + "src/content/docs/04-cases/avocado/index.md", + "8253c4e5f7fdc146", + { "html": 9196, "metadata": 9197 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"avocado-coating-case\">Avocado Coating Case\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#avocado-coating-case\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Avocado Coating Case”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Location:\u003C/strong> Post-harvest processing facility\n\u003Cstrong>Context:\u003C/strong> Process parameter optimization, agricultural quality\n\u003Cstrong>Campaign Week:\u003C/strong> 12 (Phase 3 - AI Comparison)\n\u003Cstrong>Website:\u003C/strong> /cases/avocado\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A research-based case demonstrating regression analysis for process optimization.\u003C/p>\n\u003Cp>\u003Cstrong>Analysis module:\u003C/strong> Regression Analysis — Coating amount vs. shelf life and weight loss\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-story\">The Story\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-story\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Story”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"part-1-finding-the-optimal-coating-level\">Part 1: “Finding the Optimal Coating Level”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#part-1-finding-the-optimal-coating-level\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 1: “Finding the Optimal Coating Level””\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>The setup:\u003C/strong>\nAvocados are coated with wax to extend shelf life and reduce moisture loss. More coating should help… but does it? And is there an optimal level?\u003C/p>\n\u003Cp>\u003Cstrong>The analysis:\u003C/strong>\nRegression shows a clear positive relationship between coating amount and shelf life (R² ~ 0.72). But at higher coating levels, returns diminish and over-coating risks emerge.\u003C/p>\n\u003Cp>\u003Cstrong>The insights:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Coating amount explains ~72% of shelf life variation\u003C/li>\n\u003Cli>Optimal range appears to be 1.5-2.5 ml/kg\u003C/li>\n\u003Cli>Dip method gives +1.5 days vs. Spray method\u003C/li>\n\u003Cli>Carnauba has lower optimal point than Polyethylene\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teaching-points\">Teaching Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teaching-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teaching Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Concept\u003C/th>\u003Cth>What VaRiScout Shows\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Basic regression\u003C/td>\u003Ctd>Slope interpretation: each ml/kg adds ~3 days shelf life\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>R² interpretation\u003C/td>\u003Ctd>72% of variation explained by coating amount\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Prediction\u003C/td>\u003Ctd>At 1.5 ml/kg, expect ~14 days shelf life\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Categorical predictors\u003C/td>\u003Ctd>Process (Spray/Dip) and Material as factors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trade-off analysis\u003C/td>\u003Ctd>Shelf life vs. weight loss optimization\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"datasets\">Datasets\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#datasets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Datasets”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-coating-regression-data-coating-regressioncsv\">1. Coating Regression Data (\u003Ccode dir=\"auto\">coating-regression.csv\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-coating-regression-data-coating-regressioncsv\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Coating Regression Data (coating-regression.csv)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Column\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Sample_ID\u003C/td>\u003Ctd>Integer\u003C/td>\u003Ctd>1-120\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Coating_ml_kg\u003C/td>\u003Ctd>Float\u003C/td>\u003Ctd>Coating amount (0.5 - 3.0 ml/kg)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Process\u003C/td>\u003Ctd>Factor\u003C/td>\u003Ctd>Spray, Dip\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Material\u003C/td>\u003Ctd>Factor\u003C/td>\u003Ctd>Carnauba, Polyethylene\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shelf_Life_Days\u003C/td>\u003Ctd>Float\u003C/td>\u003Ctd>Days to unacceptable quality\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Weight_Loss_Pct\u003C/td>\u003Ctd>Float\u003C/td>\u003Ctd>Percentage weight loss at day 14\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Study design:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>4 combinations × 6 coating levels × 5 replicates = 120 observations\u003C/li>\n\u003Cli>Linear relationship: ~3-4 days per ml/kg increase\u003C/li>\n\u003Cli>Plateau/decline above 2.5 ml/kg (over-coating effect)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Built-in patterns:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Dip method: +1.5 days vs. Spray\u003C/li>\n\u003Cli>Carnauba: Better weight retention, lower optimal point\u003C/li>\n\u003Cli>Polyethylene: Longer shelf life, higher optimal point\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"industry-context\">Industry Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#industry-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Industry Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"how-coating-is-applied\">How Coating is Applied\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#how-coating-is-applied\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How Coating is Applied”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Standard application rate:\u003C/strong> ~0.4 ml wax per 250g fruit (~1.6 ml/kg)\u003C/p>\n\u003Cp>\u003Cstrong>Application methods:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Spray:\u003C/strong> Traversing nozzle, horse-hair brushes to spread\u003C/li>\n\u003Cli>\u003Cstrong>Dip:\u003C/strong> Full submersion, more even coverage, uses more wax\u003C/li>\n\u003Cli>\u003Cstrong>Manual:\u003C/strong> Small operations, higher variation\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"coating-effects-research-based\">Coating Effects (Research-Based)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#coating-effects-research-based\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Coating Effects (Research-Based)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Outcome\u003C/th>\u003Cth>Effect of Coating\u003C/th>\u003Cth>Evidence\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Weight loss reduction\u003C/td>\u003Ctd>30-58% vs. uncoated\u003C/td>\u003Ctd>Aguirre et al., 2017\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shelf life extension\u003C/td>\u003Ctd>+8-21 days (refrigerated)\u003C/td>\u003Ctd>Multiple studies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Firmness retention\u003C/td>\u003Ctd>Up to 50% better\u003C/td>\u003Ctd>Aguilar-Mendez et al., 2008\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"over-coating-risks\">Over-Coating Risks\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#over-coating-risks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Over-Coating Risks”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Issue\u003C/th>\u003Cth>Cause\u003C/th>\u003Cth>Symptom\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Off-flavors\u003C/td>\u003Ctd>Blocked gas exchange\u003C/td>\u003Ctd>Fermentation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Wax whitening\u003C/td>\u003Ctd>Excessive coating + temp change\u003C/td>\u003Ctd>White deposits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Anaerobiosis\u003C/td>\u003Ctd>Too thick barrier\u003C/td>\u003Ctd>Quality degradation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key finding:\u003C/strong> Optimal coating exists — more is NOT always better.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-visuals\">Key Visuals\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-visuals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Visuals”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Scatter Plot\u003C/strong> - Coating amount vs. shelf life with regression line\u003C/li>\n\u003Cli>\u003Cstrong>Multiple Regression Lines\u003C/strong> - By Process (Spray vs. Dip)\u003C/li>\n\u003Cli>\u003Cstrong>Residual Plot\u003C/strong> - Checking regression assumptions\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-demo-flow\">VaRiScout Demo Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-demo-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VaRiScout Demo Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"module-1-regression-analysis\">Module 1: Regression Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#module-1-regression-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Module 1: Regression Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Load \u003Ccode dir=\"auto\">coating-regression.csv\u003C/code>\u003C/li>\n\u003Cli>Create scatter plot: Coating_ml_kg (X) vs. Shelf_Life_Days (Y)\u003C/li>\n\u003Cli>Fit regression line\u003C/li>\n\u003Cli>View R² (~0.72) and equation\u003C/li>\n\u003Cli>Add Process as factor → see two parallel lines\u003C/li>\n\u003Cli>Identify optimal range: 1.5-2.5 ml/kg\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-key-insight\">The Key Insight\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-key-insight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Key Insight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Regression finding:\u003C/strong> Coating amount strongly predicts shelf life (R² = 0.72), but 28% remains unexplained — factors like application method, environmental conditions, and fruit variability all contribute.\u003C/p>\n\u003Cp>\u003Cstrong>Business decision:\u003C/strong> Standardize application technique and control environmental factors, then re-run regression for tighter predictions.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-message\">Core Message\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-message\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Message”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“The equation is easy. The insight is in the pattern.”\u003C/em>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ai-comparison-week-12\">AI Comparison (Week 12)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ai-comparison-week-12\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “AI Comparison (Week 12)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This case is featured in the AI comparison video:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tool\u003C/th>\u003Cth>What It Does\u003C/th>\u003Cth>What It Misses\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Copilot\u003C/td>\u003Ctd>Calculates regression equation\u003C/td>\u003Ctd>May not suggest checking assumptions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analyst Agent\u003C/td>\u003Ctd>Fits model, provides interpretation\u003C/td>\u003Ctd>May miss non-linearity at high coating\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>VaRiScout\u003C/td>\u003Ctd>Shows relationship visually\u003C/td>\u003Ctd>Clicking outliers → “What’s special about this point?”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>The visual advantage:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>See if relationship is actually linear\u003C/li>\n\u003Cli>Identify outliers affecting the fit\u003C/li>\n\u003Cli>Filter by factor: “Does relationship hold for all groups?”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"references\">References\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Aguirre-Joya, J.A. et al. (2017). Effects of coating on avocado quality. \u003Cem>Food Packaging and Shelf Life\u003C/em>\u003C/li>\n\u003Cli>Blakey, R.J. (2012). Avocado post-harvest operations. University of KwaZulu-Natal.\u003C/li>\n\u003Cli>Maftoonazad, N. & Ramaswamy, H.S. (2005). Postharvest shelf-life extension of avocados. \u003Cem>LWT\u003C/em>\u003C/li>\n\u003Cli>Tesfay, S.Z. et al. (2017). Carboxymethyl cellulose coating. \u003Cem>South African Journal of Botany\u003C/em>\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cem>Case developed for VaRiScout Lite demonstration\u003C/em>\n\u003Cem>Target audience: Lean Six Sigma Green Belt trainees\u003C/em>\u003C/p>", + { + "headings": 9198, + "localImagePaths": 9246, + "remoteImagePaths": 9247, + "frontmatter": 9248, + "imagePaths": 9249 + }, + [ + 9199, 9201, 9202, 9205, 9208, 9211, 9214, 9217, 9220, 9223, 9226, 9229, 9232, 9235, 9238, 9239, + 9242, 9245 + ], + { "depth": 30, "slug": 9200, "text": 9188 }, + "avocado-coating-case", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 9203, "text": 9204 }, + "the-story", + "The Story", + { "depth": 79, "slug": 9206, "text": 9207 }, + "part-1-finding-the-optimal-coating-level", + "Part 1: “Finding the Optimal Coating Level”", + { "depth": 33, "slug": 9209, "text": 9210 }, + "teaching-points", + "Teaching Points", + { "depth": 33, "slug": 9212, "text": 9213 }, + "datasets", + "Datasets", + { "depth": 79, "slug": 9215, "text": 9216 }, + "1-coating-regression-data-coating-regressioncsv", + "1. Coating Regression Data (coating-regression.csv)", + { "depth": 33, "slug": 9218, "text": 9219 }, + "industry-context", + "Industry Context", + { "depth": 79, "slug": 9221, "text": 9222 }, + "how-coating-is-applied", + "How Coating is Applied", + { "depth": 79, "slug": 9224, "text": 9225 }, + "coating-effects-research-based", + "Coating Effects (Research-Based)", + { "depth": 79, "slug": 9227, "text": 9228 }, + "over-coating-risks", + "Over-Coating Risks", + { "depth": 33, "slug": 9230, "text": 9231 }, + "key-visuals", + "Key Visuals", + { "depth": 33, "slug": 9233, "text": 9234 }, + "variscout-demo-flow", + "VaRiScout Demo Flow", + { "depth": 79, "slug": 9236, "text": 9237 }, + "module-1-regression-analysis", + "Module 1: Regression Analysis", + { "depth": 33, "slug": 754, "text": 755 }, + { "depth": 33, "slug": 9240, "text": 9241 }, + "core-message", + "Core Message", + { "depth": 33, "slug": 9243, "text": 9244 }, + "ai-comparison-week-12", + "AI Comparison (Week 12)", + { "depth": 33, "slug": 878, "text": 879 }, + [], + [], + { "title": 9188 }, + [], + "04-cases/coffee", + { "id": 9250, "data": 9252, "body": 9257, "filePath": 9258, "digest": 9259, "rendered": 9260 }, + { + "title": 9253, + "editUrl": 16, + "head": 9254, + "template": 18, + "sidebar": 9255, + "pagefind": 16, + "draft": 20 + }, + "Coffee Washing Station Case", + [], + { "hidden": 20, "attrs": 9256 }, + {}, + "# Coffee Washing Station Case\n\n**Location:** East African coffee washing station\n**Context:** Export quality control, agricultural processing\n**Campaign Week:** 9 (Phase 3 - Africa)\n**Website:** /cases/coffee\n\n---\n\n## Overview\n\nA practical case demonstrating variation analysis with both continuous measurements and defect classification.\n\n**Analysis module:** Moisture Analysis — Process variation by drying bed\n\n---\n\n## The Story\n\n### Part 1: \"Why Does Bed C Keep Failing Export Spec?\"\n\n**The setup:**\nA coffee washing station has three drying beds (A, B, C). Export grade requires 10-12% moisture content. Quality reports show \"some batches fail spec\" but don't reveal the pattern.\n\n**The reveal:**\nVaRiScout instantly shows Bed C is the problem - consistently running 12-14% moisture while A and B are stable within spec. The Pareto chart shows Bed C also has higher defect counts.\n\n**The insight:**\nBefore VaRiScout: \"We have a moisture problem\"\nAfter VaRiScout: \"Bed C has a moisture problem - check airflow, shade, or drainage\"\n\n---\n\n## Teaching Points\n\n| Concept | What VaRiScout Shows |\n| ---------------------- | ---------------------------------------------------------------- |\n| Factor comparison | Boxplot instantly reveals Bed C is different |\n| Spec limits in context | I-Chart shows _where_ failures occur, not just _that_ they occur |\n| Two data types | Continuous (moisture %) + Categorical (defect counts) |\n| Root cause direction | Variation pattern points to equipment/location, not operator |\n\n---\n\n## Datasets\n\n### 1. Washing Station Data (`washing-station.csv`)\n\n| Column | Type | Description |\n| ------------- | ---------- | ------------------------------------ |\n| Batch_ID | ID | 1-30 |\n| Drying_Bed | Factor | A, B, C (10 each) |\n| Moisture_pct | Continuous | Target 10-12%, Bed C runs 12.4-14.1% |\n| Full_Black | Count | Rare defect (0-2) |\n| Insect_Damage | Count | Low frequency (0-3) |\n| Floater | Count | Moderate (0-5) |\n| Broken | Count | Most common (2-9) |\n\n**Built-in patterns:**\n\n- Bed A: Mean ~11.0%, all in spec\n- Bed B: Mean ~11.4%, all in spec\n- Bed C: Mean ~13.2%, all OUT of spec\n- Defect counts correlate with moisture (Bed C higher)\n\n---\n\n## Key Visuals\n\n1. **I-Chart** - Moisture % over batches with spec lines (10-12%)\n2. **Boxplot** - Moisture % by Drying Bed (A, B, C) - the \"aha\" moment\n3. **Pareto** - Defect counts showing Broken >> Floater >> Insect >> Full Black\n4. **Linked filtering** - Click Bed C, see its defect profile vs others\n\n---\n\n## Industry Context\n\n### How Coffee Moisture is Measured\n\n**Capacitance moisture meters** are the industry standard:\n\n- Common brands: Sinar, Lighttells MD-500, G-Won, Wile\n- Cost: ~$300-500 for quality meters\n- Used at washing stations, dry mills, and roasteries worldwide\n- Published tolerance: ±0.5% moisture\n\n## VaRiScout Demo Flow\n\n### Module 1: Process Analysis\n\n1. Load `washing-station.csv`\n2. Create I-Chart with Moisture_pct, spec lines at 10-12%\n3. Create Boxplot by Drying_Bed\n4. Click Bed C → see instant filtering\n5. Create Pareto of defect types\n\n---\n\n## Core Message\n\n_\"The variation pattern tells you where to look.\"_\n\n---\n\n## References\n\n- ISO 6673: Green coffee — Determination of loss in mass at 105°C\n- ISO 1447: Green coffee — Determination of moisture content\n- Sucafina: \"Consistency in Measuring Moisture Content\"\n- Perfect Daily Grind: \"How to Measure Moisture in Parchment & Green Coffee Beans\"\n\n---\n\n_Case developed for VaRiScout Lite demonstration_\n_Target audience: Lean Six Sigma Green Belt trainees_", + "src/content/docs/04-cases/coffee/index.md", + "34427810f596f45e", + { "html": 9261, "metadata": 9262 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"coffee-washing-station-case\">Coffee Washing Station Case\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#coffee-washing-station-case\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Coffee Washing Station Case”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Location:\u003C/strong> East African coffee washing station\n\u003Cstrong>Context:\u003C/strong> Export quality control, agricultural processing\n\u003Cstrong>Campaign Week:\u003C/strong> 9 (Phase 3 - Africa)\n\u003Cstrong>Website:\u003C/strong> /cases/coffee\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A practical case demonstrating variation analysis with both continuous measurements and defect classification.\u003C/p>\n\u003Cp>\u003Cstrong>Analysis module:\u003C/strong> Moisture Analysis — Process variation by drying bed\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-story\">The Story\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-story\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Story”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"part-1-why-does-bed-c-keep-failing-export-spec\">Part 1: “Why Does Bed C Keep Failing Export Spec?”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#part-1-why-does-bed-c-keep-failing-export-spec\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 1: “Why Does Bed C Keep Failing Export Spec?””\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>The setup:\u003C/strong>\nA coffee washing station has three drying beds (A, B, C). Export grade requires 10-12% moisture content. Quality reports show “some batches fail spec” but don’t reveal the pattern.\u003C/p>\n\u003Cp>\u003Cstrong>The reveal:\u003C/strong>\nVaRiScout instantly shows Bed C is the problem - consistently running 12-14% moisture while A and B are stable within spec. The Pareto chart shows Bed C also has higher defect counts.\u003C/p>\n\u003Cp>\u003Cstrong>The insight:\u003C/strong>\nBefore VaRiScout: “We have a moisture problem”\nAfter VaRiScout: “Bed C has a moisture problem - check airflow, shade, or drainage”\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teaching-points\">Teaching Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teaching-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teaching Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Concept\u003C/th>\u003Cth>What VaRiScout Shows\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Factor comparison\u003C/td>\u003Ctd>Boxplot instantly reveals Bed C is different\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Spec limits in context\u003C/td>\u003Ctd>I-Chart shows \u003Cem>where\u003C/em> failures occur, not just \u003Cem>that\u003C/em> they occur\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Two data types\u003C/td>\u003Ctd>Continuous (moisture %) + Categorical (defect counts)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Root cause direction\u003C/td>\u003Ctd>Variation pattern points to equipment/location, not operator\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"datasets\">Datasets\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#datasets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Datasets”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-washing-station-data-washing-stationcsv\">1. Washing Station Data (\u003Ccode dir=\"auto\">washing-station.csv\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-washing-station-data-washing-stationcsv\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Washing Station Data (washing-station.csv)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Column\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Batch_ID\u003C/td>\u003Ctd>ID\u003C/td>\u003Ctd>1-30\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Drying_Bed\u003C/td>\u003Ctd>Factor\u003C/td>\u003Ctd>A, B, C (10 each)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Moisture_pct\u003C/td>\u003Ctd>Continuous\u003C/td>\u003Ctd>Target 10-12%, Bed C runs 12.4-14.1%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Full_Black\u003C/td>\u003Ctd>Count\u003C/td>\u003Ctd>Rare defect (0-2)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Insect_Damage\u003C/td>\u003Ctd>Count\u003C/td>\u003Ctd>Low frequency (0-3)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Floater\u003C/td>\u003Ctd>Count\u003C/td>\u003Ctd>Moderate (0-5)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Broken\u003C/td>\u003Ctd>Count\u003C/td>\u003Ctd>Most common (2-9)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Built-in patterns:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Bed A: Mean ~11.0%, all in spec\u003C/li>\n\u003Cli>Bed B: Mean ~11.4%, all in spec\u003C/li>\n\u003Cli>Bed C: Mean ~13.2%, all OUT of spec\u003C/li>\n\u003Cli>Defect counts correlate with moisture (Bed C higher)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-visuals\">Key Visuals\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-visuals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Visuals”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> - Moisture % over batches with spec lines (10-12%)\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong> - Moisture % by Drying Bed (A, B, C) - the “aha” moment\u003C/li>\n\u003Cli>\u003Cstrong>Pareto\u003C/strong> - Defect counts showing Broken >> Floater >> Insect >> Full Black\u003C/li>\n\u003Cli>\u003Cstrong>Linked filtering\u003C/strong> - Click Bed C, see its defect profile vs others\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"industry-context\">Industry Context\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#industry-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Industry Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"how-coffee-moisture-is-measured\">How Coffee Moisture is Measured\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#how-coffee-moisture-is-measured\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How Coffee Moisture is Measured”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Capacitance moisture meters\u003C/strong> are the industry standard:\u003C/p>\n\u003Cul>\n\u003Cli>Common brands: Sinar, Lighttells MD-500, G-Won, Wile\u003C/li>\n\u003Cli>Cost: ~$300-500 for quality meters\u003C/li>\n\u003Cli>Used at washing stations, dry mills, and roasteries worldwide\u003C/li>\n\u003Cli>Published tolerance: ±0.5% moisture\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-demo-flow\">VaRiScout Demo Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-demo-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VaRiScout Demo Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"module-1-process-analysis\">Module 1: Process Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#module-1-process-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Module 1: Process Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Load \u003Ccode dir=\"auto\">washing-station.csv\u003C/code>\u003C/li>\n\u003Cli>Create I-Chart with Moisture_pct, spec lines at 10-12%\u003C/li>\n\u003Cli>Create Boxplot by Drying_Bed\u003C/li>\n\u003Cli>Click Bed C → see instant filtering\u003C/li>\n\u003Cli>Create Pareto of defect types\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-message\">Core Message\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-message\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Message”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“The variation pattern tells you where to look.”\u003C/em>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"references\">References\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#references\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “References”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>ISO 6673: Green coffee — Determination of loss in mass at 105°C\u003C/li>\n\u003Cli>ISO 1447: Green coffee — Determination of moisture content\u003C/li>\n\u003Cli>Sucafina: “Consistency in Measuring Moisture Content”\u003C/li>\n\u003Cli>Perfect Daily Grind: “How to Measure Moisture in Parchment & Green Coffee Beans”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cem>Case developed for VaRiScout Lite demonstration\u003C/em>\n\u003Cem>Target audience: Lean Six Sigma Green Belt trainees\u003C/em>\u003C/p>", + { + "headings": 9263, + "localImagePaths": 9287, + "remoteImagePaths": 9288, + "frontmatter": 9289, + "imagePaths": 9290 + }, + [9264, 9266, 9267, 9268, 9271, 9272, 9273, 9276, 9277, 9278, 9281, 9282, 9285, 9286], + { "depth": 30, "slug": 9265, "text": 9253 }, + "coffee-washing-station-case", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 9203, "text": 9204 }, + { "depth": 79, "slug": 9269, "text": 9270 }, + "part-1-why-does-bed-c-keep-failing-export-spec", + "Part 1: “Why Does Bed C Keep Failing Export Spec?”", + { "depth": 33, "slug": 9209, "text": 9210 }, + { "depth": 33, "slug": 9212, "text": 9213 }, + { "depth": 79, "slug": 9274, "text": 9275 }, + "1-washing-station-data-washing-stationcsv", + "1. Washing Station Data (washing-station.csv)", + { "depth": 33, "slug": 9230, "text": 9231 }, + { "depth": 33, "slug": 9218, "text": 9219 }, + { "depth": 79, "slug": 9279, "text": 9280 }, + "how-coffee-moisture-is-measured", + "How Coffee Moisture is Measured", + { "depth": 33, "slug": 9233, "text": 9234 }, + { "depth": 79, "slug": 9283, "text": 9284 }, + "module-1-process-analysis", + "Module 1: Process Analysis", + { "depth": 33, "slug": 9240, "text": 9241 }, + { "depth": 33, "slug": 878, "text": 879 }, + [], + [], + { "title": 9253 }, + [], + "04-cases/bottleneck", + { "id": 9291, "data": 9293, "body": 9298, "filePath": 9299, "digest": 9300, "rendered": 9301 }, + { + "title": 9294, + "editUrl": 16, + "head": 9295, + "template": 18, + "sidebar": 9296, + "pagefind": 16, + "draft": 20 + }, + "Bottleneck Case - ESTIEM", + [], + { "hidden": 20, "attrs": 9297 }, + {}, + "# Bottleneck Case - ESTIEM\n\n## Campaign Position\n\n**Week 1** - The Conversion Video (\"The Bottleneck\")\n\n## Origin\n\nTeaching case from ESTIEM Lean Six Sigma training. Demonstrates how process flow analysis reveals hidden variation sources.\n\n## The Setup\n\nA manufacturing process has 5 sequential steps. Management has always blamed Step 3 for delays and is considering a €50,000 equipment upgrade for that station.\n\n**The twist:** When you actually look at the data, Step 2 has 3x the variation of Step 3. Step 3's average time is higher, but Step 2's inconsistency is what's creating the backlog.\n\n## The Problem Statement\n\n> \"This process had 5 steps. Step 3 was always blamed for delays. The manager wanted to invest in Step 3 equipment. But look what happens when we actually see the data...\"\n\n## VaRiScout Analysis\n\n### Charts Used\n\n| Chart | What It Shows |\n| ------- | --------------------------------------------------------------------------------- |\n| I-Chart | Cycle times for each step - Step 2 shows high variation, Step 3 is stable |\n| Boxplot | Cycle time by Process Step - reveals Step 2's wide spread vs Step 3's consistency |\n\n### The Reveal\n\n- **Average cycle times:** Step 3 = 45 sec, Step 2 = 38 sec\n- **Variation (Range):** Step 3 = 8 sec, Step 2 = 24 sec\n- **The insight:** \"Step 2 had 3x the variation. It WAS the bottleneck.\"\n\n## Three-Act Structure\n\n### Act 1: The Problem\n\nShow the averages. Step 3 looks worst at 45 seconds average. Management's conclusion seems reasonable.\n\n**Key visualization:** Bar chart of averages - Step 3 is tallest\n\n### Act 2: Your Turn\n\nInteractive VaRiScout demo. User explores the data themselves.\n\n**Guided questions:**\n\n- \"Click on the boxplot. What do you notice about the spread?\"\n- \"Look at the I-Chart. Which step has the most unpredictable timing?\"\n\n### Act 3: The Solution\n\nThe variation analysis reveals the truth. Step 2's inconsistency (24-second range) causes more downstream delays than Step 3's consistently higher but predictable timing.\n\n**Business impact:**\n\n- Investing €50k in Step 3 would not solve the problem\n- Step 2 investigation reveals: operator training issue, equipment not standardized\n- Actual fix: €5k training + standardized work instructions\n\n## Teaching Points\n\n| Concept | Learning |\n| --------------------- | ---------------------------------------- |\n| Averages can mislead | High average ≠ biggest problem |\n| Variation matters | Predictable slow > unpredictable fast |\n| Visual analysis first | The pattern tells the story before stats |\n| Question assumptions | \"We always blamed Step 3\" isn't evidence |\n\n## Key Message\n\n> \"What's hiding in YOUR process?\"\n\n## AI Comparison (Week 4)\n\nSame dataset analyzed with VaRiScout vs Copilot Analyst Agent:\n\n- **VaRiScout:** Instantly shows boxplot variation, I-Chart patterns visible\n- **Copilot Analyst:** Calculates averages correctly, may miss variation story\n- **Teaching point:** AI is great at calculation, but visual EDA catches what matters\n\n## Linked Filtering Demonstration\n\n- Click Step 2 in boxplot → I-Chart filters to show only Step 2 observations\n- Time series reveals: first half of shift stable, second half variable (fatigue?)\n\n## Dataset\n\n### File: `data.csv`\n\n| Column | Description | Type |\n| -------------- | --------------------- | ----------- |\n| Observation | Sequential ID (1-150) | int |\n| Step | Process step (1-5) | categorical |\n| Cycle_Time_sec | Time to complete step | numeric |\n| Shift | Morning/Afternoon | categorical |\n| Day | Mon-Fri | categorical |\n\n### Data Characteristics\n\n- 30 observations per step (150 total)\n- Step 2: Mean 38 sec, SD 8 sec (high variation)\n- Step 3: Mean 45 sec, SD 2.7 sec (low variation)\n- Other steps: Means 30-35 sec, SD 3-4 sec (moderate)\n\n### Sample Rows\n\n```csv\nObservation,Step,Cycle_Time_sec,Shift,Day\n1,1,32,Morning,Mon\n2,1,34,Morning,Mon\n3,1,31,Morning,Mon\n...\n31,2,28,Morning,Mon\n32,2,52,Morning,Mon\n33,2,36,Morning,Mon\n...\n```\n\n## Video Script Notes\n\n### Hook (0-15 sec)\n\n\"Every factory has a Step 3. The step everyone complains about. The one management wants to upgrade. But what if they're wrong?\"\n\n### Story (15 sec - 3 min)\n\n- Walk through the 5-step process\n- Show the average times (Step 3 looks worst)\n- Manager's request: €50k upgrade for Step 3\n- \"But I said: let me see the data first...\"\n\n### Reveal (3-4 min)\n\n- Open VaRiScout\n- Paste the data\n- Click boxplot\n- \"Look at Step 2. That spread. That's your bottleneck.\"\n- Explain variation vs average\n\n### CTA (4-5 min)\n\n- \"What's hiding in YOUR process?\"\n- \"Try VaRiScout free at variscout.com\"\n- \"Same data, different insight.\"\n\n---\n\n_Case created for: VaRiScout Content Campaign Week 1_\n_Teaching level: Introduction to variation analysis_\n_Prerequisites: None - this is the entry point_", + "src/content/docs/04-cases/bottleneck/index.md", + "b2c2db182b9b8b47", + { "html": 9302, "metadata": 9303 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"bottleneck-case---estiem\">Bottleneck Case - ESTIEM\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#bottleneck-case---estiem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Bottleneck Case - ESTIEM”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"campaign-position\">Campaign Position\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#campaign-position\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Campaign Position”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Week 1\u003C/strong> - The Conversion Video (“The Bottleneck”)\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"origin\">Origin\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#origin\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Origin”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Teaching case from ESTIEM Lean Six Sigma training. Demonstrates how process flow analysis reveals hidden variation sources.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-setup\">The Setup\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A manufacturing process has 5 sequential steps. Management has always blamed Step 3 for delays and is considering a €50,000 equipment upgrade for that station.\u003C/p>\n\u003Cp>\u003Cstrong>The twist:\u003C/strong> When you actually look at the data, Step 2 has 3x the variation of Step 3. Step 3’s average time is higher, but Step 2’s inconsistency is what’s creating the backlog.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem-statement\">The Problem Statement\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem-statement\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem Statement”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“This process had 5 steps. Step 3 was always blamed for delays. The manager wanted to invest in Step 3 equipment. But look what happens when we actually see the data…”\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-analysis\">VaRiScout Analysis\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VaRiScout Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"charts-used\">Charts Used\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#charts-used\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Charts Used”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>What It Shows\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>I-Chart\u003C/td>\u003Ctd>Cycle times for each step - Step 2 shows high variation, Step 3 is stable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Cycle time by Process Step - reveals Step 2’s wide spread vs Step 3’s consistency\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-reveal\">The Reveal\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-reveal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Reveal”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Average cycle times:\u003C/strong> Step 3 = 45 sec, Step 2 = 38 sec\u003C/li>\n\u003Cli>\u003Cstrong>Variation (Range):\u003C/strong> Step 3 = 8 sec, Step 2 = 24 sec\u003C/li>\n\u003Cli>\u003Cstrong>The insight:\u003C/strong> “Step 2 had 3x the variation. It WAS the bottleneck.”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"three-act-structure\">Three-Act Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#three-act-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Three-Act Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-1-the-problem\">Act 1: The Problem\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-1-the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 1: The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Show the averages. Step 3 looks worst at 45 seconds average. Management’s conclusion seems reasonable.\u003C/p>\n\u003Cp>\u003Cstrong>Key visualization:\u003C/strong> Bar chart of averages - Step 3 is tallest\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-2-your-turn\">Act 2: Your Turn\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-2-your-turn\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 2: Your Turn”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Interactive VaRiScout demo. User explores the data themselves.\u003C/p>\n\u003Cp>\u003Cstrong>Guided questions:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“Click on the boxplot. What do you notice about the spread?”\u003C/li>\n\u003Cli>“Look at the I-Chart. Which step has the most unpredictable timing?”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-3-the-solution\">Act 3: The Solution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-3-the-solution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 3: The Solution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The variation analysis reveals the truth. Step 2’s inconsistency (24-second range) causes more downstream delays than Step 3’s consistently higher but predictable timing.\u003C/p>\n\u003Cp>\u003Cstrong>Business impact:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Investing €50k in Step 3 would not solve the problem\u003C/li>\n\u003Cli>Step 2 investigation reveals: operator training issue, equipment not standardized\u003C/li>\n\u003Cli>Actual fix: €5k training + standardized work instructions\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teaching-points\">Teaching Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teaching-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teaching Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Concept\u003C/th>\u003Cth>Learning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Averages can mislead\u003C/td>\u003Ctd>High average ≠ biggest problem\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Variation matters\u003C/td>\u003Ctd>Predictable slow > unpredictable fast\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Visual analysis first\u003C/td>\u003Ctd>The pattern tells the story before stats\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Question assumptions\u003C/td>\u003Ctd>”We always blamed Step 3” isn’t evidence\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-message\">Key Message\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-message\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Message”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“What’s hiding in YOUR process?”\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ai-comparison-week-4\">AI Comparison (Week 4)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ai-comparison-week-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “AI Comparison (Week 4)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Same dataset analyzed with VaRiScout vs Copilot Analyst Agent:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>VaRiScout:\u003C/strong> Instantly shows boxplot variation, I-Chart patterns visible\u003C/li>\n\u003Cli>\u003Cstrong>Copilot Analyst:\u003C/strong> Calculates averages correctly, may miss variation story\u003C/li>\n\u003Cli>\u003Cstrong>Teaching point:\u003C/strong> AI is great at calculation, but visual EDA catches what matters\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"linked-filtering-demonstration\">Linked Filtering Demonstration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#linked-filtering-demonstration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Linked Filtering Demonstration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Click Step 2 in boxplot → I-Chart filters to show only Step 2 observations\u003C/li>\n\u003Cli>Time series reveals: first half of shift stable, second half variable (fatigue?)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dataset\">Dataset\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dataset\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dataset”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"file-datacsv\">File: \u003Ccode dir=\"auto\">data.csv\u003C/code>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#file-datacsv\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “File: data.csv”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Column\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Type\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Observation\u003C/td>\u003Ctd>Sequential ID (1-150)\u003C/td>\u003Ctd>int\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Step\u003C/td>\u003Ctd>Process step (1-5)\u003C/td>\u003Ctd>categorical\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cycle_Time_sec\u003C/td>\u003Ctd>Time to complete step\u003C/td>\u003Ctd>numeric\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shift\u003C/td>\u003Ctd>Morning/Afternoon\u003C/td>\u003Ctd>categorical\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Day\u003C/td>\u003Ctd>Mon-Fri\u003C/td>\u003Ctd>categorical\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-characteristics\">Data Characteristics\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-characteristics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Characteristics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>30 observations per step (150 total)\u003C/li>\n\u003Cli>Step 2: Mean 38 sec, SD 8 sec (high variation)\u003C/li>\n\u003Cli>Step 3: Mean 45 sec, SD 2.7 sec (low variation)\u003C/li>\n\u003Cli>Other steps: Means 30-35 sec, SD 3-4 sec (moderate)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"sample-rows\">Sample Rows\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#sample-rows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sample Rows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"csv\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Observation,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Step,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Cycle_Time_sec,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Shift,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Day\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">1,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">1,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">32,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Morning,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Mon\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">2,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">1,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">34,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Morning,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Mon\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">3,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">1,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">31,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Morning,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Mon\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">31,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">2,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">28,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Morning,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Mon\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">32,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">2,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">52,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Morning,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Mon\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">33,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">2,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">36,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Morning,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Mon\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Observation,Step,Cycle_Time_sec,Shift,Day1,1,32,Morning,Mon2,1,34,Morning,Mon3,1,31,Morning,Mon...31,2,28,Morning,Mon32,2,52,Morning,Mon33,2,36,Morning,Mon...\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"video-script-notes\">Video Script Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#video-script-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Video Script Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"hook-0-15-sec\">Hook (0-15 sec)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#hook-0-15-sec\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hook (0-15 sec)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>“Every factory has a Step 3. The step everyone complains about. The one management wants to upgrade. But what if they’re wrong?”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"story-15-sec---3-min\">Story (15 sec - 3 min)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#story-15-sec---3-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Story (15 sec - 3 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Walk through the 5-step process\u003C/li>\n\u003Cli>Show the average times (Step 3 looks worst)\u003C/li>\n\u003Cli>Manager’s request: €50k upgrade for Step 3\u003C/li>\n\u003Cli>“But I said: let me see the data first…”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"reveal-3-4-min\">Reveal (3-4 min)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#reveal-3-4-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reveal (3-4 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Open VaRiScout\u003C/li>\n\u003Cli>Paste the data\u003C/li>\n\u003Cli>Click boxplot\u003C/li>\n\u003Cli>“Look at Step 2. That spread. That’s your bottleneck.”\u003C/li>\n\u003Cli>Explain variation vs average\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cta-4-5-min\">CTA (4-5 min)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cta-4-5-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CTA (4-5 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“What’s hiding in YOUR process?”\u003C/li>\n\u003Cli>“Try VaRiScout free at variscout.com”\u003C/li>\n\u003Cli>“Same data, different insight.”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cem>Case created for: VaRiScout Content Campaign Week 1\u003C/em>\n\u003Cem>Teaching level: Introduction to variation analysis\u003C/em>\n\u003Cem>Prerequisites: None - this is the entry point\u003C/em>\u003C/p>", + { + "headings": 9304, + "localImagePaths": 9373, + "remoteImagePaths": 9374, + "frontmatter": 9375, + "imagePaths": 9376 + }, + [ + 9305, 9307, 9310, 9313, 9316, 9319, 9322, 9325, 9328, 9331, 9334, 9335, 9336, 9337, 9340, 9343, + 9346, 9349, 9352, 9355, 9358, 9361, 9364, 9367, 9370 + ], + { "depth": 30, "slug": 9306, "text": 9294 }, + "bottleneck-case---estiem", + { "depth": 33, "slug": 9308, "text": 9309 }, + "campaign-position", + "Campaign Position", + { "depth": 33, "slug": 9311, "text": 9312 }, + "origin", + "Origin", + { "depth": 33, "slug": 9314, "text": 9315 }, + "the-setup", + "The Setup", + { "depth": 33, "slug": 9317, "text": 9318 }, + "the-problem-statement", + "The Problem Statement", + { "depth": 33, "slug": 9320, "text": 9321 }, + "variscout-analysis", + "VaRiScout Analysis", + { "depth": 79, "slug": 9323, "text": 9324 }, + "charts-used", + "Charts Used", + { "depth": 79, "slug": 9326, "text": 9327 }, + "the-reveal", + "The Reveal", + { "depth": 33, "slug": 9329, "text": 9330 }, + "three-act-structure", + "Three-Act Structure", + { "depth": 79, "slug": 9332, "text": 9333 }, + "act-1-the-problem", + "Act 1: The Problem", + { "depth": 79, "slug": 4587, "text": 4588 }, + { "depth": 79, "slug": 4590, "text": 4591 }, + { "depth": 33, "slug": 9209, "text": 9210 }, + { "depth": 33, "slug": 9338, "text": 9339 }, + "key-message", + "Key Message", + { "depth": 33, "slug": 9341, "text": 9342 }, + "ai-comparison-week-4", + "AI Comparison (Week 4)", + { "depth": 33, "slug": 9344, "text": 9345 }, + "linked-filtering-demonstration", + "Linked Filtering Demonstration", + { "depth": 33, "slug": 9347, "text": 9348 }, + "dataset", + "Dataset", + { "depth": 79, "slug": 9350, "text": 9351 }, + "file-datacsv", + "File: data.csv", + { "depth": 79, "slug": 9353, "text": 9354 }, + "data-characteristics", + "Data Characteristics", + { "depth": 79, "slug": 9356, "text": 9357 }, + "sample-rows", + "Sample Rows", + { "depth": 33, "slug": 9359, "text": 9360 }, + "video-script-notes", + "Video Script Notes", + { "depth": 79, "slug": 9362, "text": 9363 }, + "hook-0-15-sec", + "Hook (0-15 sec)", + { "depth": 79, "slug": 9365, "text": 9366 }, + "story-15-sec---3-min", + "Story (15 sec - 3 min)", + { "depth": 79, "slug": 9368, "text": 9369 }, + "reveal-3-4-min", + "Reveal (3-4 min)", + { "depth": 79, "slug": 9371, "text": 9372 }, + "cta-4-5-min", + "CTA (4-5 min)", + [], + [], + { "title": 9294 }, + [], + "04-cases/hospital-ward", + { "id": 9377, "data": 9379, "body": 9384, "filePath": 9385, "digest": 9386, "rendered": 9387 }, + { + "title": 9380, + "editUrl": 16, + "head": 9381, + "template": 18, + "sidebar": 9382, + "pagefind": 16, + "draft": 20 + }, + "Hospital Ward Case - ABB/Practitioner Context", + [], + { "hidden": 20, "attrs": 9383 }, + {}, + "# Hospital Ward Case - ABB/Practitioner Context\n\n## Campaign Position\n\n**Week 5** - \"Hospital Ward\" (Aggregation Case)\n**Week 8** - AI Comparison using same dataset\n\n## Origin\n\nTeaching case for practitioner training. Demonstrates the aggregation trap - how daily/weekly averages hide operational reality.\n\n## The Setup\n\nA hospital ward has 20 beds. The management dashboard shows \"75% average utilization\" - suggesting comfortable spare capacity. Administrators are considering reducing staffing during \"low demand\" periods.\n\n**The twist:** The 75% daily average hides two critical realities:\n\n- Night shift regularly hits 95%+ (crisis level)\n- Afternoon dips to 50% (apparent waste)\n\n## The Problem Statement\n\n> \"The dashboard showed 75%. Everything looked fine. But the nurses knew something was wrong...\"\n\n## VaRiScout Analysis\n\n### Phase 1: Daily View (What Management Sees)\n\n| Chart | What It Shows |\n| ------- | ----------------------------------------------------------- |\n| I-Chart | Daily utilization % - stable around 75% with control limits |\n\n**Management conclusion:** \"We have 25% spare capacity. Consider reducing night staff.\"\n\n### Phase 2: Hourly View (What's Actually Happening)\n\n| Chart | What It Shows |\n| ------- | ----------------------------------------------------------------------------------------------- |\n| I-Chart | Hourly bed occupancy - wild variation visible |\n| Boxplot | Utilization by Hour → Night (22:00-06:00) peaks at 95%+, Afternoon (14:00-16:00) valleys at 50% |\n| Boxplot | Utilization by Day of Week → Sunday highest, Wednesday lowest |\n\n**The reveal:** \"That 75% average hides crisis-level peaks and wasteful valleys.\"\n\n## Three-Act Structure\n\n### Act 1: The Problem\n\nShow the daily dashboard. 75% average looks stable. Management's conclusion seems reasonable.\n\n**Key visualization:** Daily I-Chart - process appears in control at 75%\n\n### Act 2: Your Turn\n\nInteractive VaRiScout demo. User explores hourly data.\n\n**Guided questions:**\n\n- \"Switch to hourly view. What pattern emerges?\"\n- \"Use boxplot by Hour. When does occupancy peak?\"\n- \"What happens at night? What happens in afternoon?\"\n\n### Act 3: The Solution\n\nThe hourly analysis reveals:\n\n- **Night (22:00-06:00):** 95% average, hitting 100% several nights\n- **Afternoon (14:00-16:00):** 50% average\n- **The aggregation trap:** Daily average = (95 + 50) / 2 ≈ 75%\n\n**Business impact:**\n\n- Reducing night staff would create patient safety crisis\n- Afternoon \"waste\" is actually discharge processing time\n- Solution: Flex staffing by time of day, not uniform reduction\n\n## Teaching Points\n\n| Concept | Learning |\n| --------------------------- | --------------------------------------------- |\n| Aggregation hides variation | Daily averages mask hourly reality |\n| Dashboards can mislead | KPIs optimized for executives, not operations |\n| Granularity matters | The right time resolution reveals patterns |\n| Question the summary | \"75% average\" doesn't mean \"75% all the time\" |\n\n## Key Message\n\n> \"Why your dashboard is lying\"\n>\n> \"What your daily average hides\"\n\n## AI Comparison (Week 8)\n\nSame dataset analyzed with VaRiScout vs Copilot Analyst Agent:\n\n- **VaRiScout:** Hour-by-hour boxplot instantly shows bimodal pattern\n- **Copilot Analyst:** Calculates daily average correctly, may not think to disaggregate\n- **Teaching point:** AI answers the question you ask. EDA helps you ask better questions.\n\n## Linked Filtering Demonstration\n\n- Click \"Night\" in hour boxplot → I-Chart filters to show only night observations\n- Reveals: Night shift is consistently at crisis, not random peaks\n\n## Dataset\n\n### File: `data.csv`\n\n| Column | Description | Type |\n| --------------- | ------------------------------- | ----------- |\n| Date | Date (2026-01-01 to 2026-01-28) | date |\n| Hour | Hour of day (0-23) | int |\n| Day_of_Week | Mon-Sun | categorical |\n| Time_Period | Night/Morning/Afternoon/Evening | categorical |\n| Beds_Occupied | Number of beds occupied (0-20) | int |\n| Utilization_pct | Beds_Occupied / 20 \\* 100 | numeric |\n\n### Data Characteristics\n\n- 28 days × 24 hours = 672 observations\n- Overall average: 75%\n- Night hours (22:00-06:00): Mean 95%, occasional 100%\n- Afternoon hours (14:00-16:00): Mean 50%\n- Morning/Evening: Mean 70-80%\n\n### Sample Rows\n\n```csv\nDate,Hour,Day_of_Week,Time_Period,Beds_Occupied,Utilization_pct\n2026-01-01,0,Wed,Night,19,95\n2026-01-01,1,Wed,Night,19,95\n2026-01-01,2,Wed,Night,18,90\n...\n2026-01-01,14,Wed,Afternoon,10,50\n2026-01-01,15,Wed,Afternoon,11,55\n...\n```\n\n## Video Script Notes\n\n### Hook (0-15 sec)\n\n\"Your dashboard says 75%. Your staff is burned out. Something doesn't add up.\"\n\n### Story (15 sec - 3 min)\n\n- Show the hospital ward context (20 beds)\n- Display the management dashboard: 75% utilization\n- Administrator's request: \"We have spare capacity. Cut night staffing.\"\n- Nurse's pushback: \"But we're always full at night!\"\n- \"Who's right? Let's look at the data...\"\n\n### Reveal (3-4 min)\n\n- Open VaRiScout with hourly data\n- Start with daily summary (confirms 75%)\n- Switch to hourly view\n- Create boxplot by Hour\n- \"Look at night hours. 95%. Look at afternoon. 50%.\"\n- \"The average? Exactly 75%. But the reality is completely different.\"\n\n### CTA (4-5 min)\n\n- \"What's your dashboard hiding?\"\n- \"Try VaRiScout at variscout.com\"\n- \"See what your averages don't show.\"\n\n## MSA Applicability\n\n**Not applicable** - bed counts are counts, not continuous measurements. No measurement system to validate.\n\n## Connection to Other Cases\n\n- **Bottleneck:** Shows variation in process times\n- **Hospital Ward:** Shows variation hidden by aggregation\n- **Together:** Two ways averages mislead us\n\n---\n\n_Case created for: VaRiScout Content Campaign Week 5_\n_Teaching level: Understanding aggregation and time-based patterns_\n_Prerequisites: Basic I-Chart and Boxplot understanding (Weeks 2-3)_", + "src/content/docs/04-cases/hospital-ward/index.md", + "3c0a3a0f5d07794c", + { "html": 9388, "metadata": 9389 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"hospital-ward-case---abbpractitioner-context\">Hospital Ward Case - ABB/Practitioner Context\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#hospital-ward-case---abbpractitioner-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hospital Ward Case - ABB/Practitioner Context”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"campaign-position\">Campaign Position\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#campaign-position\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Campaign Position”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Week 5\u003C/strong> - “Hospital Ward” (Aggregation Case)\n\u003Cstrong>Week 8\u003C/strong> - AI Comparison using same dataset\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"origin\">Origin\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#origin\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Origin”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Teaching case for practitioner training. Demonstrates the aggregation trap - how daily/weekly averages hide operational reality.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-setup\">The Setup\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-setup\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Setup”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A hospital ward has 20 beds. The management dashboard shows “75% average utilization” - suggesting comfortable spare capacity. Administrators are considering reducing staffing during “low demand” periods.\u003C/p>\n\u003Cp>\u003Cstrong>The twist:\u003C/strong> The 75% daily average hides two critical realities:\u003C/p>\n\u003Cul>\n\u003Cli>Night shift regularly hits 95%+ (crisis level)\u003C/li>\n\u003Cli>Afternoon dips to 50% (apparent waste)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-problem-statement\">The Problem Statement\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-problem-statement\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Problem Statement”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“The dashboard showed 75%. Everything looked fine. But the nurses knew something was wrong…”\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-analysis\">VaRiScout Analysis\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VaRiScout Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-1-daily-view-what-management-sees\">Phase 1: Daily View (What Management Sees)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-1-daily-view-what-management-sees\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 1: Daily View (What Management Sees)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>What It Shows\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>I-Chart\u003C/td>\u003Ctd>Daily utilization % - stable around 75% with control limits\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Management conclusion:\u003C/strong> “We have 25% spare capacity. Consider reducing night staff.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-2-hourly-view-whats-actually-happening\">Phase 2: Hourly View (What’s Actually Happening)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-hourly-view-whats-actually-happening\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2: Hourly View (What’s Actually Happening)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>What It Shows\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>I-Chart\u003C/td>\u003Ctd>Hourly bed occupancy - wild variation visible\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Utilization by Hour → Night (22:00-06:00) peaks at 95%+, Afternoon (14:00-16:00) valleys at 50%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Utilization by Day of Week → Sunday highest, Wednesday lowest\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>The reveal:\u003C/strong> “That 75% average hides crisis-level peaks and wasteful valleys.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"three-act-structure\">Three-Act Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#three-act-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Three-Act Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-1-the-problem\">Act 1: The Problem\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-1-the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 1: The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Show the daily dashboard. 75% average looks stable. Management’s conclusion seems reasonable.\u003C/p>\n\u003Cp>\u003Cstrong>Key visualization:\u003C/strong> Daily I-Chart - process appears in control at 75%\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-2-your-turn\">Act 2: Your Turn\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-2-your-turn\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 2: Your Turn”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Interactive VaRiScout demo. User explores hourly data.\u003C/p>\n\u003Cp>\u003Cstrong>Guided questions:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>“Switch to hourly view. What pattern emerges?”\u003C/li>\n\u003Cli>“Use boxplot by Hour. When does occupancy peak?”\u003C/li>\n\u003Cli>“What happens at night? What happens in afternoon?”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"act-3-the-solution\">Act 3: The Solution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#act-3-the-solution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Act 3: The Solution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The hourly analysis reveals:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Night (22:00-06:00):\u003C/strong> 95% average, hitting 100% several nights\u003C/li>\n\u003Cli>\u003Cstrong>Afternoon (14:00-16:00):\u003C/strong> 50% average\u003C/li>\n\u003Cli>\u003Cstrong>The aggregation trap:\u003C/strong> Daily average = (95 + 50) / 2 ≈ 75%\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Business impact:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Reducing night staff would create patient safety crisis\u003C/li>\n\u003Cli>Afternoon “waste” is actually discharge processing time\u003C/li>\n\u003Cli>Solution: Flex staffing by time of day, not uniform reduction\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teaching-points\">Teaching Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teaching-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teaching Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Concept\u003C/th>\u003Cth>Learning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Aggregation hides variation\u003C/td>\u003Ctd>Daily averages mask hourly reality\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Dashboards can mislead\u003C/td>\u003Ctd>KPIs optimized for executives, not operations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Granularity matters\u003C/td>\u003Ctd>The right time resolution reveals patterns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Question the summary\u003C/td>\u003Ctd>”75% average” doesn’t mean “75% all the time”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-message\">Key Message\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-message\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Message”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>“Why your dashboard is lying”\u003C/p>\n\u003Cp>“What your daily average hides”\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"ai-comparison-week-8\">AI Comparison (Week 8)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#ai-comparison-week-8\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “AI Comparison (Week 8)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Same dataset analyzed with VaRiScout vs Copilot Analyst Agent:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>VaRiScout:\u003C/strong> Hour-by-hour boxplot instantly shows bimodal pattern\u003C/li>\n\u003Cli>\u003Cstrong>Copilot Analyst:\u003C/strong> Calculates daily average correctly, may not think to disaggregate\u003C/li>\n\u003Cli>\u003Cstrong>Teaching point:\u003C/strong> AI answers the question you ask. EDA helps you ask better questions.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"linked-filtering-demonstration\">Linked Filtering Demonstration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#linked-filtering-demonstration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Linked Filtering Demonstration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Click “Night” in hour boxplot → I-Chart filters to show only night observations\u003C/li>\n\u003Cli>Reveals: Night shift is consistently at crisis, not random peaks\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dataset\">Dataset\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dataset\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dataset”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"file-datacsv\">File: \u003Ccode dir=\"auto\">data.csv\u003C/code>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#file-datacsv\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “File: data.csv”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Column\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Type\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Date\u003C/td>\u003Ctd>Date (2026-01-01 to 2026-01-28)\u003C/td>\u003Ctd>date\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hour\u003C/td>\u003Ctd>Hour of day (0-23)\u003C/td>\u003Ctd>int\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Day_of_Week\u003C/td>\u003Ctd>Mon-Sun\u003C/td>\u003Ctd>categorical\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Time_Period\u003C/td>\u003Ctd>Night/Morning/Afternoon/Evening\u003C/td>\u003Ctd>categorical\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Beds_Occupied\u003C/td>\u003Ctd>Number of beds occupied (0-20)\u003C/td>\u003Ctd>int\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Utilization_pct\u003C/td>\u003Ctd>Beds_Occupied / 20 * 100\u003C/td>\u003Ctd>numeric\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-characteristics\">Data Characteristics\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-characteristics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Characteristics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>28 days × 24 hours = 672 observations\u003C/li>\n\u003Cli>Overall average: 75%\u003C/li>\n\u003Cli>Night hours (22:00-06:00): Mean 95%, occasional 100%\u003C/li>\n\u003Cli>Afternoon hours (14:00-16:00): Mean 50%\u003C/li>\n\u003Cli>Morning/Evening: Mean 70-80%\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"sample-rows\">Sample Rows\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#sample-rows\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sample Rows”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"csv\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Date,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Hour,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Day_of_Week,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Time_Period,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Beds_Occupied,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">Utilization_pct\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">2026-01-01,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">0,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Wed,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Night,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">19,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">95\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">2026-01-01,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">1,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Wed,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Night,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">19,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">95\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">2026-01-01,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">2,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Wed,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Night,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">18,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">90\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">2026-01-01,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">14,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Wed,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Afternoon,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">10,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">50\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">2026-01-01,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">15,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Wed,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Afternoon,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">11,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">55\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Date,Hour,Day_of_Week,Time_Period,Beds_Occupied,Utilization_pct2026-01-01,0,Wed,Night,19,952026-01-01,1,Wed,Night,19,952026-01-01,2,Wed,Night,18,90...2026-01-01,14,Wed,Afternoon,10,502026-01-01,15,Wed,Afternoon,11,55...\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"video-script-notes\">Video Script Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#video-script-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Video Script Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"hook-0-15-sec\">Hook (0-15 sec)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#hook-0-15-sec\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hook (0-15 sec)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>“Your dashboard says 75%. Your staff is burned out. Something doesn’t add up.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"story-15-sec---3-min\">Story (15 sec - 3 min)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#story-15-sec---3-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Story (15 sec - 3 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Show the hospital ward context (20 beds)\u003C/li>\n\u003Cli>Display the management dashboard: 75% utilization\u003C/li>\n\u003Cli>Administrator’s request: “We have spare capacity. Cut night staffing.”\u003C/li>\n\u003Cli>Nurse’s pushback: “But we’re always full at night!”\u003C/li>\n\u003Cli>“Who’s right? Let’s look at the data…”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"reveal-3-4-min\">Reveal (3-4 min)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#reveal-3-4-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reveal (3-4 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Open VaRiScout with hourly data\u003C/li>\n\u003Cli>Start with daily summary (confirms 75%)\u003C/li>\n\u003Cli>Switch to hourly view\u003C/li>\n\u003Cli>Create boxplot by Hour\u003C/li>\n\u003Cli>“Look at night hours. 95%. Look at afternoon. 50%.”\u003C/li>\n\u003Cli>“The average? Exactly 75%. But the reality is completely different.”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cta-4-5-min\">CTA (4-5 min)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cta-4-5-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CTA (4-5 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>“What’s your dashboard hiding?”\u003C/li>\n\u003Cli>“Try VaRiScout at variscout.com”\u003C/li>\n\u003Cli>“See what your averages don’t show.”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"msa-applicability\">MSA Applicability\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#msa-applicability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “MSA Applicability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Not applicable\u003C/strong> - bed counts are counts, not continuous measurements. No measurement system to validate.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"connection-to-other-cases\">Connection to Other Cases\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#connection-to-other-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Connection to Other Cases”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Bottleneck:\u003C/strong> Shows variation in process times\u003C/li>\n\u003Cli>\u003Cstrong>Hospital Ward:\u003C/strong> Shows variation hidden by aggregation\u003C/li>\n\u003Cli>\u003Cstrong>Together:\u003C/strong> Two ways averages mislead us\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cem>Case created for: VaRiScout Content Campaign Week 5\u003C/em>\n\u003Cem>Teaching level: Understanding aggregation and time-based patterns\u003C/em>\n\u003Cem>Prerequisites: Basic I-Chart and Boxplot understanding (Weeks 2-3)\u003C/em>\u003C/p>", + { + "headings": 9390, + "localImagePaths": 9429, + "remoteImagePaths": 9430, + "frontmatter": 9431, + "imagePaths": 9432 + }, + [ + 9391, 9393, 9394, 9395, 9396, 9397, 9398, 9401, 9404, 9405, 9406, 9407, 9408, 9409, 9410, 9413, + 9414, 9415, 9416, 9417, 9418, 9419, 9420, 9421, 9422, 9423, 9426 + ], + { "depth": 30, "slug": 9392, "text": 9380 }, + "hospital-ward-case---abbpractitioner-context", + { "depth": 33, "slug": 9308, "text": 9309 }, + { "depth": 33, "slug": 9311, "text": 9312 }, + { "depth": 33, "slug": 9314, "text": 9315 }, + { "depth": 33, "slug": 9317, "text": 9318 }, + { "depth": 33, "slug": 9320, "text": 9321 }, + { "depth": 79, "slug": 9399, "text": 9400 }, + "phase-1-daily-view-what-management-sees", + "Phase 1: Daily View (What Management Sees)", + { "depth": 79, "slug": 9402, "text": 9403 }, + "phase-2-hourly-view-whats-actually-happening", + "Phase 2: Hourly View (What’s Actually Happening)", + { "depth": 33, "slug": 9329, "text": 9330 }, + { "depth": 79, "slug": 9332, "text": 9333 }, + { "depth": 79, "slug": 4587, "text": 4588 }, + { "depth": 79, "slug": 4590, "text": 4591 }, + { "depth": 33, "slug": 9209, "text": 9210 }, + { "depth": 33, "slug": 9338, "text": 9339 }, + { "depth": 33, "slug": 9411, "text": 9412 }, + "ai-comparison-week-8", + "AI Comparison (Week 8)", + { "depth": 33, "slug": 9344, "text": 9345 }, + { "depth": 33, "slug": 9347, "text": 9348 }, + { "depth": 79, "slug": 9350, "text": 9351 }, + { "depth": 79, "slug": 9353, "text": 9354 }, + { "depth": 79, "slug": 9356, "text": 9357 }, + { "depth": 33, "slug": 9359, "text": 9360 }, + { "depth": 79, "slug": 9362, "text": 9363 }, + { "depth": 79, "slug": 9365, "text": 9366 }, + { "depth": 79, "slug": 9368, "text": 9369 }, + { "depth": 79, "slug": 9371, "text": 9372 }, + { "depth": 33, "slug": 9424, "text": 9425 }, + "msa-applicability", + "MSA Applicability", + { "depth": 33, "slug": 9427, "text": 9428 }, + "connection-to-other-cases", + "Connection to Other Cases", + [], + [], + { "title": 9380 }, + [], + "04-cases/machine-utilization", + { "id": 9433, "data": 9435, "body": 9440, "filePath": 9441, "digest": 9442, "rendered": 9443 }, + { + "title": 9436, + "editUrl": 16, + "head": 9437, + "template": 18, + "sidebar": 9438, + "pagefind": 16, + "draft": 20 + }, + "Case Study: \"Do We Really Need a New Machine?\"", + [], + { "hidden": 20, "attrs": 9439 }, + {}, + "# Case Study: \"Do We Really Need a New Machine?\"\n\n## Background\n\nBright Star Foods is a food processing company in Nairobi. Their single packaging machine has been running for 6 years. The production manager has requested budget for a second machine, claiming: \"We're at maximum capacity. We can't take more orders.\"\n\nBefore approving the €180,000 investment, the Quality Manager decides to collect some simple data. She assigns a production assistant to observe the machine for two weeks.\n\n**Data collection method:** Record every stoppage - when it started, when it ended, and why.\n\n**Shift:** 8 hours (480 minutes), Monday to Friday\n\n**Reason codes used:**\n\n- **Clearing output** - Moving finished packages to make space\n- **No product** - Waiting for product to package (from upstream)\n- **Refill supplies** - Loading boxes, film, labels, tape\n- **Changeover** - Switching to different product/package size\n- **Break / Lunch** - Scheduled breaks\n- **Repair** - Fixing machine issues\n\n---\n\n## Week 1: Tally Sheet Approach\n\nThe first week, the observer used a simple tally sheet - making a mark each time the machine stopped, categorized by reason, plus recording total stoppage time at end of day.\n\n### Daily Tally\n\n| Day | No product | Clearing | Refill | Changeover | Break | Lunch | Repair | Total Stops |\n| --------- | ---------- | -------- | ------ | ---------- | ------ | ----- | ------ | ----------- |\n| Monday | 4 | 3 | 2 | 2 | 2 | 1 | 0 | 14 |\n| Tuesday | 3 | 2 | 1 | 3 | 2 | 1 | 0 | 12 |\n| Wednesday | 4 | 3 | 2 | 2 | 2 | 1 | 1 | 15 |\n| Thursday | 4 | 2 | 2 | 4 | 2 | 1 | 0 | 15 |\n| Friday | 5 | 3 | 2 | 4 | 2 | 1 | 0 | 17 |\n| **Total** | **20** | **13** | **9** | **15** | **10** | **5** | **1** | **73** |\n\n### Daily Running Time\n\n| Day | Total Stoppage (min) | Running Time (min) | Running % |\n| --------- | -------------------- | ------------------ | --------- |\n| Monday | 218 | 262 | 55% |\n| Tuesday | 196 | 284 | 59% |\n| Wednesday | 241 | 239 | 50% |\n| Thursday | 205 | 275 | 57% |\n| Friday | 258 | 222 | 46% |\n\n**Week 1 Average: 53% running time**\n\n### Week 1 Observations\n\nThe tally sheet immediately revealed:\n\n- Machine stops **73 times per week** - about 15 times per day\n- \"No product\" is the most frequent stop (20 times)\n- Only 1 repair all week - the machine itself is reliable\n- Friday had the most stops (17) and lowest running time (46%)\n\n---\n\n## Week 2: Detailed Stoppage Log\n\nAfter seeing Week 1 results, the Quality Manager asked for more detail. Every individual stoppage was recorded.\n\n### Monday\n\n| Stop # | Start | End | Duration (min) | Reason |\n| --------- | ----- | ----- | -------------- | --------------- |\n| 1 | 07:00 | 07:18 | 18 | Clearing output |\n| 2 | 08:12 | 08:24 | 12 | No product |\n| 3 | 09:05 | 09:14 | 9 | Changeover |\n| 4 | 10:00 | 10:15 | 15 | Break |\n| 5 | 10:15 | 10:23 | 8 | Refill supplies |\n| 6 | 11:20 | 11:31 | 11 | No product |\n| 7 | 12:00 | 12:30 | 30 | Lunch |\n| 8 | 12:30 | 12:44 | 14 | Clearing output |\n| 9 | 13:25 | 13:38 | 13 | Changeover |\n| 10 | 14:15 | 14:26 | 11 | No product |\n| 11 | 15:00 | 15:15 | 15 | Break |\n| 12 | 15:15 | 15:24 | 9 | Refill supplies |\n| **Total** | | | **165** | |\n\n### Tuesday\n\n| Stop # | Start | End | Duration (min) | Reason |\n| --------- | ----- | ----- | -------------- | --------------- |\n| 1 | 07:00 | 07:08 | 8 | Clearing output |\n| 2 | 07:45 | 07:56 | 11 | Changeover |\n| 3 | 08:40 | 08:52 | 12 | No product |\n| 4 | 10:00 | 10:15 | 15 | Break |\n| 5 | 10:42 | 10:53 | 11 | Changeover |\n| 6 | 11:35 | 11:47 | 12 | No product |\n| 7 | 12:00 | 12:30 | 30 | Lunch |\n| 8 | 12:30 | 12:38 | 8 | Refill supplies |\n| 9 | 13:15 | 13:24 | 9 | No product |\n| 10 | 14:30 | 14:41 | 11 | Changeover |\n| 11 | 15:00 | 15:15 | 15 | Break |\n| 12 | 15:50 | 16:02 | 12 | Clearing output |\n| **Total** | | | **154** | |\n\n### Wednesday\n\n| Stop # | Start | End | Duration (min) | Reason |\n| --------- | ----- | ----- | -------------- | --------------- |\n| 1 | 07:00 | 07:24 | 24 | Clearing output |\n| 2 | 08:05 | 08:17 | 12 | No product |\n| 3 | 08:55 | 09:08 | 13 | Changeover |\n| 4 | 10:00 | 10:15 | 15 | Break |\n| 5 | 10:15 | 10:26 | 11 | Refill supplies |\n| 6 | 11:00 | 11:14 | 14 | No product |\n| 7 | 11:45 | 12:27 | 42 | Repair |\n| 8 | 12:27 | 12:57 | 30 | Lunch |\n| 9 | 12:57 | 13:12 | 15 | Clearing output |\n| 10 | 14:00 | 14:11 | 11 | Changeover |\n| 11 | 15:00 | 15:15 | 15 | Break |\n| 12 | 15:15 | 15:27 | 12 | Refill supplies |\n| 13 | 15:55 | 16:08 | 13 | No product |\n| **Total** | | | **227** | |\n\n### Thursday\n\n| Stop # | Start | End | Duration (min) | Reason |\n| --------- | ----- | ----- | -------------- | --------------- |\n| 1 | 07:00 | 07:12 | 12 | Clearing output |\n| 2 | 07:50 | 08:01 | 11 | Changeover |\n| 3 | 08:45 | 08:56 | 11 | No product |\n| 4 | 09:30 | 09:42 | 12 | Changeover |\n| 5 | 10:00 | 10:15 | 15 | Break |\n| 6 | 10:50 | 11:02 | 12 | No product |\n| 7 | 11:40 | 11:51 | 11 | Refill supplies |\n| 8 | 12:00 | 12:30 | 30 | Lunch |\n| 9 | 12:30 | 12:41 | 11 | Clearing output |\n| 10 | 13:20 | 13:32 | 12 | Changeover |\n| 11 | 14:25 | 14:36 | 11 | No product |\n| 12 | 15:00 | 15:15 | 15 | Break |\n| 13 | 15:40 | 15:52 | 12 | Refill supplies |\n| **Total** | | | **175** | |\n\n### Friday\n\n| Stop # | Start | End | Duration (min) | Reason |\n| --------- | ----- | ----- | -------------- | --------------- |\n| 1 | 07:00 | 07:28 | 28 | Clearing output |\n| 2 | 08:10 | 08:23 | 13 | No product |\n| 3 | 09:00 | 09:13 | 13 | Changeover |\n| 4 | 10:00 | 10:15 | 15 | Break |\n| 5 | 10:15 | 10:28 | 13 | Refill supplies |\n| 6 | 10:55 | 11:10 | 15 | No product |\n| 7 | 11:45 | 11:58 | 13 | Changeover |\n| 8 | 12:00 | 12:30 | 30 | Lunch |\n| 9 | 12:30 | 12:48 | 18 | Clearing output |\n| 10 | 13:30 | 13:44 | 14 | No product |\n| 11 | 14:20 | 14:35 | 15 | Changeover |\n| 12 | 15:00 | 15:15 | 15 | Break |\n| 13 | 15:15 | 15:32 | 17 | Refill supplies |\n| 14 | 16:10 | 16:24 | 14 | No product |\n| **Total** | | | **233** | |\n\n---\n\n### Week 2 Daily Summary\n\n| Day | No product | Clearing | Refill | Changeover | Break | Lunch | Repair | Total Stops | Stoppage Min | Running % |\n| --------- | ---------- | -------- | ------ | ---------- | ------ | ----- | ------ | ----------- | ------------ | --------- |\n| Monday | 3 | 2 | 2 | 2 | 2 | 1 | 0 | 12 | 165 | 66% |\n| Tuesday | 3 | 2 | 1 | 3 | 2 | 1 | 0 | 12 | 154 | 68% |\n| Wednesday | 3 | 2 | 2 | 2 | 2 | 1 | 1 | 13 | 227 | 53% |\n| Thursday | 3 | 2 | 2 | 3 | 2 | 1 | 0 | 13 | 175 | 64% |\n| Friday | 4 | 2 | 2 | 3 | 2 | 1 | 0 | 14 | 233 | 51% |\n| **Total** | **16** | **10** | **9** | **13** | **10** | **5** | **1** | **64** | **954** | |\n\n**Week 2 Average: 60% running time**\n\n### Week 1 vs Week 2 Comparison\n\n| Metric | Week 1 | Week 2 |\n| ----------------- | ------ | ------ |\n| Average running % | 53% | 60% |\n| Total stops | 73 | 64 |\n| Repair events | 1 | 1 |\n\nWeek 2 was slightly better - but still far from \"at capacity\".\n\n---\n\n## Week 2 Summary: All Stoppages for I-Chart Analysis\n\n| Obs | Day | Duration (min) | Reason |\n| --- | --- | -------------- | --------------- |\n| 1 | Mon | 18 | Clearing output |\n| 2 | Mon | 12 | No product |\n| 3 | Mon | 9 | Changeover |\n| 4 | Mon | 15 | Break |\n| 5 | Mon | 8 | Refill supplies |\n| 6 | Mon | 11 | No product |\n| 7 | Mon | 30 | Lunch |\n| 8 | Mon | 14 | Clearing output |\n| 9 | Mon | 13 | Changeover |\n| 10 | Mon | 11 | No product |\n| 11 | Mon | 15 | Break |\n| 12 | Mon | 9 | Refill supplies |\n| 13 | Tue | 8 | Clearing output |\n| 14 | Tue | 11 | Changeover |\n| 15 | Tue | 12 | No product |\n| 16 | Tue | 15 | Break |\n| 17 | Tue | 11 | Changeover |\n| 18 | Tue | 12 | No product |\n| 19 | Tue | 30 | Lunch |\n| 20 | Tue | 8 | Refill supplies |\n| 21 | Tue | 9 | No product |\n| 22 | Tue | 11 | Changeover |\n| 23 | Tue | 15 | Break |\n| 24 | Tue | 12 | Clearing output |\n| 25 | Wed | 24 | Clearing output |\n| 26 | Wed | 12 | No product |\n| 27 | Wed | 13 | Changeover |\n| 28 | Wed | 15 | Break |\n| 29 | Wed | 11 | Refill supplies |\n| 30 | Wed | 14 | No product |\n| 31 | Wed | 42 | Repair |\n| 32 | Wed | 30 | Lunch |\n| 33 | Wed | 15 | Clearing output |\n| 34 | Wed | 11 | Changeover |\n| 35 | Wed | 15 | Break |\n| 36 | Wed | 12 | Refill supplies |\n| 37 | Wed | 13 | No product |\n| 38 | Thu | 12 | Clearing output |\n| 39 | Thu | 11 | Changeover |\n| 40 | Thu | 11 | No product |\n| 41 | Thu | 12 | Changeover |\n| 42 | Thu | 15 | Break |\n| 43 | Thu | 12 | No product |\n| 44 | Thu | 11 | Refill supplies |\n| 45 | Thu | 30 | Lunch |\n| 46 | Thu | 11 | Clearing output |\n| 47 | Thu | 12 | Changeover |\n| 48 | Thu | 11 | No product |\n| 49 | Thu | 15 | Break |\n| 50 | Thu | 12 | Refill supplies |\n| 51 | Fri | 28 | Clearing output |\n| 52 | Fri | 13 | No product |\n| 53 | Fri | 13 | Changeover |\n| 54 | Fri | 15 | Break |\n| 55 | Fri | 13 | Refill supplies |\n| 56 | Fri | 15 | No product |\n| 57 | Fri | 13 | Changeover |\n| 58 | Fri | 30 | Lunch |\n| 59 | Fri | 18 | Clearing output |\n| 60 | Fri | 14 | No product |\n| 61 | Fri | 15 | Changeover |\n| 62 | Fri | 15 | Break |\n| 63 | Fri | 17 | Refill supplies |\n| 64 | Fri | 14 | No product |\n\n---\n\n## Data Summary for Analysis\n\n### Reason Code Totals (Week 2)\n\n| Reason | Count | Total Minutes | % of Stoppage Time |\n| --------------- | ------ | ------------- | ------------------ |\n| No product | 16 | 196 | 21% |\n| Clearing output | 10 | 160 | 17% |\n| Changeover | 13 | 155 | 16% |\n| Lunch | 5 | 150 | 16% |\n| Break | 10 | 150 | 16% |\n| Refill supplies | 9 | 101 | 11% |\n| Repair | 1 | 42 | 4% |\n| **Total** | **64** | **954** | **100%** |\n\n### Key Observations to Discover\n\n1. **Run Charts (Both Weeks):** Machine running only 53-60% of available time\n2. **I-Chart (Week 2 stoppages):**\n - Most stoppages cluster 8-18 minutes\n - One outlier: 42-minute repair\n - Lunch (30 min) appears as consistent \"high\" points\n3. **Pareto of Reasons:**\n - \"No product\" + \"Clearing output\" + \"Refill supplies\" = 48% of all stoppage time\n - These are _workflow issues_, not machine issues\n4. **Planned vs. Unplanned:**\n - Breaks + Lunch = 300 minutes (31% of stoppages)\n - Workflow issues = 457 minutes (48%)\n - Only 4% was actual machine issue (repair)\n\n### The Insight\n\nThe machine isn't at capacity. It's starving and choking.\n\n- **Starving:** 196 minutes/week waiting for product from upstream\n- **Choking:** 160 minutes/week waiting for space to put finished goods\n- **Fumbling:** 101 minutes/week fetching supplies that could be staged\n\nFix the material flow and workspace layout → gain 7+ hours per week → that's almost a full extra day of production.\n\n**No new machine needed.**\n\n### The Solutions (No Cost)\n\n1. **Staging area for finished goods** - Don't wait until output table is full\n2. **Buffer stock from upstream** - Small WIP buffer before packaging\n3. **Pre-staged supplies** - Labels, boxes, film ready at machine before shift\n4. **Changeover preparation** - Next product's materials ready before current run ends\n\n---\n\n## Discussion Questions\n\n1. Looking at the Week 1 run chart, what does the variation tell you?\n2. On the I-chart, which points are \"special causes\" vs. common cause variation?\n3. The Pareto shows the biggest losses. Which one would you attack first and why?\n4. What would you recommend to management before any equipment purchase?\n5. How could this simple data collection method be applied in other contexts?\n\n---\n\n## Teaching Notes\n\n**Week 1 Charts (VaRiScout Lite):**\n\n1. **I-Chart / Run chart:** Daily running % - 5 points showing instability (46-59%)\n2. **Pareto:** Stop counts by reason - \"No product\" leads with 20 stops\n\n**Week 2 Charts (VaRiScout Lite):**\n\n1. **I-Chart (daily):** Daily running % - 5 points (51-68%), compare stability to Week 1\n2. **I-Chart (stoppages):** Individual stoppage durations - 64 points, 42-min repair as outlier\n3. **Pareto (counts):** Stop counts by reason - compare pattern to Week 1\n4. **Pareto (minutes):** Stop reasons by total minutes - reveals true cost\n5. **Boxplot by Day:** Duration vs Day - reveals Friday/Wednesday patterns\n6. **Boxplot by Reason:** Duration vs Reason - shows Lunch/Repair as longer stops\n\n**The Two-Week Teaching Progression:**\n\n- Week 1: \"How bad is it?\" → Run chart shows 53% utilization, Pareto shows frequency\n- Week 2: \"Is it consistent? What's really costing us?\" → Compare weeks, drill into individual stoppages\n\n**Comparison Analysis:**\n| What to Compare | Week 1 | Week 2 | Insight |\n|-----------------|--------|--------|---------|\n| Running % | 53% avg | 60% avg | Variation between weeks |\n| Total stops | 73 | 64 | Fewer stops, but still too many |\n| #1 reason (count) | No product (20) | No product (16) | Same culprit |\n| Repairs | 1 | 1 | Machine is reliable |\n\n**Key Insight:**\nWeek 1 Pareto (by count): \"No product\" leads\nWeek 2 Pareto (by minutes): \"No product\" still leads, but relative weights shift\n\nCounting stops ≠ measuring impact. A 42-minute repair counts as \"1\" but hurts more than four 10-minute stops.\n\n**Key learning points:**\n\n- Simple observation reveals truth\n- \"Capacity problem\" was actually a workflow problem\n- No sensors, no software, no complexity needed\n- One person, two weeks, pen and paper\n- The solutions cost nothing - just better organization\n- Count data vs. measurement data tell different stories\n- Week-to-week variation shows this isn't a fluke", + "src/content/docs/04-cases/machine-utilization/index.md", + "4cda51045685fe8d", + { "html": 9444, "metadata": 9445 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"case-study-do-we-really-need-a-new-machine\">Case Study: “Do We Really Need a New Machine?”\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#case-study-do-we-really-need-a-new-machine\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Case Study: “Do We Really Need a New Machine?””\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"background\">Background\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#background\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Background”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Bright Star Foods is a food processing company in Nairobi. Their single packaging machine has been running for 6 years. The production manager has requested budget for a second machine, claiming: “We’re at maximum capacity. We can’t take more orders.”\u003C/p>\n\u003Cp>Before approving the €180,000 investment, the Quality Manager decides to collect some simple data. She assigns a production assistant to observe the machine for two weeks.\u003C/p>\n\u003Cp>\u003Cstrong>Data collection method:\u003C/strong> Record every stoppage - when it started, when it ended, and why.\u003C/p>\n\u003Cp>\u003Cstrong>Shift:\u003C/strong> 8 hours (480 minutes), Monday to Friday\u003C/p>\n\u003Cp>\u003Cstrong>Reason codes used:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Clearing output\u003C/strong> - Moving finished packages to make space\u003C/li>\n\u003Cli>\u003Cstrong>No product\u003C/strong> - Waiting for product to package (from upstream)\u003C/li>\n\u003Cli>\u003Cstrong>Refill supplies\u003C/strong> - Loading boxes, film, labels, tape\u003C/li>\n\u003Cli>\u003Cstrong>Changeover\u003C/strong> - Switching to different product/package size\u003C/li>\n\u003Cli>\u003Cstrong>Break / Lunch\u003C/strong> - Scheduled breaks\u003C/li>\n\u003Cli>\u003Cstrong>Repair\u003C/strong> - Fixing machine issues\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"week-1-tally-sheet-approach\">Week 1: Tally Sheet Approach\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#week-1-tally-sheet-approach\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Week 1: Tally Sheet Approach”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The first week, the observer used a simple tally sheet - making a mark each time the machine stopped, categorized by reason, plus recording total stoppage time at end of day.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"daily-tally\">Daily Tally\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#daily-tally\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Daily Tally”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Day\u003C/th>\u003Cth>No product\u003C/th>\u003Cth>Clearing\u003C/th>\u003Cth>Refill\u003C/th>\u003Cth>Changeover\u003C/th>\u003Cth>Break\u003C/th>\u003Cth>Lunch\u003C/th>\u003Cth>Repair\u003C/th>\u003Cth>Total Stops\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Monday\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>0\u003C/td>\u003Ctd>14\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tuesday\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>0\u003C/td>\u003Ctd>12\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Wednesday\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>15\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Thursday\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>0\u003C/td>\u003Ctd>15\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Friday\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>0\u003C/td>\u003Ctd>17\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>20\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>13\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>9\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>15\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>10\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>5\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>1\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>73\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"daily-running-time\">Daily Running Time\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#daily-running-time\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Daily Running Time”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Day\u003C/th>\u003Cth>Total Stoppage (min)\u003C/th>\u003Cth>Running Time (min)\u003C/th>\u003Cth>Running %\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Monday\u003C/td>\u003Ctd>218\u003C/td>\u003Ctd>262\u003C/td>\u003Ctd>55%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tuesday\u003C/td>\u003Ctd>196\u003C/td>\u003Ctd>284\u003C/td>\u003Ctd>59%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Wednesday\u003C/td>\u003Ctd>241\u003C/td>\u003Ctd>239\u003C/td>\u003Ctd>50%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Thursday\u003C/td>\u003Ctd>205\u003C/td>\u003Ctd>275\u003C/td>\u003Ctd>57%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Friday\u003C/td>\u003Ctd>258\u003C/td>\u003Ctd>222\u003C/td>\u003Ctd>46%\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Week 1 Average: 53% running time\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"week-1-observations\">Week 1 Observations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#week-1-observations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Week 1 Observations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The tally sheet immediately revealed:\u003C/p>\n\u003Cul>\n\u003Cli>Machine stops \u003Cstrong>73 times per week\u003C/strong> - about 15 times per day\u003C/li>\n\u003Cli>“No product” is the most frequent stop (20 times)\u003C/li>\n\u003Cli>Only 1 repair all week - the machine itself is reliable\u003C/li>\n\u003Cli>Friday had the most stops (17) and lowest running time (46%)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"week-2-detailed-stoppage-log\">Week 2: Detailed Stoppage Log\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#week-2-detailed-stoppage-log\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Week 2: Detailed Stoppage Log”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After seeing Week 1 results, the Quality Manager asked for more detail. Every individual stoppage was recorded.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"monday\">Monday\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#monday\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Monday”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stop #\u003C/th>\u003Cth>Start\u003C/th>\u003Cth>End\u003C/th>\u003Cth>Duration (min)\u003C/th>\u003Cth>Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>07:00\u003C/td>\u003Ctd>07:18\u003C/td>\u003Ctd>18\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>08:12\u003C/td>\u003Ctd>08:24\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>09:05\u003C/td>\u003Ctd>09:14\u003C/td>\u003Ctd>9\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>10:00\u003C/td>\u003Ctd>10:15\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>10:15\u003C/td>\u003Ctd>10:23\u003C/td>\u003Ctd>8\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>11:20\u003C/td>\u003Ctd>11:31\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>12:00\u003C/td>\u003Ctd>12:30\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>Lunch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>12:30\u003C/td>\u003Ctd>12:44\u003C/td>\u003Ctd>14\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>13:25\u003C/td>\u003Ctd>13:38\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>14:15\u003C/td>\u003Ctd>14:26\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>15:00\u003C/td>\u003Ctd>15:15\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>15:15\u003C/td>\u003Ctd>15:24\u003C/td>\u003Ctd>9\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>165\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tuesday\">Tuesday\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tuesday\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tuesday”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stop #\u003C/th>\u003Cth>Start\u003C/th>\u003Cth>End\u003C/th>\u003Cth>Duration (min)\u003C/th>\u003Cth>Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>07:00\u003C/td>\u003Ctd>07:08\u003C/td>\u003Ctd>8\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>07:45\u003C/td>\u003Ctd>07:56\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>08:40\u003C/td>\u003Ctd>08:52\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>10:00\u003C/td>\u003Ctd>10:15\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>10:42\u003C/td>\u003Ctd>10:53\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>11:35\u003C/td>\u003Ctd>11:47\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>12:00\u003C/td>\u003Ctd>12:30\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>Lunch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>12:30\u003C/td>\u003Ctd>12:38\u003C/td>\u003Ctd>8\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>13:15\u003C/td>\u003Ctd>13:24\u003C/td>\u003Ctd>9\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>14:30\u003C/td>\u003Ctd>14:41\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>15:00\u003C/td>\u003Ctd>15:15\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>15:50\u003C/td>\u003Ctd>16:02\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>154\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"wednesday\">Wednesday\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#wednesday\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Wednesday”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stop #\u003C/th>\u003Cth>Start\u003C/th>\u003Cth>End\u003C/th>\u003Cth>Duration (min)\u003C/th>\u003Cth>Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>07:00\u003C/td>\u003Ctd>07:24\u003C/td>\u003Ctd>24\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>08:05\u003C/td>\u003Ctd>08:17\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>08:55\u003C/td>\u003Ctd>09:08\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>10:00\u003C/td>\u003Ctd>10:15\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>10:15\u003C/td>\u003Ctd>10:26\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>11:00\u003C/td>\u003Ctd>11:14\u003C/td>\u003Ctd>14\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>11:45\u003C/td>\u003Ctd>12:27\u003C/td>\u003Ctd>42\u003C/td>\u003Ctd>Repair\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>12:27\u003C/td>\u003Ctd>12:57\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>Lunch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>12:57\u003C/td>\u003Ctd>13:12\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>14:00\u003C/td>\u003Ctd>14:11\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>15:00\u003C/td>\u003Ctd>15:15\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>15:15\u003C/td>\u003Ctd>15:27\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>13\u003C/td>\u003Ctd>15:55\u003C/td>\u003Ctd>16:08\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>227\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"thursday\">Thursday\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#thursday\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Thursday”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stop #\u003C/th>\u003Cth>Start\u003C/th>\u003Cth>End\u003C/th>\u003Cth>Duration (min)\u003C/th>\u003Cth>Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>07:00\u003C/td>\u003Ctd>07:12\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>07:50\u003C/td>\u003Ctd>08:01\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>08:45\u003C/td>\u003Ctd>08:56\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>09:30\u003C/td>\u003Ctd>09:42\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>10:00\u003C/td>\u003Ctd>10:15\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>10:50\u003C/td>\u003Ctd>11:02\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>11:40\u003C/td>\u003Ctd>11:51\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>12:00\u003C/td>\u003Ctd>12:30\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>Lunch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>12:30\u003C/td>\u003Ctd>12:41\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>13:20\u003C/td>\u003Ctd>13:32\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>14:25\u003C/td>\u003Ctd>14:36\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>15:00\u003C/td>\u003Ctd>15:15\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>13\u003C/td>\u003Ctd>15:40\u003C/td>\u003Ctd>15:52\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>175\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"friday\">Friday\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#friday\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Friday”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Stop #\u003C/th>\u003Cth>Start\u003C/th>\u003Cth>End\u003C/th>\u003Cth>Duration (min)\u003C/th>\u003Cth>Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>07:00\u003C/td>\u003Ctd>07:28\u003C/td>\u003Ctd>28\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>08:10\u003C/td>\u003Ctd>08:23\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>09:00\u003C/td>\u003Ctd>09:13\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>10:00\u003C/td>\u003Ctd>10:15\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>10:15\u003C/td>\u003Ctd>10:28\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>10:55\u003C/td>\u003Ctd>11:10\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>11:45\u003C/td>\u003Ctd>11:58\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>12:00\u003C/td>\u003Ctd>12:30\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>Lunch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>12:30\u003C/td>\u003Ctd>12:48\u003C/td>\u003Ctd>18\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>13:30\u003C/td>\u003Ctd>13:44\u003C/td>\u003Ctd>14\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>14:20\u003C/td>\u003Ctd>14:35\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>15:00\u003C/td>\u003Ctd>15:15\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>13\u003C/td>\u003Ctd>15:15\u003C/td>\u003Ctd>15:32\u003C/td>\u003Ctd>17\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>14\u003C/td>\u003Ctd>16:10\u003C/td>\u003Ctd>16:24\u003C/td>\u003Ctd>14\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003C/td>\u003Ctd>\u003Cstrong>233\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"week-2-daily-summary\">Week 2 Daily Summary\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#week-2-daily-summary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Week 2 Daily Summary”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Day\u003C/th>\u003Cth>No product\u003C/th>\u003Cth>Clearing\u003C/th>\u003Cth>Refill\u003C/th>\u003Cth>Changeover\u003C/th>\u003Cth>Break\u003C/th>\u003Cth>Lunch\u003C/th>\u003Cth>Repair\u003C/th>\u003Cth>Total Stops\u003C/th>\u003Cth>Stoppage Min\u003C/th>\u003Cth>Running %\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Monday\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>0\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>165\u003C/td>\u003Ctd>66%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tuesday\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>0\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>154\u003C/td>\u003Ctd>68%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Wednesday\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>227\u003C/td>\u003Ctd>53%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Thursday\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>0\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>175\u003C/td>\u003Ctd>64%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Friday\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>3\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>0\u003C/td>\u003Ctd>14\u003C/td>\u003Ctd>233\u003C/td>\u003Ctd>51%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>16\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>10\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>9\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>13\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>10\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>5\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>1\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>64\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>954\u003C/strong>\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Week 2 Average: 60% running time\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"week-1-vs-week-2-comparison\">Week 1 vs Week 2 Comparison\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#week-1-vs-week-2-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Week 1 vs Week 2 Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Week 1\u003C/th>\u003Cth>Week 2\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Average running %\u003C/td>\u003Ctd>53%\u003C/td>\u003Ctd>60%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Total stops\u003C/td>\u003Ctd>73\u003C/td>\u003Ctd>64\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Repair events\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Week 2 was slightly better - but still far from “at capacity”.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"week-2-summary-all-stoppages-for-i-chart-analysis\">Week 2 Summary: All Stoppages for I-Chart Analysis\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#week-2-summary-all-stoppages-for-i-chart-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Week 2 Summary: All Stoppages for I-Chart Analysis”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Obs\u003C/th>\u003Cth>Day\u003C/th>\u003Cth>Duration (min)\u003C/th>\u003Cth>Reason\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>18\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>9\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>8\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>7\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>Lunch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>8\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>14\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>9\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>10\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>11\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>12\u003C/td>\u003Ctd>Mon\u003C/td>\u003Ctd>9\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>13\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>8\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>14\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>15\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>16\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>17\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>18\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>19\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>Lunch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>20\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>8\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>21\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>9\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>22\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>23\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>24\u003C/td>\u003Ctd>Tue\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>25\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>24\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>26\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>27\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>28\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>29\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>30\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>14\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>31\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>42\u003C/td>\u003Ctd>Repair\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>32\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>Lunch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>33\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>34\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>35\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>36\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>37\u003C/td>\u003Ctd>Wed\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>38\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>39\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>40\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>41\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>42\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>43\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>44\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>45\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>Lunch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>46\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>47\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>48\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>49\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>50\u003C/td>\u003Ctd>Thu\u003C/td>\u003Ctd>12\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>51\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>28\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>52\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>53\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>54\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>55\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>56\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>57\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>58\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>30\u003C/td>\u003Ctd>Lunch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>59\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>18\u003C/td>\u003Ctd>Clearing output\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>60\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>14\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>61\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Changeover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>62\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>15\u003C/td>\u003Ctd>Break\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>63\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>17\u003C/td>\u003Ctd>Refill supplies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>64\u003C/td>\u003Ctd>Fri\u003C/td>\u003Ctd>14\u003C/td>\u003Ctd>No product\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-summary-for-analysis\">Data Summary for Analysis\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-summary-for-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Summary for Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"reason-code-totals-week-2\">Reason Code Totals (Week 2)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#reason-code-totals-week-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reason Code Totals (Week 2)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Reason\u003C/th>\u003Cth>Count\u003C/th>\u003Cth>Total Minutes\u003C/th>\u003Cth>% of Stoppage Time\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No product\u003C/td>\u003Ctd>16\u003C/td>\u003Ctd>196\u003C/td>\u003Ctd>21%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Clearing output\u003C/td>\u003Ctd>10\u003C/td>\u003Ctd>160\u003C/td>\u003Ctd>17%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Changeover\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>155\u003C/td>\u003Ctd>16%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Lunch\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>150\u003C/td>\u003Ctd>16%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Break\u003C/td>\u003Ctd>10\u003C/td>\u003Ctd>150\u003C/td>\u003Ctd>16%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Refill supplies\u003C/td>\u003Ctd>9\u003C/td>\u003Ctd>101\u003C/td>\u003Ctd>11%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Repair\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>42\u003C/td>\u003Ctd>4%\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Total\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>64\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>954\u003C/strong>\u003C/td>\u003Ctd>\u003Cstrong>100%\u003C/strong>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"key-observations-to-discover\">Key Observations to Discover\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#key-observations-to-discover\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Observations to Discover”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Run Charts (Both Weeks):\u003C/strong> Machine running only 53-60% of available time\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart (Week 2 stoppages):\u003C/strong>\n\u003Cul>\n\u003Cli>Most stoppages cluster 8-18 minutes\u003C/li>\n\u003Cli>One outlier: 42-minute repair\u003C/li>\n\u003Cli>Lunch (30 min) appears as consistent “high” points\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Pareto of Reasons:\u003C/strong>\n\u003Cul>\n\u003Cli>“No product” + “Clearing output” + “Refill supplies” = 48% of all stoppage time\u003C/li>\n\u003Cli>These are \u003Cem>workflow issues\u003C/em>, not machine issues\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Planned vs. Unplanned:\u003C/strong>\n\u003Cul>\n\u003Cli>Breaks + Lunch = 300 minutes (31% of stoppages)\u003C/li>\n\u003Cli>Workflow issues = 457 minutes (48%)\u003C/li>\n\u003Cli>Only 4% was actual machine issue (repair)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-insight\">The Insight\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-insight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Insight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The machine isn’t at capacity. It’s starving and choking.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Starving:\u003C/strong> 196 minutes/week waiting for product from upstream\u003C/li>\n\u003Cli>\u003Cstrong>Choking:\u003C/strong> 160 minutes/week waiting for space to put finished goods\u003C/li>\n\u003Cli>\u003Cstrong>Fumbling:\u003C/strong> 101 minutes/week fetching supplies that could be staged\u003C/li>\n\u003C/ul>\n\u003Cp>Fix the material flow and workspace layout → gain 7+ hours per week → that’s almost a full extra day of production.\u003C/p>\n\u003Cp>\u003Cstrong>No new machine needed.\u003C/strong>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-solutions-no-cost\">The Solutions (No Cost)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-solutions-no-cost\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Solutions (No Cost)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Staging area for finished goods\u003C/strong> - Don’t wait until output table is full\u003C/li>\n\u003Cli>\u003Cstrong>Buffer stock from upstream\u003C/strong> - Small WIP buffer before packaging\u003C/li>\n\u003Cli>\u003Cstrong>Pre-staged supplies\u003C/strong> - Labels, boxes, film ready at machine before shift\u003C/li>\n\u003Cli>\u003Cstrong>Changeover preparation\u003C/strong> - Next product’s materials ready before current run ends\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"discussion-questions\">Discussion Questions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#discussion-questions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Discussion Questions”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Looking at the Week 1 run chart, what does the variation tell you?\u003C/li>\n\u003Cli>On the I-chart, which points are “special causes” vs. common cause variation?\u003C/li>\n\u003Cli>The Pareto shows the biggest losses. Which one would you attack first and why?\u003C/li>\n\u003Cli>What would you recommend to management before any equipment purchase?\u003C/li>\n\u003Cli>How could this simple data collection method be applied in other contexts?\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teaching-notes\">Teaching Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teaching-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teaching Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Week 1 Charts (VaRiScout Lite):\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>I-Chart / Run chart:\u003C/strong> Daily running % - 5 points showing instability (46-59%)\u003C/li>\n\u003Cli>\u003Cstrong>Pareto:\u003C/strong> Stop counts by reason - “No product” leads with 20 stops\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Week 2 Charts (VaRiScout Lite):\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>I-Chart (daily):\u003C/strong> Daily running % - 5 points (51-68%), compare stability to Week 1\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart (stoppages):\u003C/strong> Individual stoppage durations - 64 points, 42-min repair as outlier\u003C/li>\n\u003Cli>\u003Cstrong>Pareto (counts):\u003C/strong> Stop counts by reason - compare pattern to Week 1\u003C/li>\n\u003Cli>\u003Cstrong>Pareto (minutes):\u003C/strong> Stop reasons by total minutes - reveals true cost\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Day:\u003C/strong> Duration vs Day - reveals Friday/Wednesday patterns\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot by Reason:\u003C/strong> Duration vs Reason - shows Lunch/Repair as longer stops\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>The Two-Week Teaching Progression:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Week 1: “How bad is it?” → Run chart shows 53% utilization, Pareto shows frequency\u003C/li>\n\u003Cli>Week 2: “Is it consistent? What’s really costing us?” → Compare weeks, drill into individual stoppages\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Comparison Analysis:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>What to Compare\u003C/th>\u003Cth>Week 1\u003C/th>\u003Cth>Week 2\u003C/th>\u003Cth>Insight\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Running %\u003C/td>\u003Ctd>53% avg\u003C/td>\u003Ctd>60% avg\u003C/td>\u003Ctd>Variation between weeks\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Total stops\u003C/td>\u003Ctd>73\u003C/td>\u003Ctd>64\u003C/td>\u003Ctd>Fewer stops, but still too many\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>#1 reason (count)\u003C/td>\u003Ctd>No product (20)\u003C/td>\u003Ctd>No product (16)\u003C/td>\u003Ctd>Same culprit\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Repairs\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>Machine is reliable\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key Insight:\u003C/strong>\nWeek 1 Pareto (by count): “No product” leads\nWeek 2 Pareto (by minutes): “No product” still leads, but relative weights shift\u003C/p>\n\u003Cp>Counting stops ≠ measuring impact. A 42-minute repair counts as “1” but hurts more than four 10-minute stops.\u003C/p>\n\u003Cp>\u003Cstrong>Key learning points:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Simple observation reveals truth\u003C/li>\n\u003Cli>“Capacity problem” was actually a workflow problem\u003C/li>\n\u003Cli>No sensors, no software, no complexity needed\u003C/li>\n\u003Cli>One person, two weeks, pen and paper\u003C/li>\n\u003Cli>The solutions cost nothing - just better organization\u003C/li>\n\u003Cli>Count data vs. measurement data tell different stories\u003C/li>\n\u003Cli>Week-to-week variation shows this isn’t a fluke\u003C/li>\n\u003C/ul>", + { + "headings": 9446, + "localImagePaths": 9513, + "remoteImagePaths": 9514, + "frontmatter": 9515, + "imagePaths": 9516 + }, + [ + 9447, 9450, 9453, 9456, 9459, 9462, 9465, 9468, 9471, 9474, 9477, 9480, 9483, 9486, 9489, 9492, + 9495, 9498, 9501, 9504, 9507, 9510 + ], + { "depth": 30, "slug": 9448, "text": 9449 }, + "case-study-do-we-really-need-a-new-machine", + "Case Study: “Do We Really Need a New Machine?”", + { "depth": 33, "slug": 9451, "text": 9452 }, + "background", + "Background", + { "depth": 33, "slug": 9454, "text": 9455 }, + "week-1-tally-sheet-approach", + "Week 1: Tally Sheet Approach", + { "depth": 79, "slug": 9457, "text": 9458 }, + "daily-tally", + "Daily Tally", + { "depth": 79, "slug": 9460, "text": 9461 }, + "daily-running-time", + "Daily Running Time", + { "depth": 79, "slug": 9463, "text": 9464 }, + "week-1-observations", + "Week 1 Observations", + { "depth": 33, "slug": 9466, "text": 9467 }, + "week-2-detailed-stoppage-log", + "Week 2: Detailed Stoppage Log", + { "depth": 79, "slug": 9469, "text": 9470 }, + "monday", + "Monday", + { "depth": 79, "slug": 9472, "text": 9473 }, + "tuesday", + "Tuesday", + { "depth": 79, "slug": 9475, "text": 9476 }, + "wednesday", + "Wednesday", + { "depth": 79, "slug": 9478, "text": 9479 }, + "thursday", + "Thursday", + { "depth": 79, "slug": 9481, "text": 9482 }, + "friday", + "Friday", + { "depth": 79, "slug": 9484, "text": 9485 }, + "week-2-daily-summary", + "Week 2 Daily Summary", + { "depth": 79, "slug": 9487, "text": 9488 }, + "week-1-vs-week-2-comparison", + "Week 1 vs Week 2 Comparison", + { "depth": 33, "slug": 9490, "text": 9491 }, + "week-2-summary-all-stoppages-for-i-chart-analysis", + "Week 2 Summary: All Stoppages for I-Chart Analysis", + { "depth": 33, "slug": 9493, "text": 9494 }, + "data-summary-for-analysis", + "Data Summary for Analysis", + { "depth": 79, "slug": 9496, "text": 9497 }, + "reason-code-totals-week-2", + "Reason Code Totals (Week 2)", + { "depth": 79, "slug": 9499, "text": 9500 }, + "key-observations-to-discover", + "Key Observations to Discover", + { "depth": 79, "slug": 9502, "text": 9503 }, + "the-insight", + "The Insight", + { "depth": 79, "slug": 9505, "text": 9506 }, + "the-solutions-no-cost", + "The Solutions (No Cost)", + { "depth": 33, "slug": 9508, "text": 9509 }, + "discussion-questions", + "Discussion Questions", + { "depth": 33, "slug": 9511, "text": 9512 }, + "teaching-notes", + "Teaching Notes", + [], + [], + { "title": 9436 }, + [], + "04-cases/packaging", + { "id": 9517, "data": 9519, "body": 9524, "filePath": 9525, "digest": 9526, "rendered": 9527 }, + { + "title": 9520, + "editUrl": 16, + "head": 9521, + "template": 18, + "sidebar": 9522, + "pagefind": 16, + "draft": 20 + }, + "Packaging Line Case", + [], + { "hidden": 20, "attrs": 9523 }, + {}, + "# Packaging Line Case\n\n**Location:** Food packaging facility, Africa\n**Context:** Multi-product packaging line quality analysis\n**Campaign Week:** 9 (Phase 3 - Africa)\n**Website:** /cases/packaging\n\n---\n\n## Overview\n\nA practical case from real work in Africa, demonstrating:\n\n1. **Defect Analysis:** Prioritization using Pareto and tracking over time\n2. **Process Diagnosis:** Connecting defect outcomes to process parameters\n\n---\n\n## The Story\n\n### Part 1: \"Where Should We Focus?\"\n\n**The setup:**\nA packaging facility tracks defects across multiple products. Management wants to reduce defect-related costs but doesn't know where to focus improvement efforts.\n\n**The question:**\nWhich product has the biggest problem, and what type of defects are we seeing?\n\n**VaRiScout analysis:**\n\n- Boxplot: Defect % by product → Product C highest and most variable\n- I-Chart: Defect % over time with target line → recent weeks crossing target\n- Pareto: Defect types → underfill dominates\n- Business translation: Convert defect % to €/week\n\n**The insight:**\n\"We know Product C has an underfill problem costing €X per week.\"\n\n### Part 2: \"What's Driving the Underfill?\"\n\n**The question:**\nDefect counts can't tell us _why_ the underfills happen. What's driving the variation?\n\n**VaRiScout analysis:**\n\n- Histogram: Distribution shape - centered? skewed? bimodal?\n- I-Chart: Fill weights over time - drift? shift?\n- Boxplot: By shift or line - is one factor driving it?\n- Capability: Against spec limits - where does the distribution sit?\n\n**The insight:**\n\"Night shift is systematically underfilling - averaging 495.5g while Day and Evening shifts average 498.5g. Night shift Cpk is below 1.0.\"\n\n---\n\n## Teaching Points\n\n| Concept | What VaRiScout Shows |\n| --------------------- | ------------------------------------------------ |\n| Pareto prioritization | Focus on the vital few defect types |\n| Factor comparison | Boxplot reveals Night shift is different |\n| Two data types | Counts (defects) vs. measurements (fill weights) |\n| Process vs. outcome | Defects show _what_, measurements show _why_ |\n\n---\n\n## Datasets\n\n### 1. Defect Tracking Data (`defects.csv`)\n\n| Column | Type | Description |\n| -------------- | -------- | ------------------------------------------------------------- |\n| Date | Date | Production date |\n| Product | Factor | A, B, C, D |\n| Units_Produced | Integer | Daily production volume |\n| Defect_Count | Integer | Number of defective units |\n| Defect_Type | Category | Seal_Failure, Label_Error, Underfill, Overfill, Contamination |\n| Defect_Percent | Float | Defect_Count / Units_Produced × 100 |\n\n**Built-in patterns:**\n\n- Product C has highest defect rate (~3-4%)\n- Underfill is dominant defect type for Product C\n- Defect rate trending upward over time\n\n### 2. Fill Weight Data (`fillweights.csv`)\n\n| Column | Type | Description |\n| ------------- | -------- | ---------------------------- |\n| Sequence | Integer | Sample sequence number |\n| Timestamp | DateTime | Sample collection time |\n| Fill_Weight_g | Float | Measured fill weight (grams) |\n| Shift | Factor | Day, Evening, Night |\n\n**Built-in patterns:**\n\n- Target: 500g, LSL: 493g\n- Day shift: Mean ~498.5g, stable\n- Evening shift: Mean ~498.5g, stable\n- Night shift: Mean ~495.5g, more variable\n- Night shift has Cpk below 1.0\n\n---\n\n## Key Visuals\n\n1. **Pareto Chart** - Defect types for Product C (Underfill dominates)\n2. **I-Chart** - Fill weights over time with control limits\n3. **Boxplot** - Fill weight by Shift (Night shift lower and wider)\n4. **Capability Analysis** - Distribution vs. spec limits (LSL = 493g)\n\n---\n\n## Business Context (Africa)\n\nThis case reflects real constraints in developing economies:\n\n- Resource constraints: can't fix everything at once, need to prioritize\n- Simple tools: no expensive software, browser-based analysis\n- Practical decisions: where to invest limited improvement resources\n- Cost sensitivity: underweight penalties vs. overfill giveaway\n\n---\n\n## Two-Dataset Lesson\n\nDifferent questions need different data:\n\n| Question | Data Type | Example |\n| -------------------- | -------------------- | -------------------------- |\n| What is happening? | Defect counts | Underfill rate trending up |\n| Why is it happening? | Process measurements | Night shift running 3g low |\n\n---\n\n## VaRiScout Demo Flow\n\n### Module 1: Defect Prioritization\n\n1. Load `defects.csv`\n2. Filter to Product C\n3. Create Pareto chart of defect types\n4. Create I-Chart of defect % over time\n5. Identify: Underfill is the priority\n\n### Module 2: Process Diagnosis\n\n1. Load `fillweights.csv`\n2. Create I-Chart of fill weights\n3. Create Boxplot by Shift\n4. Run Capability analysis (LSL = 493g)\n5. Identify: Night shift is the problem\n\n---\n\n## Core Message\n\n_\"Defect counts tell you WHAT is happening. Process measurements tell you WHY.\"_\n\n---\n\n## Linked Filtering Demonstration\n\n- **Week 1:** Click Product C in boxplot → Pareto updates to show only Product C defect types\n- **Week 2:** Click Night shift in boxplot → I-Chart and histogram update to show only Night shift data\n\n---\n\n_Case developed for VaRiScout Lite demonstration_\n_Origin: Real case from Jukkis's work in Africa_", + "src/content/docs/04-cases/packaging/index.md", + "ef51b3f82f283bbf", + { "html": 9528, "metadata": 9529 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"packaging-line-case\">Packaging Line Case\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#packaging-line-case\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Packaging Line Case”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Location:\u003C/strong> Food packaging facility, Africa\n\u003Cstrong>Context:\u003C/strong> Multi-product packaging line quality analysis\n\u003Cstrong>Campaign Week:\u003C/strong> 9 (Phase 3 - Africa)\n\u003Cstrong>Website:\u003C/strong> /cases/packaging\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A practical case from real work in Africa, demonstrating:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Defect Analysis:\u003C/strong> Prioritization using Pareto and tracking over time\u003C/li>\n\u003Cli>\u003Cstrong>Process Diagnosis:\u003C/strong> Connecting defect outcomes to process parameters\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-story\">The Story\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-story\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Story”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"part-1-where-should-we-focus\">Part 1: “Where Should We Focus?”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#part-1-where-should-we-focus\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 1: “Where Should We Focus?””\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>The setup:\u003C/strong>\nA packaging facility tracks defects across multiple products. Management wants to reduce defect-related costs but doesn’t know where to focus improvement efforts.\u003C/p>\n\u003Cp>\u003Cstrong>The question:\u003C/strong>\nWhich product has the biggest problem, and what type of defects are we seeing?\u003C/p>\n\u003Cp>\u003Cstrong>VaRiScout analysis:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Boxplot: Defect % by product → Product C highest and most variable\u003C/li>\n\u003Cli>I-Chart: Defect % over time with target line → recent weeks crossing target\u003C/li>\n\u003Cli>Pareto: Defect types → underfill dominates\u003C/li>\n\u003Cli>Business translation: Convert defect % to €/week\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>The insight:\u003C/strong>\n“We know Product C has an underfill problem costing €X per week.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"part-2-whats-driving-the-underfill\">Part 2: “What’s Driving the Underfill?”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#part-2-whats-driving-the-underfill\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Part 2: “What’s Driving the Underfill?””\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>The question:\u003C/strong>\nDefect counts can’t tell us \u003Cem>why\u003C/em> the underfills happen. What’s driving the variation?\u003C/p>\n\u003Cp>\u003Cstrong>VaRiScout analysis:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Histogram: Distribution shape - centered? skewed? bimodal?\u003C/li>\n\u003Cli>I-Chart: Fill weights over time - drift? shift?\u003C/li>\n\u003Cli>Boxplot: By shift or line - is one factor driving it?\u003C/li>\n\u003Cli>Capability: Against spec limits - where does the distribution sit?\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>The insight:\u003C/strong>\n“Night shift is systematically underfilling - averaging 495.5g while Day and Evening shifts average 498.5g. Night shift Cpk is below 1.0.”\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teaching-points\">Teaching Points\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teaching-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teaching Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Concept\u003C/th>\u003Cth>What VaRiScout Shows\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Pareto prioritization\u003C/td>\u003Ctd>Focus on the vital few defect types\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Factor comparison\u003C/td>\u003Ctd>Boxplot reveals Night shift is different\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Two data types\u003C/td>\u003Ctd>Counts (defects) vs. measurements (fill weights)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Process vs. outcome\u003C/td>\u003Ctd>Defects show \u003Cem>what\u003C/em>, measurements show \u003Cem>why\u003C/em>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"datasets\">Datasets\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#datasets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Datasets”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-defect-tracking-data-defectscsv\">1. Defect Tracking Data (\u003Ccode dir=\"auto\">defects.csv\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-defect-tracking-data-defectscsv\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Defect Tracking Data (defects.csv)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Column\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Date\u003C/td>\u003Ctd>Date\u003C/td>\u003Ctd>Production date\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Product\u003C/td>\u003Ctd>Factor\u003C/td>\u003Ctd>A, B, C, D\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Units_Produced\u003C/td>\u003Ctd>Integer\u003C/td>\u003Ctd>Daily production volume\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Defect_Count\u003C/td>\u003Ctd>Integer\u003C/td>\u003Ctd>Number of defective units\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Defect_Type\u003C/td>\u003Ctd>Category\u003C/td>\u003Ctd>Seal_Failure, Label_Error, Underfill, Overfill, Contamination\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Defect_Percent\u003C/td>\u003Ctd>Float\u003C/td>\u003Ctd>Defect_Count / Units_Produced × 100\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Built-in patterns:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Product C has highest defect rate (~3-4%)\u003C/li>\n\u003Cli>Underfill is dominant defect type for Product C\u003C/li>\n\u003Cli>Defect rate trending upward over time\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-fill-weight-data-fillweightscsv\">2. Fill Weight Data (\u003Ccode dir=\"auto\">fillweights.csv\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-fill-weight-data-fillweightscsv\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Fill Weight Data (fillweights.csv)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Column\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Sequence\u003C/td>\u003Ctd>Integer\u003C/td>\u003Ctd>Sample sequence number\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Timestamp\u003C/td>\u003Ctd>DateTime\u003C/td>\u003Ctd>Sample collection time\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Fill_Weight_g\u003C/td>\u003Ctd>Float\u003C/td>\u003Ctd>Measured fill weight (grams)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shift\u003C/td>\u003Ctd>Factor\u003C/td>\u003Ctd>Day, Evening, Night\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Built-in patterns:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Target: 500g, LSL: 493g\u003C/li>\n\u003Cli>Day shift: Mean ~498.5g, stable\u003C/li>\n\u003Cli>Evening shift: Mean ~498.5g, stable\u003C/li>\n\u003Cli>Night shift: Mean ~495.5g, more variable\u003C/li>\n\u003Cli>Night shift has Cpk below 1.0\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-visuals\">Key Visuals\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-visuals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Visuals”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Pareto Chart\u003C/strong> - Defect types for Product C (Underfill dominates)\u003C/li>\n\u003Cli>\u003Cstrong>I-Chart\u003C/strong> - Fill weights over time with control limits\u003C/li>\n\u003Cli>\u003Cstrong>Boxplot\u003C/strong> - Fill weight by Shift (Night shift lower and wider)\u003C/li>\n\u003Cli>\u003Cstrong>Capability Analysis\u003C/strong> - Distribution vs. spec limits (LSL = 493g)\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"business-context-africa\">Business Context (Africa)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#business-context-africa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Business Context (Africa)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>This case reflects real constraints in developing economies:\u003C/p>\n\u003Cul>\n\u003Cli>Resource constraints: can’t fix everything at once, need to prioritize\u003C/li>\n\u003Cli>Simple tools: no expensive software, browser-based analysis\u003C/li>\n\u003Cli>Practical decisions: where to invest limited improvement resources\u003C/li>\n\u003Cli>Cost sensitivity: underweight penalties vs. overfill giveaway\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"two-dataset-lesson\">Two-Dataset Lesson\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#two-dataset-lesson\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two-Dataset Lesson”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Different questions need different data:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Question\u003C/th>\u003Cth>Data Type\u003C/th>\u003Cth>Example\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>What is happening?\u003C/td>\u003Ctd>Defect counts\u003C/td>\u003Ctd>Underfill rate trending up\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Why is it happening?\u003C/td>\u003Ctd>Process measurements\u003C/td>\u003Ctd>Night shift running 3g low\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-demo-flow\">VaRiScout Demo Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-demo-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VaRiScout Demo Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"module-1-defect-prioritization\">Module 1: Defect Prioritization\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#module-1-defect-prioritization\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Module 1: Defect Prioritization”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Load \u003Ccode dir=\"auto\">defects.csv\u003C/code>\u003C/li>\n\u003Cli>Filter to Product C\u003C/li>\n\u003Cli>Create Pareto chart of defect types\u003C/li>\n\u003Cli>Create I-Chart of defect % over time\u003C/li>\n\u003Cli>Identify: Underfill is the priority\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"module-2-process-diagnosis\">Module 2: Process Diagnosis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#module-2-process-diagnosis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Module 2: Process Diagnosis”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Load \u003Ccode dir=\"auto\">fillweights.csv\u003C/code>\u003C/li>\n\u003Cli>Create I-Chart of fill weights\u003C/li>\n\u003Cli>Create Boxplot by Shift\u003C/li>\n\u003Cli>Run Capability analysis (LSL = 493g)\u003C/li>\n\u003Cli>Identify: Night shift is the problem\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-message\">Core Message\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-message\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Message”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cem>“Defect counts tell you WHAT is happening. Process measurements tell you WHY.”\u003C/em>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"linked-filtering-demonstration\">Linked Filtering Demonstration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#linked-filtering-demonstration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Linked Filtering Demonstration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Week 1:\u003C/strong> Click Product C in boxplot → Pareto updates to show only Product C defect types\u003C/li>\n\u003Cli>\u003Cstrong>Week 2:\u003C/strong> Click Night shift in boxplot → I-Chart and histogram update to show only Night shift data\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cem>Case developed for VaRiScout Lite demonstration\u003C/em>\n\u003Cem>Origin: Real case from Jukkis’s work in Africa\u003C/em>\u003C/p>", + { + "headings": 9530, + "localImagePaths": 9565, + "remoteImagePaths": 9566, + "frontmatter": 9567, + "imagePaths": 9568 + }, + [ + 9531, 9533, 9534, 9535, 9538, 9541, 9542, 9543, 9546, 9549, 9550, 9553, 9556, 9557, 9560, 9563, + 9564 + ], + { "depth": 30, "slug": 9532, "text": 9520 }, + "packaging-line-case", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 9203, "text": 9204 }, + { "depth": 79, "slug": 9536, "text": 9537 }, + "part-1-where-should-we-focus", + "Part 1: “Where Should We Focus?”", + { "depth": 79, "slug": 9539, "text": 9540 }, + "part-2-whats-driving-the-underfill", + "Part 2: “What’s Driving the Underfill?”", + { "depth": 33, "slug": 9209, "text": 9210 }, + { "depth": 33, "slug": 9212, "text": 9213 }, + { "depth": 79, "slug": 9544, "text": 9545 }, + "1-defect-tracking-data-defectscsv", + "1. Defect Tracking Data (defects.csv)", + { "depth": 79, "slug": 9547, "text": 9548 }, + "2-fill-weight-data-fillweightscsv", + "2. Fill Weight Data (fillweights.csv)", + { "depth": 33, "slug": 9230, "text": 9231 }, + { "depth": 33, "slug": 9551, "text": 9552 }, + "business-context-africa", + "Business Context (Africa)", + { "depth": 33, "slug": 9554, "text": 9555 }, + "two-dataset-lesson", + "Two-Dataset Lesson", + { "depth": 33, "slug": 9233, "text": 9234 }, + { "depth": 79, "slug": 9558, "text": 9559 }, + "module-1-defect-prioritization", + "Module 1: Defect Prioritization", + { "depth": 79, "slug": 9561, "text": 9562 }, + "module-2-process-diagnosis", + "Module 2: Process Diagnosis", + { "depth": 33, "slug": 9240, "text": 9241 }, + { "depth": 33, "slug": 9344, "text": 9345 }, + [], + [], + { "title": 9520 }, + [], + "04-cases/oven-zones", + { "id": 9569, "data": 9571, "body": 9576, "filePath": 9577, "digest": 9578, "rendered": 9579 }, + { + "title": 9572, + "editUrl": 16, + "head": 9573, + "template": 18, + "sidebar": 9574, + "pagefind": 16, + "draft": 20 + }, + "Multi-Zone Oven Temperature Control Case Study", + [], + { "hidden": 20, "attrs": 9575 }, + {}, + "# Multi-Zone Oven Temperature Control Case Study\n\n**Difficulty:** Intermediate\n**Category:** Process Control / Manufacturing\n**Dataset Size:** 100 measurements × 8 temperature zones\n**Analysis Type:** Performance Mode (Multi-Channel Capability Analysis)\n\n## Scenario\n\nYou're a process engineer at an industrial bakery analyzing an 8-zone continuous baking oven. The oven has a temperature profile designed to gradually heat products from 180°C to a peak of 230°C, then cool them back to 180°C for exit.\n\nRecent quality issues suggest temperature control problems in some zones. Your task: identify which zones need maintenance and prioritize repairs.\n\n## Temperature Profile (Target)\n\n```\nZone 1 (Entry): 180°C ±10°C\nZone 2: 200°C ±10°C\nZone 3: 220°C ±10°C ← Problem Area\nZone 4 (Peak): 230°C ±10°C\nZone 5 (Peak): 230°C ±10°C\nZone 6: 220°C ±10°C ← Problem Area\nZone 7: 200°C ±10°C\nZone 8 (Exit): 180°C ±10°C\n```\n\n## Dataset Structure\n\n### Measurements\n\n- **100 observations** from continuous production\n- **8 temperature zones** (Z1_Entry, Z2, Z3, Z4_Peak, Z5_Peak, Z6, Z7, Z8_Exit)\n- Temperature measured in °C with 0.01°C precision\n\n### Factors\n\n- **Product_Type:** Digestive (40%), Shortbread (35%), Oat (25%)\n- **Line_Speed:** Fast (30%), Normal (50%), Slow (20%)\n- **Time_of_Day:** Morning (40%), Afternoon (35%), Night (25%)\n\n## Learning Objectives\n\n### Primary Objectives\n\n1. **Use Pareto analysis** to identify worst-performing zones\n2. **Distinguish Cp vs Cpk issues** (variance vs centering problems)\n3. **Apply the Pareto Principle** (80/20 rule in maintenance prioritization)\n4. **Understand Cpk target values** (industry-specific minimum requirements)\n\n### Secondary Objectives\n\n5. **Multi-factor drill-down** to verify issues are systematic, not product-dependent\n6. **Root cause classification** (equipment issues vs operational issues)\n7. **Maintenance prioritization** based on impact and severity\n\n## Analysis Walkthrough\n\n### Step 1: Load Data & Enter Performance Mode\n\n1. Click **\"Load Sample\"** → Select **\"Multi-Zone Oven Temperature Control\"**\n2. VariScout auto-detects 8 measure columns and suggests **Performance Mode**\n3. Accept Performance Mode to see all 8 zones analyzed simultaneously\n\n**What to observe:**\n\n- Performance Summary shows zone health distribution\n- \"Needs Attention\" count highlights problem zones\n\n### Step 2: Identify Problem Zones (Pareto Chart)\n\nThe **Pareto Chart** ranks zones by Cpk (worst first):\n\n```\nZone 3: Cpk ~0.89 (Critical - Red)\nZone 6: Cpk ~1.07 (Warning - Amber)\nZone 4: Cpk ~1.52 (Capable - Green)\nZone 7: Cpk ~1.85 (Capable - Green)\n...\n```\n\n**Key Insight:** Only 2 of 8 zones (25%) need attention, demonstrating the **Pareto Principle**:\n\n- **Zone 3** is below Cpk = 1.0 (process not capable)\n- **Zone 6** is below Cpk = 1.33 (barely capable)\n\n### Step 3: Diagnose Root Causes (Capability Histograms)\n\nClick on each problem zone to see its distribution:\n\n#### Zone 3 Analysis\n\n**Click \"Z3\" in Pareto chart**\n\n- **Distribution:** Wide, bell-shaped, centered on target (220°C)\n- **Cp:** ~1.48 (width could fit in spec if centered)\n- **Cpk:** ~0.89 (actual process is not capable due to variance)\n- **Root Cause:** **High variance issue** - likely faulty thermocouple causing erratic readings\n- **Fix:** Replace thermocouple in Zone 3\n\n#### Zone 6 Analysis\n\n**Click \"Z6\" in Pareto chart**\n\n- **Distribution:** Narrow, but left-shifted (~212°C instead of 220°C)\n- **Mean:** 212°C (8°C below target)\n- **Cp:** ~1.33 (width could fit if centered)\n- **Cpk:** ~1.07 (centering offset reduces capability)\n- **Root Cause:** **Centering issue** - likely burner fouling causing under-heating\n- **Fix:** Clean burner in Zone 6 to restore proper heating\n\n### Step 4: Adjust Cpk Target (Industry Standards)\n\n**In Performance Dashboard → Adjust \"Target Cpk\" input**\n\nTry different industry standards to see how requirements change:\n\n#### Automotive (Default): Cpk = 1.33\n\n- Zone 3: Below target (Cpk ~0.89) ⚠️\n- Zone 6: Below target (Cpk ~1.07) ⚠️\n- Standard industrial minimum for automotive\n\n#### Aerospace (Strict): Cpk = 2.0\n\n- Zones 3, 6, 4, 7: Below target\n- Demonstrates higher standards for critical applications\n- Only highest-performing zones meet requirement\n\n#### Consumer Goods (Lenient): Cpk = 1.0\n\n- Only Zone 3 below target (Cpk ~0.89)\n- Shows more tolerant standards for non-critical products\n- Zone 6 now considered acceptable\n\n**Teaching Point:** Same data, different target - organizational standards drive what counts as \"capable\"!\n\n### Step 5: Verify Systematic Issues (Drill-Down)\n\n**Add Filter: Product_Type = \"Digestive\"**\n\n**Observation:** Z3 and Z6 issues **persist** across all product types\n\n- η² (eta-squared) contribution from Product_Type is minimal (~2-3%)\n- Confirms issues are **equipment problems**, not product-dependent\n\n**Try filtering by Line_Speed and Time_of_Day** - issues remain consistent.\n\n**Conclusion:** Problems are systematic equipment failures requiring maintenance, not operational adjustments.\n\n## Expected Insights\n\n### Insight 1: Zone 3 - Variance Problem\n\n**Finding:** Zone 3 has critical Cpk (~0.89) due to excessive temperature variance\n**Evidence:**\n\n- Cp = 1.48 (process width could fit in spec)\n- Cpk = 0.89 (actual centering and variance cause failures)\n- Wide distribution (stdDev ~4.5°C vs target ~2.0°C)\n\n**Root Cause:** Faulty thermocouple causing erratic temperature readings\n**Recommendation:** Replace thermocouple sensor in Zone 3\n**Impact:** High - this zone is producing out-of-spec product\n\n### Insight 2: Zone 6 - Centering Problem\n\n**Finding:** Zone 6 has warning-level Cpk (~1.07) due to 8°C offset below target\n**Evidence:**\n\n- Mean = 212°C (target = 220°C)\n- Cp = 1.33 (distribution width is acceptable)\n- Cpk = 1.07 (centering offset reduces capability)\n- Left-shifted distribution\n\n**Root Cause:** Burner fouling causing under-heating\n**Recommendation:** Clean burner assembly and verify gas flow\n**Impact:** Medium - process is barely capable, risk of future issues\n\n### Insight 3: Pareto Principle Validation\n\n**Finding:** 2 of 8 zones (25%) account for 100% of flagged issues\n**Strategy:** Focus maintenance resources on these 2 zones rather than blanket maintenance\n**Cost Savings:** Targeted repairs vs full oven shutdown\n**Priority:** Fix Z3 first (critical), then Z6 (warning)\n\n### Insight 4: Product-Independent Issues\n\n**Finding:** η² contribution from Product_Type, Line_Speed, and Time_of_Day is minimal (\u003C5% combined)\n**Conclusion:** Issues are equipment failures, not operational or product-specific\n**Action:** Maintenance team (not production team) responsible for resolution\n\n## Key Concepts Demonstrated\n\n### 1. Cp vs Cpk Distinction\n\n| Metric | Zone 3 | Zone 6 | Interpretation |\n| --------- | ---------------- | ----------- | --------------------------------------- |\n| **Cp** | 1.48 | 1.33 | Process width relative to spec width |\n| **Cpk** | 0.89 | 1.07 | Actual capability considering centering |\n| **Issue** | Variance | Centering | Root cause type |\n| **Fix** | Reduce variation | Adjust mean | Corrective action |\n\n### 2. Pareto Principle (80/20 Rule)\n\n- **Traditional:** 80% of effects from 20% of causes\n- **This case:** 100% of issues from 25% of zones (2 of 8)\n- **Implication:** Targeted maintenance is more efficient than blanket maintenance\n\n### 3. Cpk Target Values\n\nDifferent industries have different minimum Cpk requirements:\n\n- **Aerospace/Medical:** Cpk ≥ 2.0 for \"capable\" (near-zero defects)\n- **Automotive:** Cpk ≥ 1.33 (industry standard, ~63 PPM defects)\n- **Food/Consumer:** Cpk ≥ 1.0 may be acceptable (lower criticality)\n\nAdjusting the target value shows how the same data is interpreted differently based on organizational standards and industry requirements.\n\n### 4. Multi-Factor Analysis\n\nDrill-down by Product, Speed, and Shift confirms issues are:\n\n- **Systematic:** Present across all conditions\n- **Equipment-related:** Not operational or product-specific\n- **Maintenance-focused:** Require mechanical fixes, not process tuning\n\n## Teaching Guide (For Instructors)\n\n### Session Structure (60 minutes)\n\n#### Introduction (10 min)\n\n- Present scenario: industrial baking oven with quality issues\n- Explain temperature profile (entry → peak → exit)\n- Frame question: \"Which zones need maintenance?\"\n\n#### Analysis Phase 1: Identification (15 min)\n\n- Load data and enter Performance Mode\n- Use Pareto chart to identify Z3 and Z6\n- Discuss \"needs attention\" count and Pareto ranking\n\n#### Analysis Phase 2: Diagnosis (15 min)\n\n- Click Z3 → diagnose variance issue (Cp vs Cpk)\n- Click Z6 → diagnose centering issue (left-shifted distribution)\n- Differentiate between variance and centering problems\n\n#### Advanced Analysis: Verification (10 min)\n\n- Drill down by Product_Type to verify systematic issues\n- Check η² contribution (low = equipment problem)\n- Confirm issues are not product/speed dependent\n\n#### Discussion: Threshold Impact (10 min)\n\n- Adjust thresholds to aerospace standards (1.5, 2.0, 2.5)\n- Observe more zones flagged\n- Discuss industry-specific standards and context\n\n#### Conclusion: Actionable Recommendations (10 min)\n\n- Prioritize repairs: Z3 (critical) before Z6 (warning)\n- Explain Pareto principle in maintenance strategy\n- Calculate cost/benefit of targeted vs blanket maintenance\n\n### Discussion Questions\n\n1. **Why is Zone 3's Cp higher than its Cpk?** (Variance issue vs centering)\n2. **What would happen if we adjusted the Zone 6 mean by 8°C?** (Cpk would improve to ~1.8)\n3. **Why doesn't Product_Type explain the variance?** (Equipment issue, not product-specific)\n4. **Should we repair all zones or just Z3 and Z6?** (Pareto principle discussion)\n5. **How do aerospace vs consumer goods standards change the analysis?** (Threshold customization)\n\n### Common Student Mistakes\n\n1. **Confusing Cp and Cpk** - Emphasize Cp = potential, Cpk = actual\n2. **Blaming products** - Show low η² proves it's equipment, not products\n3. **Over-maintenance** - Pareto principle: fix 2 zones, not all 8\n4. **Ignoring context** - Thresholds depend on industry requirements\n\n## Data Export\n\nThe raw data is available as CSV for external analysis:\n\n```csv\nMeasurement_ID,Product_Type,Line_Speed,Time_of_Day,Z1_Entry,Z2,Z3,Z4_Peak,Z5_Peak,Z6,Z7,Z8_Exit\n1,Digestive,Normal,Morning,180.23,200.45,221.34,230.12,229.87,212.45,200.23,180.11\n...\n```\n\nExport from VariScout via **Settings → Export Analysis** for use in Minitab, JMP, or Excel.\n\n## Related Case Studies\n\n- **Sachets (Fill Weight Variability):** Another multi-channel capability analysis (discrete manufacturing)\n- **Coffee Roaster (Temperature Control):** Single-channel temperature control with similar Cp/Cpk concepts\n- **Bottleneck Analysis:** Demonstrates Pareto principle in a different context (throughput)\n\n## Technical Notes\n\n### Statistical Details\n\n- **Tolerance:** ±10°C for all zones (2σ approach)\n- **Sample Size:** n=100 per zone (adequate for capability analysis)\n- **Distribution:** Normal (validated via probability plots)\n- **Measurement System:** Assumed capable (no MSA issues)\n\n### Data Generation\n\nData generated using Box-Muller transform for normal distributions:\n\n- Zone 3: mean=220°C, σ=4.5°C (high variance)\n- Zone 6: mean=212°C, σ=2.5°C (centering offset)\n- Other zones: σ=1.5-2.2°C (good control)\n\n### Thresholds Used\n\n- **Default (Automotive):** Critical \u003C 1.0, Warning \u003C 1.33, Capable \u003C 1.67\n- **Aerospace:** Critical \u003C 1.5, Warning \u003C 2.0, Capable \u003C 2.5\n- **Consumer Goods:** Critical \u003C 0.67, Warning \u003C 1.0, Capable \u003C 1.33\n\n---\n\n**Case Study Author:** VariScout Development Team\n**Version:** 1.0\n**Last Updated:** February 2026\n**License:** Educational use permitted with attribution", + "src/content/docs/04-cases/oven-zones/index.md", + "a37502646b8b4e75", + { "html": 9580, "metadata": 9581 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"multi-zone-oven-temperature-control-case-study\">Multi-Zone Oven Temperature Control Case Study\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#multi-zone-oven-temperature-control-case-study\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Multi-Zone Oven Temperature Control Case Study”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Difficulty:\u003C/strong> Intermediate\n\u003Cstrong>Category:\u003C/strong> Process Control / Manufacturing\n\u003Cstrong>Dataset Size:\u003C/strong> 100 measurements × 8 temperature zones\n\u003Cstrong>Analysis Type:\u003C/strong> Performance Mode (Multi-Channel Capability Analysis)\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"scenario\">Scenario\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#scenario\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scenario”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>You’re a process engineer at an industrial bakery analyzing an 8-zone continuous baking oven. The oven has a temperature profile designed to gradually heat products from 180°C to a peak of 230°C, then cool them back to 180°C for exit.\u003C/p>\n\u003Cp>Recent quality issues suggest temperature control problems in some zones. Your task: identify which zones need maintenance and prioritize repairs.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"temperature-profile-target\">Temperature Profile (Target)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#temperature-profile-target\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Temperature Profile (Target)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 1 (Entry): 180°C ±10°C\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 2: 200°C ±10°C\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 3: 220°C ±10°C ← Problem Area\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 4 (Peak): 230°C ±10°C\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 5 (Peak): 230°C ±10°C\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 6: 220°C ±10°C ← Problem Area\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 7: 200°C ±10°C\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 8 (Exit): 180°C ±10°C\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Zone 1 (Entry): 180°C ±10°CZone 2: 200°C ±10°CZone 3: 220°C ±10°C ← Problem AreaZone 4 (Peak): 230°C ±10°CZone 5 (Peak): 230°C ±10°CZone 6: 220°C ±10°C ← Problem AreaZone 7: 200°C ±10°CZone 8 (Exit): 180°C ±10°C\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dataset-structure\">Dataset Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dataset-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dataset Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"measurements\">Measurements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#measurements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Measurements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>100 observations\u003C/strong> from continuous production\u003C/li>\n\u003Cli>\u003Cstrong>8 temperature zones\u003C/strong> (Z1_Entry, Z2, Z3, Z4_Peak, Z5_Peak, Z6, Z7, Z8_Exit)\u003C/li>\n\u003Cli>Temperature measured in °C with 0.01°C precision\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"factors\">Factors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#factors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Factors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Product_Type:\u003C/strong> Digestive (40%), Shortbread (35%), Oat (25%)\u003C/li>\n\u003Cli>\u003Cstrong>Line_Speed:\u003C/strong> Fast (30%), Normal (50%), Slow (20%)\u003C/li>\n\u003Cli>\u003Cstrong>Time_of_Day:\u003C/strong> Morning (40%), Afternoon (35%), Night (25%)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"learning-objectives\">Learning Objectives\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#learning-objectives\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Learning Objectives”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"primary-objectives\">Primary Objectives\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#primary-objectives\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Primary Objectives”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Use Pareto analysis\u003C/strong> to identify worst-performing zones\u003C/li>\n\u003Cli>\u003Cstrong>Distinguish Cp vs Cpk issues\u003C/strong> (variance vs centering problems)\u003C/li>\n\u003Cli>\u003Cstrong>Apply the Pareto Principle\u003C/strong> (80/20 rule in maintenance prioritization)\u003C/li>\n\u003Cli>\u003Cstrong>Understand Cpk target values\u003C/strong> (industry-specific minimum requirements)\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"secondary-objectives\">Secondary Objectives\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#secondary-objectives\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Secondary Objectives”\u003C/span>\u003C/a>\u003C/div>\n\u003Col start=\"5\">\n\u003Cli>\u003Cstrong>Multi-factor drill-down\u003C/strong> to verify issues are systematic, not product-dependent\u003C/li>\n\u003Cli>\u003Cstrong>Root cause classification\u003C/strong> (equipment issues vs operational issues)\u003C/li>\n\u003Cli>\u003Cstrong>Maintenance prioritization\u003C/strong> based on impact and severity\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysis-walkthrough\">Analysis Walkthrough\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-walkthrough\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis Walkthrough”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-1-load-data--enter-performance-mode\">Step 1: Load Data & Enter Performance Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-1-load-data--enter-performance-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 1: Load Data & Enter Performance Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Click \u003Cstrong>“Load Sample”\u003C/strong> → Select \u003Cstrong>“Multi-Zone Oven Temperature Control”\u003C/strong>\u003C/li>\n\u003Cli>VariScout auto-detects 8 measure columns and suggests \u003Cstrong>Performance Mode\u003C/strong>\u003C/li>\n\u003Cli>Accept Performance Mode to see all 8 zones analyzed simultaneously\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>What to observe:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Performance Summary shows zone health distribution\u003C/li>\n\u003Cli>“Needs Attention” count highlights problem zones\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-2-identify-problem-zones-pareto-chart\">Step 2: Identify Problem Zones (Pareto Chart)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-2-identify-problem-zones-pareto-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 2: Identify Problem Zones (Pareto Chart)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Cstrong>Pareto Chart\u003C/strong> ranks zones by Cpk (worst first):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 3: Cpk ~0.89 (Critical - Red)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 6: Cpk ~1.07 (Warning - Amber)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 4: Cpk ~1.52 (Capable - Green)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Zone 7: Cpk ~1.85 (Capable - Green)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">...\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Zone 3: Cpk ~0.89 (Critical - Red)Zone 6: Cpk ~1.07 (Warning - Amber)Zone 4: Cpk ~1.52 (Capable - Green)Zone 7: Cpk ~1.85 (Capable - Green)...\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Key Insight:\u003C/strong> Only 2 of 8 zones (25%) need attention, demonstrating the \u003Cstrong>Pareto Principle\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Zone 3\u003C/strong> is below Cpk = 1.0 (process not capable)\u003C/li>\n\u003Cli>\u003Cstrong>Zone 6\u003C/strong> is below Cpk = 1.33 (barely capable)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-3-diagnose-root-causes-capability-histograms\">Step 3: Diagnose Root Causes (Capability Histograms)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-3-diagnose-root-causes-capability-histograms\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 3: Diagnose Root Causes (Capability Histograms)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click on each problem zone to see its distribution:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"zone-3-analysis\">Zone 3 Analysis\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#zone-3-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Zone 3 Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Click “Z3” in Pareto chart\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Distribution:\u003C/strong> Wide, bell-shaped, centered on target (220°C)\u003C/li>\n\u003Cli>\u003Cstrong>Cp:\u003C/strong> ~1.48 (width could fit in spec if centered)\u003C/li>\n\u003Cli>\u003Cstrong>Cpk:\u003C/strong> ~0.89 (actual process is not capable due to variance)\u003C/li>\n\u003Cli>\u003Cstrong>Root Cause:\u003C/strong> \u003Cstrong>High variance issue\u003C/strong> - likely faulty thermocouple causing erratic readings\u003C/li>\n\u003Cli>\u003Cstrong>Fix:\u003C/strong> Replace thermocouple in Zone 3\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"zone-6-analysis\">Zone 6 Analysis\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#zone-6-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Zone 6 Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Click “Z6” in Pareto chart\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Distribution:\u003C/strong> Narrow, but left-shifted (~212°C instead of 220°C)\u003C/li>\n\u003Cli>\u003Cstrong>Mean:\u003C/strong> 212°C (8°C below target)\u003C/li>\n\u003Cli>\u003Cstrong>Cp:\u003C/strong> ~1.33 (width could fit if centered)\u003C/li>\n\u003Cli>\u003Cstrong>Cpk:\u003C/strong> ~1.07 (centering offset reduces capability)\u003C/li>\n\u003Cli>\u003Cstrong>Root Cause:\u003C/strong> \u003Cstrong>Centering issue\u003C/strong> - likely burner fouling causing under-heating\u003C/li>\n\u003Cli>\u003Cstrong>Fix:\u003C/strong> Clean burner in Zone 6 to restore proper heating\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-4-adjust-cpk-target-industry-standards\">Step 4: Adjust Cpk Target (Industry Standards)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-4-adjust-cpk-target-industry-standards\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 4: Adjust Cpk Target (Industry Standards)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>In Performance Dashboard → Adjust “Target Cpk” input\u003C/strong>\u003C/p>\n\u003Cp>Try different industry standards to see how requirements change:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"automotive-default-cpk--133\">Automotive (Default): Cpk = 1.33\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#automotive-default-cpk--133\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Automotive (Default): Cpk = 1.33”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Zone 3: Below target (Cpk ~0.89) ⚠️\u003C/li>\n\u003Cli>Zone 6: Below target (Cpk ~1.07) ⚠️\u003C/li>\n\u003Cli>Standard industrial minimum for automotive\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"aerospace-strict-cpk--20\">Aerospace (Strict): Cpk = 2.0\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#aerospace-strict-cpk--20\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Aerospace (Strict): Cpk = 2.0”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Zones 3, 6, 4, 7: Below target\u003C/li>\n\u003Cli>Demonstrates higher standards for critical applications\u003C/li>\n\u003Cli>Only highest-performing zones meet requirement\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"consumer-goods-lenient-cpk--10\">Consumer Goods (Lenient): Cpk = 1.0\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#consumer-goods-lenient-cpk--10\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Consumer Goods (Lenient): Cpk = 1.0”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Only Zone 3 below target (Cpk ~0.89)\u003C/li>\n\u003Cli>Shows more tolerant standards for non-critical products\u003C/li>\n\u003Cli>Zone 6 now considered acceptable\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Teaching Point:\u003C/strong> Same data, different target - organizational standards drive what counts as “capable”!\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-5-verify-systematic-issues-drill-down\">Step 5: Verify Systematic Issues (Drill-Down)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-5-verify-systematic-issues-drill-down\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step 5: Verify Systematic Issues (Drill-Down)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Add Filter: Product_Type = “Digestive”\u003C/strong>\u003C/p>\n\u003Cp>\u003Cstrong>Observation:\u003C/strong> Z3 and Z6 issues \u003Cstrong>persist\u003C/strong> across all product types\u003C/p>\n\u003Cul>\n\u003Cli>η² (eta-squared) contribution from Product_Type is minimal (~2-3%)\u003C/li>\n\u003Cli>Confirms issues are \u003Cstrong>equipment problems\u003C/strong>, not product-dependent\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Try filtering by Line_Speed and Time_of_Day\u003C/strong> - issues remain consistent.\u003C/p>\n\u003Cp>\u003Cstrong>Conclusion:\u003C/strong> Problems are systematic equipment failures requiring maintenance, not operational adjustments.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"expected-insights\">Expected Insights\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#expected-insights\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Expected Insights”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"insight-1-zone-3---variance-problem\">Insight 1: Zone 3 - Variance Problem\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#insight-1-zone-3---variance-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Insight 1: Zone 3 - Variance Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Finding:\u003C/strong> Zone 3 has critical Cpk (~0.89) due to excessive temperature variance\n\u003Cstrong>Evidence:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Cp = 1.48 (process width could fit in spec)\u003C/li>\n\u003Cli>Cpk = 0.89 (actual centering and variance cause failures)\u003C/li>\n\u003Cli>Wide distribution (stdDev ~4.5°C vs target ~2.0°C)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Root Cause:\u003C/strong> Faulty thermocouple causing erratic temperature readings\n\u003Cstrong>Recommendation:\u003C/strong> Replace thermocouple sensor in Zone 3\n\u003Cstrong>Impact:\u003C/strong> High - this zone is producing out-of-spec product\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"insight-2-zone-6---centering-problem\">Insight 2: Zone 6 - Centering Problem\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#insight-2-zone-6---centering-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Insight 2: Zone 6 - Centering Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Finding:\u003C/strong> Zone 6 has warning-level Cpk (~1.07) due to 8°C offset below target\n\u003Cstrong>Evidence:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Mean = 212°C (target = 220°C)\u003C/li>\n\u003Cli>Cp = 1.33 (distribution width is acceptable)\u003C/li>\n\u003Cli>Cpk = 1.07 (centering offset reduces capability)\u003C/li>\n\u003Cli>Left-shifted distribution\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Root Cause:\u003C/strong> Burner fouling causing under-heating\n\u003Cstrong>Recommendation:\u003C/strong> Clean burner assembly and verify gas flow\n\u003Cstrong>Impact:\u003C/strong> Medium - process is barely capable, risk of future issues\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"insight-3-pareto-principle-validation\">Insight 3: Pareto Principle Validation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#insight-3-pareto-principle-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Insight 3: Pareto Principle Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Finding:\u003C/strong> 2 of 8 zones (25%) account for 100% of flagged issues\n\u003Cstrong>Strategy:\u003C/strong> Focus maintenance resources on these 2 zones rather than blanket maintenance\n\u003Cstrong>Cost Savings:\u003C/strong> Targeted repairs vs full oven shutdown\n\u003Cstrong>Priority:\u003C/strong> Fix Z3 first (critical), then Z6 (warning)\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"insight-4-product-independent-issues\">Insight 4: Product-Independent Issues\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#insight-4-product-independent-issues\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Insight 4: Product-Independent Issues”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Finding:\u003C/strong> η² contribution from Product_Type, Line_Speed, and Time_of_Day is minimal (<5% combined)\n\u003Cstrong>Conclusion:\u003C/strong> Issues are equipment failures, not operational or product-specific\n\u003Cstrong>Action:\u003C/strong> Maintenance team (not production team) responsible for resolution\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-concepts-demonstrated\">Key Concepts Demonstrated\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-concepts-demonstrated\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Concepts Demonstrated”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-cp-vs-cpk-distinction\">1. Cp vs Cpk Distinction\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-cp-vs-cpk-distinction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Cp vs Cpk Distinction”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Metric\u003C/th>\u003Cth>Zone 3\u003C/th>\u003Cth>Zone 6\u003C/th>\u003Cth>Interpretation\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Cp\u003C/strong>\u003C/td>\u003Ctd>1.48\u003C/td>\u003Ctd>1.33\u003C/td>\u003Ctd>Process width relative to spec width\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Cpk\u003C/strong>\u003C/td>\u003Ctd>0.89\u003C/td>\u003Ctd>1.07\u003C/td>\u003Ctd>Actual capability considering centering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Issue\u003C/strong>\u003C/td>\u003Ctd>Variance\u003C/td>\u003Ctd>Centering\u003C/td>\u003Ctd>Root cause type\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Fix\u003C/strong>\u003C/td>\u003Ctd>Reduce variation\u003C/td>\u003Ctd>Adjust mean\u003C/td>\u003Ctd>Corrective action\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-pareto-principle-8020-rule\">2. Pareto Principle (80/20 Rule)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-pareto-principle-8020-rule\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Pareto Principle (80/20 Rule)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Traditional:\u003C/strong> 80% of effects from 20% of causes\u003C/li>\n\u003Cli>\u003Cstrong>This case:\u003C/strong> 100% of issues from 25% of zones (2 of 8)\u003C/li>\n\u003Cli>\u003Cstrong>Implication:\u003C/strong> Targeted maintenance is more efficient than blanket maintenance\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-cpk-target-values\">3. Cpk Target Values\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-cpk-target-values\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Cpk Target Values”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Different industries have different minimum Cpk requirements:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Aerospace/Medical:\u003C/strong> Cpk ≥ 2.0 for “capable” (near-zero defects)\u003C/li>\n\u003Cli>\u003Cstrong>Automotive:\u003C/strong> Cpk ≥ 1.33 (industry standard, ~63 PPM defects)\u003C/li>\n\u003Cli>\u003Cstrong>Food/Consumer:\u003C/strong> Cpk ≥ 1.0 may be acceptable (lower criticality)\u003C/li>\n\u003C/ul>\n\u003Cp>Adjusting the target value shows how the same data is interpreted differently based on organizational standards and industry requirements.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-multi-factor-analysis\">4. Multi-Factor Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-multi-factor-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Multi-Factor Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Drill-down by Product, Speed, and Shift confirms issues are:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Systematic:\u003C/strong> Present across all conditions\u003C/li>\n\u003Cli>\u003Cstrong>Equipment-related:\u003C/strong> Not operational or product-specific\u003C/li>\n\u003Cli>\u003Cstrong>Maintenance-focused:\u003C/strong> Require mechanical fixes, not process tuning\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teaching-guide-for-instructors\">Teaching Guide (For Instructors)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teaching-guide-for-instructors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teaching Guide (For Instructors)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"session-structure-60-minutes\">Session Structure (60 minutes)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#session-structure-60-minutes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Session Structure (60 minutes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"introduction-10-min\">Introduction (10 min)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#introduction-10-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Introduction (10 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Present scenario: industrial baking oven with quality issues\u003C/li>\n\u003Cli>Explain temperature profile (entry → peak → exit)\u003C/li>\n\u003Cli>Frame question: “Which zones need maintenance?”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"analysis-phase-1-identification-15-min\">Analysis Phase 1: Identification (15 min)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-phase-1-identification-15-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis Phase 1: Identification (15 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Load data and enter Performance Mode\u003C/li>\n\u003Cli>Use Pareto chart to identify Z3 and Z6\u003C/li>\n\u003Cli>Discuss “needs attention” count and Pareto ranking\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"analysis-phase-2-diagnosis-15-min\">Analysis Phase 2: Diagnosis (15 min)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-phase-2-diagnosis-15-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis Phase 2: Diagnosis (15 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Click Z3 → diagnose variance issue (Cp vs Cpk)\u003C/li>\n\u003Cli>Click Z6 → diagnose centering issue (left-shifted distribution)\u003C/li>\n\u003Cli>Differentiate between variance and centering problems\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"advanced-analysis-verification-10-min\">Advanced Analysis: Verification (10 min)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#advanced-analysis-verification-10-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Advanced Analysis: Verification (10 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Drill down by Product_Type to verify systematic issues\u003C/li>\n\u003Cli>Check η² contribution (low = equipment problem)\u003C/li>\n\u003Cli>Confirm issues are not product/speed dependent\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"discussion-threshold-impact-10-min\">Discussion: Threshold Impact (10 min)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#discussion-threshold-impact-10-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Discussion: Threshold Impact (10 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Adjust thresholds to aerospace standards (1.5, 2.0, 2.5)\u003C/li>\n\u003Cli>Observe more zones flagged\u003C/li>\n\u003Cli>Discuss industry-specific standards and context\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"conclusion-actionable-recommendations-10-min\">Conclusion: Actionable Recommendations (10 min)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#conclusion-actionable-recommendations-10-min\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Conclusion: Actionable Recommendations (10 min)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Prioritize repairs: Z3 (critical) before Z6 (warning)\u003C/li>\n\u003Cli>Explain Pareto principle in maintenance strategy\u003C/li>\n\u003Cli>Calculate cost/benefit of targeted vs blanket maintenance\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"discussion-questions\">Discussion Questions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#discussion-questions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Discussion Questions”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Why is Zone 3’s Cp higher than its Cpk?\u003C/strong> (Variance issue vs centering)\u003C/li>\n\u003Cli>\u003Cstrong>What would happen if we adjusted the Zone 6 mean by 8°C?\u003C/strong> (Cpk would improve to ~1.8)\u003C/li>\n\u003Cli>\u003Cstrong>Why doesn’t Product_Type explain the variance?\u003C/strong> (Equipment issue, not product-specific)\u003C/li>\n\u003Cli>\u003Cstrong>Should we repair all zones or just Z3 and Z6?\u003C/strong> (Pareto principle discussion)\u003C/li>\n\u003Cli>\u003Cstrong>How do aerospace vs consumer goods standards change the analysis?\u003C/strong> (Threshold customization)\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"common-student-mistakes\">Common Student Mistakes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#common-student-mistakes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Student Mistakes”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Confusing Cp and Cpk\u003C/strong> - Emphasize Cp = potential, Cpk = actual\u003C/li>\n\u003Cli>\u003Cstrong>Blaming products\u003C/strong> - Show low η² proves it’s equipment, not products\u003C/li>\n\u003Cli>\u003Cstrong>Over-maintenance\u003C/strong> - Pareto principle: fix 2 zones, not all 8\u003C/li>\n\u003Cli>\u003Cstrong>Ignoring context\u003C/strong> - Thresholds depend on industry requirements\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-export\">Data Export\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-export\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Export”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The raw data is available as CSV for external analysis:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"csv\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Measurement_ID,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Product_Type,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Line_Speed,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Time_of_Day,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Z1_Entry,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">Z2,\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Z3,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Z4_Peak,Z5_Peak,\u003C/span>\u003Cspan style=\"--0:#FFFFFF;--1:#BB2060\">Z6,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Z7,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Z8_Exit\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">1,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Digestive,\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Normal,\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">Morning,\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">180.23,\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">200.45,\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">221.34,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">230.12,229.87,\u003C/span>\u003Cspan style=\"--0:#FFFFFF;--1:#BB2060\">212.45,\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">200.23,\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">180.11\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Measurement_ID,Product_Type,Line_Speed,Time_of_Day,Z1_Entry,Z2,Z3,Z4_Peak,Z5_Peak,Z6,Z7,Z8_Exit1,Digestive,Normal,Morning,180.23,200.45,221.34,230.12,229.87,212.45,200.23,180.11...\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Export from VariScout via \u003Cstrong>Settings → Export Analysis\u003C/strong> for use in Minitab, JMP, or Excel.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-case-studies\">Related Case Studies\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-case-studies\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Case Studies”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Sachets (Fill Weight Variability):\u003C/strong> Another multi-channel capability analysis (discrete manufacturing)\u003C/li>\n\u003Cli>\u003Cstrong>Coffee Roaster (Temperature Control):\u003C/strong> Single-channel temperature control with similar Cp/Cpk concepts\u003C/li>\n\u003Cli>\u003Cstrong>Bottleneck Analysis:\u003C/strong> Demonstrates Pareto principle in a different context (throughput)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-notes\">Technical Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"statistical-details\">Statistical Details\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#statistical-details\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Statistical Details”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Tolerance:\u003C/strong> ±10°C for all zones (2σ approach)\u003C/li>\n\u003Cli>\u003Cstrong>Sample Size:\u003C/strong> n=100 per zone (adequate for capability analysis)\u003C/li>\n\u003Cli>\u003Cstrong>Distribution:\u003C/strong> Normal (validated via probability plots)\u003C/li>\n\u003Cli>\u003Cstrong>Measurement System:\u003C/strong> Assumed capable (no MSA issues)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-generation\">Data Generation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-generation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Generation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Data generated using Box-Muller transform for normal distributions:\u003C/p>\n\u003Cul>\n\u003Cli>Zone 3: mean=220°C, σ=4.5°C (high variance)\u003C/li>\n\u003Cli>Zone 6: mean=212°C, σ=2.5°C (centering offset)\u003C/li>\n\u003Cli>Other zones: σ=1.5-2.2°C (good control)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"thresholds-used\">Thresholds Used\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#thresholds-used\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Thresholds Used”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Default (Automotive):\u003C/strong> Critical < 1.0, Warning < 1.33, Capable < 1.67\u003C/li>\n\u003Cli>\u003Cstrong>Aerospace:\u003C/strong> Critical < 1.5, Warning < 2.0, Capable < 2.5\u003C/li>\n\u003Cli>\u003Cstrong>Consumer Goods:\u003C/strong> Critical < 0.67, Warning < 1.0, Capable < 1.33\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cp>\u003Cstrong>Case Study Author:\u003C/strong> VariScout Development Team\n\u003Cstrong>Version:\u003C/strong> 1.0\n\u003Cstrong>Last Updated:\u003C/strong> February 2026\n\u003Cstrong>License:\u003C/strong> Educational use permitted with attribution\u003C/p>", + { + "headings": 9582, + "localImagePaths": 9712, + "remoteImagePaths": 9713, + "frontmatter": 9714, + "imagePaths": 9715 + }, + [ + 9583, 9585, 9586, 9589, 9592, 9595, 9598, 9601, 9604, 9607, 9610, 9613, 9616, 9619, 9622, 9625, + 9628, 9631, 9634, 9637, 9640, 9643, 9646, 9649, 9652, 9655, 9658, 9661, 9664, 9667, 9670, 9673, + 9676, 9679, 9682, 9685, 9688, 9691, 9694, 9695, 9698, 9699, 9702, 9703, 9706, 9709 + ], + { "depth": 30, "slug": 9584, "text": 9572 }, + "multi-zone-oven-temperature-control-case-study", + { "depth": 33, "slug": 7562, "text": 7563 }, + { "depth": 33, "slug": 9587, "text": 9588 }, + "temperature-profile-target", + "Temperature Profile (Target)", + { "depth": 33, "slug": 9590, "text": 9591 }, + "dataset-structure", + "Dataset Structure", + { "depth": 79, "slug": 9593, "text": 9594 }, + "measurements", + "Measurements", + { "depth": 79, "slug": 9596, "text": 9597 }, + "factors", + "Factors", + { "depth": 33, "slug": 9599, "text": 9600 }, + "learning-objectives", + "Learning Objectives", + { "depth": 79, "slug": 9602, "text": 9603 }, + "primary-objectives", + "Primary Objectives", + { "depth": 79, "slug": 9605, "text": 9606 }, + "secondary-objectives", + "Secondary Objectives", + { "depth": 33, "slug": 9608, "text": 9609 }, + "analysis-walkthrough", + "Analysis Walkthrough", + { "depth": 79, "slug": 9611, "text": 9612 }, + "step-1-load-data--enter-performance-mode", + "Step 1: Load Data & Enter Performance Mode", + { "depth": 79, "slug": 9614, "text": 9615 }, + "step-2-identify-problem-zones-pareto-chart", + "Step 2: Identify Problem Zones (Pareto Chart)", + { "depth": 79, "slug": 9617, "text": 9618 }, + "step-3-diagnose-root-causes-capability-histograms", + "Step 3: Diagnose Root Causes (Capability Histograms)", + { "depth": 621, "slug": 9620, "text": 9621 }, + "zone-3-analysis", + "Zone 3 Analysis", + { "depth": 621, "slug": 9623, "text": 9624 }, + "zone-6-analysis", + "Zone 6 Analysis", + { "depth": 79, "slug": 9626, "text": 9627 }, + "step-4-adjust-cpk-target-industry-standards", + "Step 4: Adjust Cpk Target (Industry Standards)", + { "depth": 621, "slug": 9629, "text": 9630 }, + "automotive-default-cpk--133", + "Automotive (Default): Cpk = 1.33", + { "depth": 621, "slug": 9632, "text": 9633 }, + "aerospace-strict-cpk--20", + "Aerospace (Strict): Cpk = 2.0", + { "depth": 621, "slug": 9635, "text": 9636 }, + "consumer-goods-lenient-cpk--10", + "Consumer Goods (Lenient): Cpk = 1.0", + { "depth": 79, "slug": 9638, "text": 9639 }, + "step-5-verify-systematic-issues-drill-down", + "Step 5: Verify Systematic Issues (Drill-Down)", + { "depth": 33, "slug": 9641, "text": 9642 }, + "expected-insights", + "Expected Insights", + { "depth": 79, "slug": 9644, "text": 9645 }, + "insight-1-zone-3---variance-problem", + "Insight 1: Zone 3 - Variance Problem", + { "depth": 79, "slug": 9647, "text": 9648 }, + "insight-2-zone-6---centering-problem", + "Insight 2: Zone 6 - Centering Problem", + { "depth": 79, "slug": 9650, "text": 9651 }, + "insight-3-pareto-principle-validation", + "Insight 3: Pareto Principle Validation", + { "depth": 79, "slug": 9653, "text": 9654 }, + "insight-4-product-independent-issues", + "Insight 4: Product-Independent Issues", + { "depth": 33, "slug": 9656, "text": 9657 }, + "key-concepts-demonstrated", + "Key Concepts Demonstrated", + { "depth": 79, "slug": 9659, "text": 9660 }, + "1-cp-vs-cpk-distinction", + "1. Cp vs Cpk Distinction", + { "depth": 79, "slug": 9662, "text": 9663 }, + "2-pareto-principle-8020-rule", + "2. Pareto Principle (80/20 Rule)", + { "depth": 79, "slug": 9665, "text": 9666 }, + "3-cpk-target-values", + "3. Cpk Target Values", + { "depth": 79, "slug": 9668, "text": 9669 }, + "4-multi-factor-analysis", + "4. Multi-Factor Analysis", + { "depth": 33, "slug": 9671, "text": 9672 }, + "teaching-guide-for-instructors", + "Teaching Guide (For Instructors)", + { "depth": 79, "slug": 9674, "text": 9675 }, + "session-structure-60-minutes", + "Session Structure (60 minutes)", + { "depth": 621, "slug": 9677, "text": 9678 }, + "introduction-10-min", + "Introduction (10 min)", + { "depth": 621, "slug": 9680, "text": 9681 }, + "analysis-phase-1-identification-15-min", + "Analysis Phase 1: Identification (15 min)", + { "depth": 621, "slug": 9683, "text": 9684 }, + "analysis-phase-2-diagnosis-15-min", + "Analysis Phase 2: Diagnosis (15 min)", + { "depth": 621, "slug": 9686, "text": 9687 }, + "advanced-analysis-verification-10-min", + "Advanced Analysis: Verification (10 min)", + { "depth": 621, "slug": 9689, "text": 9690 }, + "discussion-threshold-impact-10-min", + "Discussion: Threshold Impact (10 min)", + { "depth": 621, "slug": 9692, "text": 9693 }, + "conclusion-actionable-recommendations-10-min", + "Conclusion: Actionable Recommendations (10 min)", + { "depth": 79, "slug": 9508, "text": 9509 }, + { "depth": 79, "slug": 9696, "text": 9697 }, + "common-student-mistakes", + "Common Student Mistakes", + { "depth": 33, "slug": 8164, "text": 8165 }, + { "depth": 33, "slug": 9700, "text": 9701 }, + "related-case-studies", + "Related Case Studies", + { "depth": 33, "slug": 3312, "text": 3313 }, + { "depth": 79, "slug": 9704, "text": 9705 }, + "statistical-details", + "Statistical Details", + { "depth": 79, "slug": 9707, "text": 9708 }, + "data-generation", + "Data Generation", + { "depth": 79, "slug": 9710, "text": 9711 }, + "thresholds-used", + "Thresholds Used", + [], + [], + { "title": 9572 }, + [], + "06-design-system/charts/boxplot", + { "id": 9716, "data": 9718, "body": 9723, "filePath": 9724, "digest": 9725, "rendered": 9726 }, + { + "title": 9719, + "editUrl": 16, + "head": 9720, + "template": 18, + "sidebar": 9721, + "pagefind": 16, + "draft": 20 + }, + "Boxplot Charts", + [], + { "hidden": 20, "attrs": 9722 }, + {}, + "# Boxplot Charts\n\nDistribution comparison charts for categorical and multi-channel analysis.\n\n## Overview\n\nVariScout provides two Boxplot variants for different analysis contexts:\n\n| Component | Purpose | Context | Data Source |\n| ---------------------- | ------------------------------- | ----------------- | -------------------- |\n| **Boxplot** | Distribution by category/factor | Standard Analysis | `BoxplotGroupData[]` |\n| **PerformanceBoxplot** | Channel comparison | Performance Mode | `ChannelResult[]` |\n\n**Source:** `packages/charts/src/Boxplot.tsx`, `packages/charts/src/PerformanceBoxplot.tsx`\n\n---\n\n## Standard Boxplot\n\nCompares distributions across categorical groups (shifts, operators, machines, etc.) to identify variation sources.\n\n### Props Interface\n\n```typescript\ninterface BoxplotProps extends BaseChartProps {\n /** Grouped data for boxplot (pre-calculated stats) */\n data: BoxplotGroupData[];\n /** Specification limits (USL, LSL, Target) */\n specs: SpecLimits;\n /** Y-axis label (default: 'Value') */\n yAxisLabel?: string;\n /** X-axis label - factor name (default: 'Group') */\n xAxisLabel?: string;\n /** Override Y-axis domain for Y-axis lock feature */\n yDomainOverride?: YAxisDomain;\n /** Currently selected groups (highlighted) */\n selectedGroups?: string[];\n /** Callback when a box is clicked */\n onBoxClick?: (key: string) => void;\n /** Sample size for branding bar */\n sampleSize?: number;\n /** Variation % explained by this factor */\n variationPct?: number;\n /** Threshold for high variation highlight (default: 50) */\n variationThreshold?: number;\n /** Category Total SS contributions - Map from key to % of total variation\n * Uses Total SS (captures both mean shift AND spread), not between-group only\n * Sum of all category contributions = 100%\n */\n categoryContributions?: Map\u003Cstring | number, number>;\n /** Show contribution labels below boxes (default: false) */\n showContributionLabels?: boolean;\n /** Show violin (density) overlay behind box elements (default: false) */\n showViolin?: boolean;\n}\n```\n\n### Data Structure\n\n```typescript\ninterface BoxplotGroupData {\n key: string; // Category identifier\n values: number[]; // Raw values for n calculation\n min: number; // Lower whisker (or Q1 - 1.5*IQR)\n max: number; // Upper whisker (or Q3 + 1.5*IQR)\n q1: number; // First quartile (25th percentile)\n median: number; // Median (50th percentile)\n mean: number; // Mean value (for diamond marker)\n q3: number; // Third quartile (75th percentile)\n outliers: number[]; // Values beyond 1.5*IQR fences\n}\n```\n\nUse `calculateBoxplotStats()` from `@variscout/charts/types` to convert raw data:\n\n```typescript\nimport { calculateBoxplotStats, BoxplotGroupInput } from '@variscout/charts';\n\nconst input: BoxplotGroupInput = { group: 'Shift A', values: [...] };\nconst boxplotData = calculateBoxplotStats(input);\n```\n\n### Display Modes\n\n#### Standard Mode\n\nDefault view showing distribution comparison:\n\n```tsx\n\u003CBoxplot\n data={groupedData}\n specs={{ usl: 105, lsl: 95, target: 100 }}\n yAxisLabel=\"Fill Weight (g)\"\n xAxisLabel=\"Shift\"\n/>\n```\n\n#### Drill Suggestion Mode\n\nWhen `variationPct >= variationThreshold`, the chart highlights the factor as a drill target:\n\n- X-axis label turns red with variation percentage: \"Shift (67%)\"\n- \"↓ drill here\" indicator appears below axis label\n- Signals to user that drilling into this factor will explain significant variation\n\n```tsx\n\u003CBoxplot\n data={groupedData}\n specs={specs}\n xAxisLabel=\"Shift\"\n variationPct={67} // Factor explains 67% of variation\n variationThreshold={50} // Highlight when >= 50% (default)\n/>\n```\n\n#### Contribution Labels Mode\n\nShows category-level impact percentages below each box:\n\n```tsx\n\u003CBoxplot\n data={groupedData}\n specs={specs}\n categoryContributions={contributionMap}\n showContributionLabels={true}\n/>\n```\n\nLabels are styled red when contribution ≥ `variationThreshold`.\n\n#### Selection Mode\n\nHighlights specific groups while dimming others:\n\n```tsx\n\u003CBoxplot\n data={groupedData}\n specs={specs}\n selectedGroups={['Shift A', 'Shift C']}\n onBoxClick={key => toggleSelection(key)}\n/>\n```\n\nSelection uses `useSelectionState` hook with `selectionOpacity.dimmed` (0.3) for unselected items.\n\n#### Violin Mode\n\nOverlays KDE-based density curves behind box elements to reveal distribution shape:\n\n```tsx\n\u003CBoxplot data={groupedData} specs={specs} showViolin={true} />\n```\n\nWhen enabled, each group's `values` array is passed to `calculateKDE()` from `@variscout/core`, which returns `{ value, count }[]` data for `@visx/stats` `\u003CViolinPlot>`. Uses **violin-primary rendering** (industry standard, matching Seaborn/Plotly/ggplot2):\n\n- Density curve is the dominant shape (0.35 fill opacity, 0.7 stroke opacity)\n- Thin inner IQR box (20% of band width) shows Q1-Q3 inside the violin\n- Median line spans thin box only; mean diamond centered\n- Whiskers, whisker caps, and outlier circles are hidden\n\nRequires `values.length >= 2` per group. Groups with fewer than 2 values skip violin rendering.\n\n#### Sorting\n\nCategories can be reordered using `sortBoxplotData()` from `@variscout/core`:\n\n```tsx\nimport { sortBoxplotData } from '@variscout/core';\n\nconst sorted = sortBoxplotData(groupedData, 'mean', 'desc');\n\u003CBoxplot data={sorted} specs={specs} />;\n```\n\n| Criterion | Sorts by | Use case |\n| ---------- | ---------------------- | --------------------- |\n| `'name'` | Alphabetical (default) | Stable reference view |\n| `'mean'` | Group mean value | Rank by center |\n| `'spread'` | IQR (Q3 - Q1) | Rank by consistency |\n\nDirection: `'asc'` (ascending, default) or `'desc'` (descending).\n\nSorting is applied in the **app Boxplot wrapper** before passing `data` to `BoxplotBase`. The sort state is stored in `DisplayOptions.boxplotSortBy` / `boxplotSortDirection` and controlled via `BoxplotDisplayToggle`.\n\n#### Y-Axis Lock Mode\n\nLocks Y-axis scale to a fixed range (useful during drill-down to maintain reference):\n\n```tsx\n\u003CBoxplot data={groupedData} specs={specs} yDomainOverride={{ min: 90, max: 110 }} />\n```\n\n---\n\n## PerformanceBoxplot\n\nCompares distributions across measurement channels (fill heads, cavities, etc.) in Performance Mode.\n\n### Props Interface\n\n```typescript\ninterface PerformanceBoxplotProps extends BaseChartProps {\n /** Channel results with values for boxplot calculation */\n channels: ChannelResult[];\n /** Specification limits for reference lines */\n specs: SpecLimits;\n /** Selected channel ID (shows only this channel when set) */\n selectedMeasure?: string | null;\n /** Maximum channels to display when no selection (default: 5) */\n maxDisplayed?: number;\n /** Callback when a boxplot is clicked */\n onChannelClick?: (channelId: string) => void;\n}\n```\n\n### Display Behavior\n\n| State | Display |\n| ---------------- | -------------------------------------------------------- |\n| No selection | Worst N channels by Cpk (uses `getWorstChannels()`) |\n| Channel selected | Single detailed boxplot for selected channel |\n| Empty channels | Placeholder: \"Select a channel or load performance data\" |\n\n### Visual Style\n\nPerformanceBoxplot uses neutral theme-aware colors consistent with Standard Boxplot:\n\n- Box: `chrome.boxDefault` / `chrome.boxBorder`\n- Whiskers: `chrome.whisker`\n- Median: `chartColors.cumulative`\n- Mean: Diamond marker in `chrome.labelPrimary`\n\nWhen a channel is selected, it uses `chartColors.selected` / `chartColors.selectedBorder`.\n\n### Example\n\n```tsx\nimport PerformanceBoxplot from '@variscout/charts/PerformanceBoxplot';\n\n\u003CPerformanceBoxplot\n channels={channelResults}\n specs={{ usl: 105, lsl: 95 }}\n selectedMeasure={selectedId}\n maxDisplayed={5}\n onChannelClick={handleChannelSelect}\n/>;\n```\n\n---\n\n## Statistical Elements\n\n| Element | Standard Boxplot | PerformanceBoxplot |\n| ------------------ | ------------------------- | --------------------- |\n| **Whiskers** | Min/Max (within 1.5×IQR) | Min to Max |\n| **Whisker caps** | Horizontal at min/max | Horizontal at min/max |\n| **Box** | Q1 to Q3 (IQR) | Q1 to Q3 (IQR) |\n| **Median** | Thick line | Thick line |\n| **Mean** | Diamond marker | Diamond marker |\n| **Outliers** | Red circles beyond fences | Not shown separately |\n| **n label** | Below each box | Below each box |\n| **Contribution %** | Below n (optional) | Not applicable |\n| **Spec lines** | USL/LSL (dashed red) | USL/LSL (dashed red) |\n| **Target line** | Dashed green | Not shown |\n| **Grid** | Not shown | Not shown |\n\n---\n\n## Data Flow\n\n### Standard Boxplot\n\n```\nDataContext (PWA/Azure)\n ↓\nDashboard.tsx\n ↓ calculateBoxplotStats() per group\nBoxplot (responsive wrapper)\n ↓\nBoxplotBase (renders SVG)\n```\n\n### PerformanceBoxplot\n\n```\nDataContext (PWA/Azure)\n ↓ analyzePerformanceData()\nPerformanceDashboard.tsx\n ↓ channels: ChannelResult[]\nPerformanceBoxplot (responsive wrapper)\n ↓ getWorstChannels() for display\nPerformanceBoxplotBase (renders SVG)\n```\n\n---\n\n## Interactions\n\n### Right-Click Annotations\n\nStandard Boxplot supports annotations via right-click context menu:\n\n```tsx\n// App wrapper wires right-click to annotation system\n\u003CBoxplotBase\n data={data}\n specs={specs}\n onBoxClick={handleClick} // left-click → drill-down (always)\n onBoxContextMenu={handleRightClick} // right-click → annotation menu\n highlightedCategories={highlights} // per-box fill color override\n/>\n```\n\nWhen `highlightedCategories` is provided, matching boxes use the highlight fill color instead of the default. Available colors: `red`, `amber`, `green` (from `HighlightColor` type in `@variscout/hooks`).\n\nText annotations are rendered by `ChartAnnotationLayer` (from `@variscout/ui`) as an HTML overlay positioned above the SVG chart. The layer is always active — no mode toggle needed.\n\nSee [Chart Annotations](./overview.md#chart-annotations) for full component details.\n\n### Mobile Tap Interaction\n\nOn mobile (\u003C640px), tapping a boxplot box opens a `MobileCategorySheet` bottom action sheet (from `@variscout/ui`) showing category stats: n, mean, median, IQR, and contribution %. The `onBoxContextMenu` right-click handler is desktop-only; on mobile, the `MobileChartCarousel` intercepts taps and uses the `onDrillDown` callback to open the sheet instead. Available actions in the sheet: drill-down into the category, highlight (red/amber/green), and pin as finding with an optional note.\n\n### Click Behavior\n\nBoth variants support click-based selection:\n\n```tsx\n// Standard Boxplot - toggle category filter\nonBoxClick={(key) => {\n if (selectedGroups.includes(key)) {\n setSelectedGroups(groups => groups.filter(g => g !== key));\n } else {\n setSelectedGroups(groups => [...groups, key]);\n }\n}}\n\n// PerformanceBoxplot - single channel selection (toggle)\nonChannelClick={(channelId) => {\n setSelectedMeasure(prev => prev === channelId ? null : channelId);\n}}\n```\n\n### Hover Tooltip\n\nStandard Boxplot tooltip shows:\n\n- Category key\n- Median, Mean, Q1, Q3\n- Sample size (n)\n- Impact % (if `categoryContributions` provided)\n - Uses Total SS contribution (captures both mean shift AND spread)\n - A category with mean near overall mean but high spread now shows non-zero impact\n - Sum of all category impacts = 100% (total variation fully partitioned)\n\nPerformanceBoxplot tooltip shows:\n\n- Channel label\n- Full stats: Max, Q3, Median, Mean, Q1, Min\n- Cpk value\n\n### Integration with Hooks\n\nStandard Boxplot integrates with shared hooks:\n\n| Hook | Purpose |\n| ---------------------- | --------------------------------- |\n| `useFilterNavigation` | Navigate into selected categories |\n| `useVariationTracking` | Cumulative η² explanation |\n| `useChartLayout` | Consistent margins/fonts |\n| `useChartTooltip` | Tooltip positioning |\n| `useSelectionState` | Selection opacity management |\n\n---\n\n## Cross-App Usage\n\n### PWA and Azure\n\nUse the responsive wrapper (auto-sizing with `withParentSize`):\n\n```tsx\nimport Boxplot from '@variscout/charts/Boxplot';\nimport PerformanceBoxplot from '@variscout/charts/PerformanceBoxplot';\n\n// Standard Boxplot\n\u003Cdiv className=\"h-[400px]\">\n \u003CBoxplot data={groupedData} specs={specs} onBoxClick={handleClick} />\n\u003C/div>\n\n// Performance Boxplot\n\u003Cdiv className=\"h-[300px]\">\n \u003CPerformanceBoxplot\n channels={channels}\n specs={specs}\n onChannelClick={handleClick}\n />\n\u003C/div>\n```\n\n---\n\n## Colors and Theming\n\n### Box Colors\n\n| Variant | Condition | Fill Color | Stroke Color |\n| ------------------- | ------------ | ---------------------- | ---------------------------- |\n| Standard (default) | Unselected | `chrome.boxDefault` | `chrome.boxBorder` |\n| Standard (selected) | In selection | `chartColors.selected` | `chartColors.selectedBorder` |\n| Performance | Unselected | `chrome.boxDefault` | `chrome.boxBorder` |\n| Performance | Selected | `chartColors.selected` | `chartColors.selectedBorder` |\n\n### Theme-Aware Colors\n\nPerformanceBoxplot uses `useChartTheme()` for automatic light/dark adaptation:\n\n```typescript\nconst { chrome } = useChartTheme();\n\n// Chrome colors adapt to theme:\n// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\n```\n\nStandard Boxplot uses hardcoded dark theme colors from `chromeColors`.\n\n### Whisker & Axis Colors\n\n```typescript\n// Standard Boxplot\nstroke={chromeColors.whisker} // Whisker lines\nstroke={chromeColors.axisPrimary} // Axis lines\nfill={chromeColors.labelPrimary} // Axis tick labels\nfill={chromeColors.labelSecondary} // X-axis tick labels\nfill={chromeColors.labelMuted} // n= labels\n\n// PerformanceBoxplot (theme-aware)\nstroke={chrome.axisPrimary}\nfill={chrome.labelPrimary}\n```\n\n### Responsive Sizing\n\nBoth variants use responsive utilities:\n\n```typescript\n// Standard Boxplot uses useChartLayout hook\nconst { fonts, margin, width, height } = useChartLayout({\n parentWidth,\n parentHeight,\n chartType: 'boxplot',\n showBranding,\n});\n\n// PerformanceBoxplot uses direct responsive functions\nconst margin = getResponsiveMargins(parentWidth, 'boxplot', sourceBarHeight);\nconst fonts = getResponsiveFonts(parentWidth);\n```\n\n---\n\n## BoxplotStatsTable\n\nA companion component that displays distribution metrics alongside boxplot charts.\n\n### Overview\n\n`BoxplotStatsTable` provides a tabular summary of boxplot statistics:\n\n| Column | Description |\n| --------------- | --------------------------------------------------------------- |\n| **Group** | Category identifier |\n| **n** | Sample size |\n| **Mean** | Arithmetic mean |\n| **Median** | 50th percentile |\n| **StdDev** | Standard deviation |\n| **Variation %** | Category's Total SS contribution (captures mean shift + spread) |\n\n### Props Interface\n\n```typescript\ninterface BoxplotStatsTableProps {\n /** Boxplot data with pre-calculated statistics */\n data: BoxplotGroupData[];\n /** Category contributions - Map from category key to % of total variation */\n categoryContributions?: Map\u003Cstring | number, number>;\n /** Threshold for \"high variation\" highlight (default: 50) */\n variationThreshold?: number;\n /** Compact mode for space-constrained layouts */\n compact?: boolean;\n}\n```\n\n### Visual Highlights\n\nThe table automatically highlights important patterns:\n\n| Highlight | Indicator | Meaning |\n| ------------------- | ------------------------------- | ------------------------------------------ |\n| **Highest StdDev** | ★ star prefix (amber) | Category with most internal variability |\n| **High Variation** | Red text on Variation % | Category explains ≥ threshold of variation |\n| **Top Contributor** | Red text (even below threshold) | Category with highest contribution % |\n\n### Theme Support\n\nUses `useChartTheme()` hook for automatic light/dark adaptation:\n\n```typescript\n// Colors adapt automatically:\n// - Header background: slate-800 (dark) / slate-100 (light)\n// - Row alternation: slate-900/800 (dark) / white/slate-50 (light)\n// - Text: slate-200/400 (dark) / slate-800/600 (light)\n```\n\n### Display Modes\n\n| Mode | Font Size | Padding | Use Case |\n| ----------- | --------- | ----------- | ------------------- |\n| **Default** | `text-sm` | `px-3 py-2` | PWA fullscreen view |\n| **Compact** | `text-xs` | `px-2 py-1` | Tight layouts |\n\n### Usage Example\n\n```tsx\nimport BoxplotStatsTable from '@variscout/charts/BoxplotStatsTable';\n\n// Basic usage\n\u003CBoxplotStatsTable\n data={boxplotData}\n/>\n\n// With variation tracking\n\u003CBoxplotStatsTable\n data={boxplotData}\n categoryContributions={contributionMap}\n variationThreshold={50}\n/>\n\n// Compact mode\n\u003CBoxplotStatsTable\n data={boxplotData}\n compact={true}\n/>\n```\n\n### Contribution Bars (on Boxplot Chart)\n\nWhen `categoryContributions` is provided to the Boxplot component, small horizontal bars appear below each box:\n\n```\n ┌─────┐\n │ │\n ────┼─────┼────\n │ │\n └─────┘\n ■■■■■ ← Contribution bar (red when ≥ threshold)\n [67%] ← Optional label\n```\n\n| Element | Style |\n| ------------- | ----------------------------------------------- |\n| Bar width | Proportional to contribution % |\n| Bar color | Red when ≥ `variationThreshold`, gray otherwise |\n| Max bar width | Box width (100% = full width) |\n\nEnable with `showContributionLabels={true}` on Boxplot component.\n\n### Integration Points\n\n| App | Component | Mode | Notes |\n| ----- | ---------------- | ------- | ------------------------- |\n| PWA | FocusedChartView | Default | Fullscreen boxplot detail |\n| Azure | FocusedChartView | Default | Same as PWA |\n\n---\n\n## Exports\n\n```typescript\n// Responsive wrappers (auto-sizing)\nimport Boxplot from '@variscout/charts/Boxplot';\nimport PerformanceBoxplot from '@variscout/charts/PerformanceBoxplot';\n\n// Base components (manual sizing)\nimport { BoxplotBase } from '@variscout/charts/Boxplot';\nimport { PerformanceBoxplotBase } from '@variscout/charts/PerformanceBoxplot';\n\n// Stats table\nimport BoxplotStatsTable from '@variscout/charts/BoxplotStatsTable';\n\n// Data utilities\nimport { calculateBoxplotStats, BoxplotGroupInput, BoxplotGroupData } from '@variscout/charts';\n```\n\n---\n\n## See Also\n\n- [Overview](./overview.md) - Chart design system overview and selection guide\n- [Colors](./colors.md) - Chart color constants and health classification\n- [Responsive](./responsive.md) - Responsive margin and font utilities\n- [Hooks](./hooks.md) - useChartLayout, useChartTooltip, useSelectionState\n- [Performance Mode](./performance-mode.md) - Full Performance Mode documentation\n- [IChart](./ichart.md) - Time-series control charts", + "src/content/docs/06-design-system/charts/boxplot.md", + "52de6d82583a5314", + { "html": 9727, "metadata": 9728 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"boxplot-charts\">Boxplot Charts\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#boxplot-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Boxplot Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Distribution comparison charts for categorical and multi-channel analysis.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout provides two Boxplot variants for different analysis contexts:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Context\u003C/th>\u003Cth>Data Source\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Boxplot\u003C/strong>\u003C/td>\u003Ctd>Distribution by category/factor\u003C/td>\u003Ctd>Standard Analysis\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">BoxplotGroupData[]\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>PerformanceBoxplot\u003C/strong>\u003C/td>\u003Ctd>Channel comparison\u003C/td>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ChannelResult[]\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/Boxplot.tsx\u003C/code>, \u003Ccode dir=\"auto\">packages/charts/src/PerformanceBoxplot.tsx\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"standard-boxplot\">Standard Boxplot\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#standard-boxplot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Boxplot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Compares distributions across categorical groups (shifts, operators, machines, etc.) to identify variation sources.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-interface\">Props Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> BoxplotProps \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extends\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">BaseChartProps\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Grouped data for boxplot (pre-calculated stats) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">BoxplotGroupData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Specification limits (USL, LSL, Target) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Y-axis label (default: 'Value') */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yAxisLabel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** X-axis label - factor name (default: 'Group') */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">xAxisLabel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Override Y-axis domain for Y-axis lock feature */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yDomainOverride\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">YAxisDomain\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Currently selected groups (highlighted) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedGroups\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback when a box is clicked */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onBoxClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Sample size for branding bar */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">sampleSize\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Variation % explained by this factor */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">variationPct\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Threshold for high variation highlight (default: 50) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">variationThreshold\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Category Total SS contributions - Map from key to % of total variation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">* Uses Total SS (captures both mean shift AND spread), not between-group only\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">* Sum of all category contributions = 100%\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">*/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">categoryContributions\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Map\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Show contribution labels below boxes (default: false) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showContributionLabels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Show violin (density) overlay behind box elements (default: false) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showViolin\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface BoxplotProps extends BaseChartProps { /** Grouped data for boxplot (pre-calculated stats) */ data: BoxplotGroupData[]; /** Specification limits (USL, LSL, Target) */ specs: SpecLimits; /** Y-axis label (default: 'Value') */ yAxisLabel?: string; /** X-axis label - factor name (default: 'Group') */ xAxisLabel?: string; /** Override Y-axis domain for Y-axis lock feature */ yDomainOverride?: YAxisDomain; /** Currently selected groups (highlighted) */ selectedGroups?: string[]; /** Callback when a box is clicked */ onBoxClick?: (key: string) => void; /** Sample size for branding bar */ sampleSize?: number; /** Variation % explained by this factor */ variationPct?: number; /** Threshold for high variation highlight (default: 50) */ variationThreshold?: number; /** Category Total SS contributions - Map from key to % of total variation * Uses Total SS (captures both mean shift AND spread), not between-group only * Sum of all category contributions = 100% */ categoryContributions?: Map\u003Cstring | number, number>; /** Show contribution labels below boxes (default: false) */ showContributionLabels?: boolean; /** Show violin (density) overlay behind box elements (default: false) */ showViolin?: boolean;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-structure\">Data Structure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> BoxplotGroupData {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Category identifier\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Raw values for n calculation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">min\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Lower whisker (or Q1 - 1.5*IQR)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">max\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Upper whisker (or Q3 + 1.5*IQR)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">q1\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// First quartile (25th percentile)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">median\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Median (50th percentile)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mean value (for diamond marker)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">q3\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Third quartile (75th percentile)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outliers\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Values beyond 1.5*IQR fences\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface BoxplotGroupData { key: string; // Category identifier values: number[]; // Raw values for n calculation min: number; // Lower whisker (or Q1 - 1.5*IQR) max: number; // Upper whisker (or Q3 + 1.5*IQR) q1: number; // First quartile (25th percentile) median: number; // Median (50th percentile) mean: number; // Mean value (for diamond marker) q3: number; // Third quartile (75th percentile) outliers: number[]; // Values beyond 1.5*IQR fences}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Use \u003Ccode dir=\"auto\">calculateBoxplotStats()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/charts/types\u003C/code> to convert raw data:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateBoxplotStats, BoxplotGroupInput } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">input\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">BoxplotGroupInput\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = { group: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift A\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, values:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">boxplotData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateBoxplotStats\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(input);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { calculateBoxplotStats, BoxplotGroupInput } from '@variscout/charts';const input: BoxplotGroupInput = { group: 'Shift A', values: [...] };const boxplotData = calculateBoxplotStats(input);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-modes\">Display Modes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-modes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Modes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"standard-mode\">Standard Mode\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#standard-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Default view showing distribution comparison:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Boxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">groupedData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">105\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">95\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, target: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">yAxisLabel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Fill Weight (g)\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">xAxisLabel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CBoxplot data={groupedData} specs={{ usl: 105, lsl: 95, target: 100 }} yAxisLabel="Fill Weight (g)" xAxisLabel="Shift"/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"drill-suggestion-mode\">Drill Suggestion Mode\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#drill-suggestion-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill Suggestion Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When \u003Ccode dir=\"auto\">variationPct >= variationThreshold\u003C/code>, the chart highlights the factor as a drill target:\u003C/p>\n\u003Cul>\n\u003Cli>X-axis label turns red with variation percentage: “Shift (67%)”\u003C/li>\n\u003Cli>”↓ drill here” indicator appears below axis label\u003C/li>\n\u003Cli>Signals to user that drilling into this factor will explain significant variation\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Boxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">groupedData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">xAxisLabel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">variationPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">67\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Factor explains 67% of variation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">variationThreshold\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">50\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Highlight when >= 50% (default)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CBoxplot data={groupedData} specs={specs} xAxisLabel="Shift" variationPct={67} // Factor explains 67% of variation variationThreshold={50} // Highlight when >= 50% (default)/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"contribution-labels-mode\">Contribution Labels Mode\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#contribution-labels-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Contribution Labels Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shows category-level impact percentages below each box:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Boxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">groupedData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">categoryContributions\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contributionMap\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">showContributionLabels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CBoxplot data={groupedData} specs={specs} categoryContributions={contributionMap} showContributionLabels={true}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Labels are styled red when contribution ≥ \u003Ccode dir=\"auto\">variationThreshold\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"selection-mode\">Selection Mode\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#selection-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Selection Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Highlights specific groups while dimming others:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Boxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">groupedData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedGroups\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift A\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift C\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onBoxClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toggleSelection\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(key)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CBoxplot data={groupedData} specs={specs} selectedGroups={['Shift A', 'Shift C']} onBoxClick={key => toggleSelection(key)}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Selection uses \u003Ccode dir=\"auto\">useSelectionState\u003C/code> hook with \u003Ccode dir=\"auto\">selectionOpacity.dimmed\u003C/code> (0.3) for unselected items.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"violin-mode\">Violin Mode\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#violin-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Violin Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Overlays KDE-based density curves behind box elements to reveal distribution shape:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Boxplot\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">groupedData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">showViolin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CBoxplot data={groupedData} specs={specs} showViolin={true} />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>When enabled, each group’s \u003Ccode dir=\"auto\">values\u003C/code> array is passed to \u003Ccode dir=\"auto\">calculateKDE()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>, which returns \u003Ccode dir=\"auto\">{ value, count }[]\u003C/code> data for \u003Ccode dir=\"auto\">@visx/stats\u003C/code> \u003Ccode dir=\"auto\"><ViolinPlot>\u003C/code>. Uses \u003Cstrong>violin-primary rendering\u003C/strong> (industry standard, matching Seaborn/Plotly/ggplot2):\u003C/p>\n\u003Cul>\n\u003Cli>Density curve is the dominant shape (0.35 fill opacity, 0.7 stroke opacity)\u003C/li>\n\u003Cli>Thin inner IQR box (20% of band width) shows Q1-Q3 inside the violin\u003C/li>\n\u003Cli>Median line spans thin box only; mean diamond centered\u003C/li>\n\u003Cli>Whiskers, whisker caps, and outlier circles are hidden\u003C/li>\n\u003C/ul>\n\u003Cp>Requires \u003Ccode dir=\"auto\">values.length >= 2\u003C/code> per group. Groups with fewer than 2 values skip violin rendering.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"sorting\">Sorting\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#sorting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sorting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Categories can be reordered using \u003Ccode dir=\"auto\">sortBoxplotData()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { sortBoxplotData } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sorted\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sortBoxplotData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(groupedData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">mean\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">desc\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Boxplot\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">sorted\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { sortBoxplotData } from '@variscout/core';const sorted = sortBoxplotData(groupedData, 'mean', 'desc');\u003CBoxplot data={sorted} specs={specs} />;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Criterion\u003C/th>\u003Cth>Sorts by\u003C/th>\u003Cth>Use case\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'name'\u003C/code>\u003C/td>\u003Ctd>Alphabetical (default)\u003C/td>\u003Ctd>Stable reference view\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'mean'\u003C/code>\u003C/td>\u003Ctd>Group mean value\u003C/td>\u003Ctd>Rank by center\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'spread'\u003C/code>\u003C/td>\u003Ctd>IQR (Q3 - Q1)\u003C/td>\u003Ctd>Rank by consistency\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Direction: \u003Ccode dir=\"auto\">'asc'\u003C/code> (ascending, default) or \u003Ccode dir=\"auto\">'desc'\u003C/code> (descending).\u003C/p>\n\u003Cp>Sorting is applied in the \u003Cstrong>app Boxplot wrapper\u003C/strong> before passing \u003Ccode dir=\"auto\">data\u003C/code> to \u003Ccode dir=\"auto\">BoxplotBase\u003C/code>. The sort state is stored in \u003Ccode dir=\"auto\">DisplayOptions.boxplotSortBy\u003C/code> / \u003Ccode dir=\"auto\">boxplotSortDirection\u003C/code> and controlled via \u003Ccode dir=\"auto\">BoxplotDisplayToggle\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"y-axis-lock-mode\">Y-Axis Lock Mode\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#y-axis-lock-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Y-Axis Lock Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Locks Y-axis scale to a fixed range (useful during drill-down to maintain reference):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Boxplot\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">groupedData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">yDomainOverride\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ min: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">90\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, max: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">110\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CBoxplot data={groupedData} specs={specs} yDomainOverride={{ min: 90, max: 110 }} />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performanceboxplot\">PerformanceBoxplot\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performanceboxplot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformanceBoxplot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Compares distributions across measurement channels (fill heads, cavities, etc.) in Performance Mode.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-interface-1\">Props Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-interface-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceBoxplotProps \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extends\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">BaseChartProps\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Channel results with values for boxplot calculation */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChannelResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Specification limits for reference lines */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Selected channel ID (shows only this channel when set) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Maximum channels to display when no selection (default: 5) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">maxDisplayed\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback when a boxplot is clicked */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">channelId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface PerformanceBoxplotProps extends BaseChartProps { /** Channel results with values for boxplot calculation */ channels: ChannelResult[]; /** Specification limits for reference lines */ specs: SpecLimits; /** Selected channel ID (shows only this channel when set) */ selectedMeasure?: string | null; /** Maximum channels to display when no selection (default: 5) */ maxDisplayed?: number; /** Callback when a boxplot is clicked */ onChannelClick?: (channelId: string) => void;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-behavior\">Display Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Behavior”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>State\u003C/th>\u003Cth>Display\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No selection\u003C/td>\u003Ctd>Worst N channels by Cpk (uses \u003Ccode dir=\"auto\">getWorstChannels()\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Channel selected\u003C/td>\u003Ctd>Single detailed boxplot for selected channel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Empty channels\u003C/td>\u003Ctd>Placeholder: “Select a channel or load performance data”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"visual-style\">Visual Style\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#visual-style\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Style”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>PerformanceBoxplot uses neutral theme-aware colors consistent with Standard Boxplot:\u003C/p>\n\u003Cul>\n\u003Cli>Box: \u003Ccode dir=\"auto\">chrome.boxDefault\u003C/code> / \u003Ccode dir=\"auto\">chrome.boxBorder\u003C/code>\u003C/li>\n\u003Cli>Whiskers: \u003Ccode dir=\"auto\">chrome.whisker\u003C/code>\u003C/li>\n\u003Cli>Median: \u003Ccode dir=\"auto\">chartColors.cumulative\u003C/code>\u003C/li>\n\u003Cli>Mean: Diamond marker in \u003Ccode dir=\"auto\">chrome.labelPrimary\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>When a channel is selected, it uses \u003Ccode dir=\"auto\">chartColors.selected\u003C/code> / \u003Ccode dir=\"auto\">chartColors.selectedBorder\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceBoxplot \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceBoxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceBoxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channelResults\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">105\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">95\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedId\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">maxDisplayed\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">5\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleChannelSelect\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import PerformanceBoxplot from '@variscout/charts/PerformanceBoxplot';\u003CPerformanceBoxplot channels={channelResults} specs={{ usl: 105, lsl: 95 }} selectedMeasure={selectedId} maxDisplayed={5} onChannelClick={handleChannelSelect}/>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"statistical-elements\">Statistical Elements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#statistical-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Statistical Elements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Standard Boxplot\u003C/th>\u003Cth>PerformanceBoxplot\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Whiskers\u003C/strong>\u003C/td>\u003Ctd>Min/Max (within 1.5×IQR)\u003C/td>\u003Ctd>Min to Max\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Whisker caps\u003C/strong>\u003C/td>\u003Ctd>Horizontal at min/max\u003C/td>\u003Ctd>Horizontal at min/max\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Box\u003C/strong>\u003C/td>\u003Ctd>Q1 to Q3 (IQR)\u003C/td>\u003Ctd>Q1 to Q3 (IQR)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Median\u003C/strong>\u003C/td>\u003Ctd>Thick line\u003C/td>\u003Ctd>Thick line\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mean\u003C/strong>\u003C/td>\u003Ctd>Diamond marker\u003C/td>\u003Ctd>Diamond marker\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Outliers\u003C/strong>\u003C/td>\u003Ctd>Red circles beyond fences\u003C/td>\u003Ctd>Not shown separately\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>n label\u003C/strong>\u003C/td>\u003Ctd>Below each box\u003C/td>\u003Ctd>Below each box\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Contribution %\u003C/strong>\u003C/td>\u003Ctd>Below n (optional)\u003C/td>\u003Ctd>Not applicable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Spec lines\u003C/strong>\u003C/td>\u003Ctd>USL/LSL (dashed red)\u003C/td>\u003Ctd>USL/LSL (dashed red)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Target line\u003C/strong>\u003C/td>\u003Ctd>Dashed green\u003C/td>\u003Ctd>Not shown\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Grid\u003C/strong>\u003C/td>\u003Ctd>Not shown\u003C/td>\u003Ctd>Not shown\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-flow\">Data Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-boxplot-1\">Standard Boxplot\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-boxplot-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Boxplot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext (PWA/Azure)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Dashboard.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓ calculateBoxplotStats() per group\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Boxplot (responsive wrapper)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">BoxplotBase (renders SVG)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DataContext (PWA/Azure) ↓Dashboard.tsx ↓ calculateBoxplotStats() per groupBoxplot (responsive wrapper) ↓BoxplotBase (renders SVG)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performanceboxplot-1\">PerformanceBoxplot\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performanceboxplot-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformanceBoxplot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext (PWA/Azure)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓ analyzePerformanceData()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceDashboard.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓ channels: ChannelResult[]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceBoxplot (responsive wrapper)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓ getWorstChannels() for display\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceBoxplotBase (renders SVG)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DataContext (PWA/Azure) ↓ analyzePerformanceData()PerformanceDashboard.tsx ↓ channels: ChannelResult[]PerformanceBoxplot (responsive wrapper) ↓ getWorstChannels() for displayPerformanceBoxplotBase (renders SVG)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interactions\">Interactions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interactions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interactions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"right-click-annotations\">Right-Click Annotations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#right-click-annotations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Right-Click Annotations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standard Boxplot supports annotations via right-click context menu:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// App wrapper wires right-click to annotation system\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">BoxplotBase\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onBoxClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleClick\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// left-click → drill-down (always)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onBoxContextMenu\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleRightClick\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// right-click → annotation menu\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">highlightedCategories\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">highlights\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// per-box fill color override\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// App wrapper wires right-click to annotation system\u003CBoxplotBase data={data} specs={specs} onBoxClick={handleClick} // left-click → drill-down (always) onBoxContextMenu={handleRightClick} // right-click → annotation menu highlightedCategories={highlights} // per-box fill color override/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>When \u003Ccode dir=\"auto\">highlightedCategories\u003C/code> is provided, matching boxes use the highlight fill color instead of the default. Available colors: \u003Ccode dir=\"auto\">red\u003C/code>, \u003Ccode dir=\"auto\">amber\u003C/code>, \u003Ccode dir=\"auto\">green\u003C/code> (from \u003Ccode dir=\"auto\">HighlightColor\u003C/code> type in \u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>).\u003C/p>\n\u003Cp>Text annotations are rendered by \u003Ccode dir=\"auto\">ChartAnnotationLayer\u003C/code> (from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>) as an HTML overlay positioned above the SVG chart. The layer is always active — no mode toggle needed.\u003C/p>\n\u003Cp>See \u003Ca href=\"./overview.md#chart-annotations\">Chart Annotations\u003C/a> for full component details.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mobile-tap-interaction\">Mobile Tap Interaction\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-tap-interaction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Tap Interaction”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>On mobile (<640px), tapping a boxplot box opens a \u003Ccode dir=\"auto\">MobileCategorySheet\u003C/code> bottom action sheet (from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>) showing category stats: n, mean, median, IQR, and contribution %. The \u003Ccode dir=\"auto\">onBoxContextMenu\u003C/code> right-click handler is desktop-only; on mobile, the \u003Ccode dir=\"auto\">MobileChartCarousel\u003C/code> intercepts taps and uses the \u003Ccode dir=\"auto\">onDrillDown\u003C/code> callback to open the sheet instead. Available actions in the sheet: drill-down into the category, highlight (red/amber/green), and pin as finding with an optional note.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"click-behavior\">Click Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#click-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Click Behavior”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both variants support click-based selection:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard Boxplot - toggle category filter\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onBoxClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{(key) => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (selectedGroups\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">includes\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(key)) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedGroups\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">groups\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> groups\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filter\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">g\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> g \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!==\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> key));\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">else\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedGroups\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">groups\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">groups, key]);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PerformanceBoxplot - single channel selection (toggle)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{(channelId) => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedMeasure\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">prev\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> prev \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> channelId \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> channelId);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Standard Boxplot - toggle category filteronBoxClick={(key) => { if (selectedGroups.includes(key)) { setSelectedGroups(groups => groups.filter(g => g !== key)); } else { setSelectedGroups(groups => [...groups, key]); }}}// PerformanceBoxplot - single channel selection (toggle)onChannelClick={(channelId) => { setSelectedMeasure(prev => prev === channelId ? null : channelId);}}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"hover-tooltip\">Hover Tooltip\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#hover-tooltip\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hover Tooltip”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standard Boxplot tooltip shows:\u003C/p>\n\u003Cul>\n\u003Cli>Category key\u003C/li>\n\u003Cli>Median, Mean, Q1, Q3\u003C/li>\n\u003Cli>Sample size (n)\u003C/li>\n\u003Cli>Impact % (if \u003Ccode dir=\"auto\">categoryContributions\u003C/code> provided)\n\u003Cul>\n\u003Cli>Uses Total SS contribution (captures both mean shift AND spread)\u003C/li>\n\u003Cli>A category with mean near overall mean but high spread now shows non-zero impact\u003C/li>\n\u003Cli>Sum of all category impacts = 100% (total variation fully partitioned)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ul>\n\u003Cp>PerformanceBoxplot tooltip shows:\u003C/p>\n\u003Cul>\n\u003Cli>Channel label\u003C/li>\n\u003Cli>Full stats: Max, Q3, Median, Mean, Q1, Min\u003C/li>\n\u003Cli>Cpk value\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"integration-with-hooks\">Integration with Hooks\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#integration-with-hooks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integration with Hooks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standard Boxplot integrates with shared hooks:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Hook\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useFilterNavigation\u003C/code>\u003C/td>\u003Ctd>Navigate into selected categories\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useVariationTracking\u003C/code>\u003C/td>\u003Ctd>Cumulative η² explanation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useChartLayout\u003C/code>\u003C/td>\u003Ctd>Consistent margins/fonts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useChartTooltip\u003C/code>\u003C/td>\u003Ctd>Tooltip positioning\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useSelectionState\u003C/code>\u003C/td>\u003Ctd>Selection opacity management\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-app-usage\">Cross-App Usage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-app-usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-App Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-and-azure\">PWA and Azure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-and-azure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA and Azure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use the responsive wrapper (auto-sizing with \u003Ccode dir=\"auto\">withParentSize\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Boxplot \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/Boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceBoxplot \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceBoxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard Boxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[400px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Boxplot\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">groupedData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onBoxClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleClick\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Performance Boxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[300px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceBoxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleClick\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import Boxplot from '@variscout/charts/Boxplot';import PerformanceBoxplot from '@variscout/charts/PerformanceBoxplot';// Standard Boxplot\u003Cdiv className="h-[400px]"> \u003CBoxplot data={groupedData} specs={specs} onBoxClick={handleClick} />\u003C/div>// Performance Boxplot\u003Cdiv className="h-[300px]"> \u003CPerformanceBoxplot channels={channels} specs={specs} onChannelClick={handleClick} />\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"colors-and-theming\">Colors and Theming\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#colors-and-theming\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Colors and Theming”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"box-colors\">Box Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#box-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Box Colors”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variant\u003C/th>\u003Cth>Condition\u003C/th>\u003Cth>Fill Color\u003C/th>\u003Cth>Stroke Color\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Standard (default)\u003C/td>\u003Ctd>Unselected\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chrome.boxDefault\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chrome.boxBorder\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Standard (selected)\u003C/td>\u003Ctd>In selection\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.selected\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.selectedBorder\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance\u003C/td>\u003Ctd>Unselected\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chrome.boxDefault\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chrome.boxBorder\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance\u003C/td>\u003Ctd>Selected\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.selected\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.selectedBorder\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"theme-aware-colors\">Theme-Aware Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#theme-aware-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theme-Aware Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>PerformanceBoxplot uses \u003Ccode dir=\"auto\">useChartTheme()\u003C/code> for automatic light/dark adaptation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chrome colors adapt to theme:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { chrome } = useChartTheme();// Chrome colors adapt to theme:// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Standard Boxplot uses hardcoded dark theme colors from \u003Ccode dir=\"auto\">chromeColors\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"whisker--axis-colors\">Whisker & Axis Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#whisker--axis-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Whisker & Axis Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard Boxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chromeColors.whisker} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Whisker lines\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chromeColors.axisPrimary} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Axis lines\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chromeColors.labelPrimary} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Axis tick labels\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chromeColors.labelSecondary} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// X-axis tick labels\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chromeColors.labelMuted} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// n= labels\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PerformanceBoxplot (theme-aware)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chrome.axisPrimary}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chrome.labelPrimary}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Standard Boxplotstroke={chromeColors.whisker} // Whisker linesstroke={chromeColors.axisPrimary} // Axis linesfill={chromeColors.labelPrimary} // Axis tick labelsfill={chromeColors.labelSecondary} // X-axis tick labelsfill={chromeColors.labelMuted} // n= labels// PerformanceBoxplot (theme-aware)stroke={chrome.axisPrimary}fill={chrome.labelPrimary}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"responsive-sizing\">Responsive Sizing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#responsive-sizing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Responsive Sizing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both variants use responsive utilities:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard Boxplot uses useChartLayout hook\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartLayout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">chartType: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showBranding\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PerformanceBoxplot uses direct responsive functions\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getResponsiveMargins\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">sourceBarHeight);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getResponsiveFonts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(parentWidth);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Standard Boxplot uses useChartLayout hookconst { fonts, margin, width, height } = useChartLayout({ parentWidth, parentHeight, chartType: 'boxplot', showBranding,});// PerformanceBoxplot uses direct responsive functionsconst margin = getResponsiveMargins(parentWidth, 'boxplot', sourceBarHeight);const fonts = getResponsiveFonts(parentWidth);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"boxplotstatstable\">BoxplotStatsTable\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#boxplotstatstable\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “BoxplotStatsTable”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A companion component that displays distribution metrics alongside boxplot charts.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"overview-1\">Overview\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#overview-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">BoxplotStatsTable\u003C/code> provides a tabular summary of boxplot statistics:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Column\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Group\u003C/strong>\u003C/td>\u003Ctd>Category identifier\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>n\u003C/strong>\u003C/td>\u003Ctd>Sample size\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mean\u003C/strong>\u003C/td>\u003Ctd>Arithmetic mean\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Median\u003C/strong>\u003C/td>\u003Ctd>50th percentile\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>StdDev\u003C/strong>\u003C/td>\u003Ctd>Standard deviation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Variation %\u003C/strong>\u003C/td>\u003Ctd>Category’s Total SS contribution (captures mean shift + spread)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-interface-2\">Props Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-interface-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> BoxplotStatsTableProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Boxplot data with pre-calculated statistics */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">BoxplotGroupData\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Category contributions - Map from category key to % of total variation */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">categoryContributions\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Map\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Threshold for \"high variation\" highlight (default: 50) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">variationThreshold\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Compact mode for space-constrained layouts */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">compact\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface BoxplotStatsTableProps { /** Boxplot data with pre-calculated statistics */ data: BoxplotGroupData[]; /** Category contributions - Map from category key to % of total variation */ categoryContributions?: Map\u003Cstring | number, number>; /** Threshold for "high variation" highlight (default: 50) */ variationThreshold?: number; /** Compact mode for space-constrained layouts */ compact?: boolean;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"visual-highlights\">Visual Highlights\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#visual-highlights\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Highlights”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The table automatically highlights important patterns:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Highlight\u003C/th>\u003Cth>Indicator\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Highest StdDev\u003C/strong>\u003C/td>\u003Ctd>★ star prefix (amber)\u003C/td>\u003Ctd>Category with most internal variability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>High Variation\u003C/strong>\u003C/td>\u003Ctd>Red text on Variation %\u003C/td>\u003Ctd>Category explains ≥ threshold of variation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Top Contributor\u003C/strong>\u003C/td>\u003Ctd>Red text (even below threshold)\u003C/td>\u003Ctd>Category with highest contribution %\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"theme-support\">Theme Support\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#theme-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theme Support”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Uses \u003Ccode dir=\"auto\">useChartTheme()\u003C/code> hook for automatic light/dark adaptation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Colors adapt automatically:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - Header background: slate-800 (dark) / slate-100 (light)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - Row alternation: slate-900/800 (dark) / white/slate-50 (light)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// - Text: slate-200/400 (dark) / slate-800/600 (light)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Colors adapt automatically:// - Header background: slate-800 (dark) / slate-100 (light)// - Row alternation: slate-900/800 (dark) / white/slate-50 (light)// - Text: slate-200/400 (dark) / slate-800/600 (light)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-modes-1\">Display Modes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-modes-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Modes”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Mode\u003C/th>\u003Cth>Font Size\u003C/th>\u003Cth>Padding\u003C/th>\u003Cth>Use Case\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Default\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-sm\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">px-3 py-2\u003C/code>\u003C/td>\u003Ctd>PWA fullscreen view\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Compact\u003C/strong>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-xs\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">px-2 py-1\u003C/code>\u003C/td>\u003Ctd>Tight layouts\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-example\">Usage Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> BoxplotStatsTable \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/BoxplotStatsTable\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Basic usage\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">BoxplotStatsTable\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">boxplotData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// With variation tracking\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">BoxplotStatsTable\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">boxplotData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">categoryContributions\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">contributionMap\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">variationThreshold\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">50\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Compact mode\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">BoxplotStatsTable\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">boxplotData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">compact\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import BoxplotStatsTable from '@variscout/charts/BoxplotStatsTable';// Basic usage\u003CBoxplotStatsTable data={boxplotData}/>// With variation tracking\u003CBoxplotStatsTable data={boxplotData} categoryContributions={contributionMap} variationThreshold={50}/>// Compact mode\u003CBoxplotStatsTable data={boxplotData} compact={true}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"contribution-bars-on-boxplot-chart\">Contribution Bars (on Boxplot Chart)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#contribution-bars-on-boxplot-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Contribution Bars (on Boxplot Chart)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When \u003Ccode dir=\"auto\">categoryContributions\u003C/code> is provided to the Boxplot component, small horizontal bars appear below each box:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">────┼─────┼────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">■■■■■ ← Contribution bar (red when ≥ threshold)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[67%] ← Optional label\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\" ┌─────┐ │ │ ────┼─────┼──── │ │ └─────┘ ■■■■■ ← Contribution bar (red when ≥ threshold) [67%] ← Optional label\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Style\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Bar width\u003C/td>\u003Ctd>Proportional to contribution %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Bar color\u003C/td>\u003Ctd>Red when ≥ \u003Ccode dir=\"auto\">variationThreshold\u003C/code>, gray otherwise\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Max bar width\u003C/td>\u003Ctd>Box width (100% = full width)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Enable with \u003Ccode dir=\"auto\">showContributionLabels={true}\u003C/code> on Boxplot component.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"integration-points\">Integration Points\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#integration-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integration Points”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>App\u003C/th>\u003Cth>Component\u003C/th>\u003Cth>Mode\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA\u003C/td>\u003Ctd>FocusedChartView\u003C/td>\u003Ctd>Default\u003C/td>\u003Ctd>Fullscreen boxplot detail\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure\u003C/td>\u003Ctd>FocusedChartView\u003C/td>\u003Ctd>Default\u003C/td>\u003Ctd>Same as PWA\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"exports\">Exports\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#exports\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Responsive wrappers (auto-sizing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Boxplot \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/Boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceBoxplot \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceBoxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Base components (manual sizing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { BoxplotBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/Boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { PerformanceBoxplotBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceBoxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Stats table\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> BoxplotStatsTable \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/BoxplotStatsTable\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Data utilities\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateBoxplotStats, BoxplotGroupInput, BoxplotGroupData } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Responsive wrappers (auto-sizing)import Boxplot from '@variscout/charts/Boxplot';import PerformanceBoxplot from '@variscout/charts/PerformanceBoxplot';// Base components (manual sizing)import { BoxplotBase } from '@variscout/charts/Boxplot';import { PerformanceBoxplotBase } from '@variscout/charts/PerformanceBoxplot';// Stats tableimport BoxplotStatsTable from '@variscout/charts/BoxplotStatsTable';// Data utilitiesimport { calculateBoxplotStats, BoxplotGroupInput, BoxplotGroupData } from '@variscout/charts';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview and selection guide\u003C/li>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - Chart color constants and health classification\u003C/li>\n\u003Cli>\u003Ca href=\"./responsive.md\">Responsive\u003C/a> - Responsive margin and font utilities\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - useChartLayout, useChartTooltip, useSelectionState\u003C/li>\n\u003Cli>\u003Ca href=\"./performance-mode.md\">Performance Mode\u003C/a> - Full Performance Mode documentation\u003C/li>\n\u003Cli>\u003Ca href=\"./ichart.md\">IChart\u003C/a> - Time-series control charts\u003C/li>\n\u003C/ul>", + { + "headings": 9729, + "localImagePaths": 9845, + "remoteImagePaths": 9846, + "frontmatter": 9847, + "imagePaths": 9848 + }, + [ + 9730, 9732, 9733, 9736, 9739, 9740, 9741, 9744, 9747, 9750, 9753, 9756, 9757, 9760, 9763, 9765, + 9768, 9771, 9772, 9775, 9778, 9780, 9782, 9785, 9788, 9791, 9794, 9797, 9800, 9803, 9806, 9809, + 9812, 9815, 9818, 9821, 9824, 9826, 9828, 9831, 9834, 9836, 9837, 9840, 9843, 9844 + ], + { "depth": 30, "slug": 9731, "text": 9719 }, + "boxplot-charts", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 9734, "text": 9735 }, + "standard-boxplot", + "Standard Boxplot", + { "depth": 79, "slug": 9737, "text": 9738 }, + "props-interface", + "Props Interface", + { "depth": 79, "slug": 3315, "text": 3316 }, + { "depth": 79, "slug": 980, "text": 981 }, + { "depth": 621, "slug": 9742, "text": 9743 }, + "standard-mode", + "Standard Mode", + { "depth": 621, "slug": 9745, "text": 9746 }, + "drill-suggestion-mode", + "Drill Suggestion Mode", + { "depth": 621, "slug": 9748, "text": 9749 }, + "contribution-labels-mode", + "Contribution Labels Mode", + { "depth": 621, "slug": 9751, "text": 9752 }, + "selection-mode", + "Selection Mode", + { "depth": 621, "slug": 9754, "text": 9755 }, + "violin-mode", + "Violin Mode", + { "depth": 621, "slug": 1735, "text": 1736 }, + { "depth": 621, "slug": 9758, "text": 9759 }, + "y-axis-lock-mode", + "Y-Axis Lock Mode", + { "depth": 33, "slug": 9761, "text": 9762 }, + "performanceboxplot", + "PerformanceBoxplot", + { "depth": 79, "slug": 9764, "text": 9738 }, + "props-interface-1", + { "depth": 79, "slug": 9766, "text": 9767 }, + "display-behavior", + "Display Behavior", + { "depth": 79, "slug": 9769, "text": 9770 }, + "visual-style", + "Visual Style", + { "depth": 79, "slug": 7536, "text": 7537 }, + { "depth": 33, "slug": 9773, "text": 9774 }, + "statistical-elements", + "Statistical Elements", + { "depth": 33, "slug": 9776, "text": 9777 }, + "data-flow", + "Data Flow", + { "depth": 79, "slug": 9779, "text": 9735 }, + "standard-boxplot-1", + { "depth": 79, "slug": 9781, "text": 9762 }, + "performanceboxplot-1", + { "depth": 33, "slug": 9783, "text": 9784 }, + "interactions", + "Interactions", + { "depth": 79, "slug": 9786, "text": 9787 }, + "right-click-annotations", + "Right-Click Annotations", + { "depth": 79, "slug": 9789, "text": 9790 }, + "mobile-tap-interaction", + "Mobile Tap Interaction", + { "depth": 79, "slug": 9792, "text": 9793 }, + "click-behavior", + "Click Behavior", + { "depth": 79, "slug": 9795, "text": 9796 }, + "hover-tooltip", + "Hover Tooltip", + { "depth": 79, "slug": 9798, "text": 9799 }, + "integration-with-hooks", + "Integration with Hooks", + { "depth": 33, "slug": 9801, "text": 9802 }, + "cross-app-usage", + "Cross-App Usage", + { "depth": 79, "slug": 9804, "text": 9805 }, + "pwa-and-azure", + "PWA and Azure", + { "depth": 33, "slug": 9807, "text": 9808 }, + "colors-and-theming", + "Colors and Theming", + { "depth": 79, "slug": 9810, "text": 9811 }, + "box-colors", + "Box Colors", + { "depth": 79, "slug": 9813, "text": 9814 }, + "theme-aware-colors", + "Theme-Aware Colors", + { "depth": 79, "slug": 9816, "text": 9817 }, + "whisker--axis-colors", + "Whisker & Axis Colors", + { "depth": 79, "slug": 9819, "text": 9820 }, + "responsive-sizing", + "Responsive Sizing", + { "depth": 33, "slug": 9822, "text": 9823 }, + "boxplotstatstable", + "BoxplotStatsTable", + { "depth": 79, "slug": 9825, "text": 448 }, + "overview-1", + { "depth": 79, "slug": 9827, "text": 9738 }, + "props-interface-2", + { "depth": 79, "slug": 9829, "text": 9830 }, + "visual-highlights", + "Visual Highlights", + { "depth": 79, "slug": 9832, "text": 9833 }, + "theme-support", + "Theme Support", + { "depth": 79, "slug": 9835, "text": 981 }, + "display-modes-1", + { "depth": 79, "slug": 3522, "text": 3523 }, + { "depth": 79, "slug": 9838, "text": 9839 }, + "contribution-bars-on-boxplot-chart", + "Contribution Bars (on Boxplot Chart)", + { "depth": 79, "slug": 9841, "text": 9842 }, + "integration-points", + "Integration Points", + { "depth": 33, "slug": 1723, "text": 1724 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 9719 }, + [], + "06-design-system/charts/capability", + { "id": 9849, "data": 9851, "body": 9856, "filePath": 9857, "digest": 9858, "rendered": 9859 }, + { + "title": 9852, + "editUrl": 16, + "head": 9853, + "template": 18, + "sidebar": 9854, + "pagefind": 16, + "draft": 20 + }, + "Capability Histograms", + [], + { "hidden": 20, "attrs": 9855 }, + {}, + "# Capability Histograms\n\nDistribution histograms with specification limit overlays for capability analysis.\n\n## Overview\n\nVariScout provides two capability histogram variants for different analysis contexts:\n\n| Component | Purpose | Context | Data Source |\n| ------------------------- | --------------------------- | ----------------- | --------------- |\n| **CapabilityHistogram** | Distribution vs spec limits | Standard Analysis | `number[]` |\n| **PerformanceCapability** | Single channel histogram | Performance Mode | `ChannelResult` |\n\n**Source:** `packages/charts/src/CapabilityHistogram.tsx`, `packages/charts/src/PerformanceCapability.tsx`\n\n---\n\n## Standard CapabilityHistogram\n\nShows data distribution as a histogram with specification limits and mean reference line. Used to visualize process capability and identify out-of-spec data.\n\n### Props Interface\n\n```typescript\ninterface CapabilityHistogramProps extends BaseChartProps {\n /** Raw numeric values */\n data: number[];\n /** Specification limits */\n specs: SpecLimits;\n /** Mean value for reference line */\n mean: number;\n /** Override X-axis domain (for locking scale to full dataset) - data values axis */\n xDomainOverride?: YAxisDomain;\n}\n```\n\n### Binning Algorithm\n\nUses D3's `bin()` function with 15 bins:\n\n- Domain extends to include spec limits if outside data range\n- Respects `xDomainOverride` when provided (for Y-axis lock feature)\n\n### Bar Coloring\n\nBar color is determined by position relative to spec limits:\n\n| Condition | Color |\n| ------------------------ | -------------------------- |\n| Bin midpoint within spec | Green (`chartColors.pass`) |\n| Bin midpoint >= USL | Red (`chartColors.fail`) |\n| Bin midpoint \u003C= LSL | Red (`chartColors.fail`) |\n\n### Example\n\n```tsx\nimport CapabilityHistogram from '@variscout/charts/CapabilityHistogram';\n\n\u003CCapabilityHistogram\n data={measurementValues}\n specs={{ usl: 105, lsl: 95, target: 100 }}\n mean={99.5}\n/>;\n```\n\n### X-Axis Lock Mode\n\nLocks X-axis scale to a fixed range (useful during drill-down):\n\n```tsx\n\u003CCapabilityHistogram\n data={filteredData}\n specs={specs}\n mean={mean}\n xDomainOverride={{ min: 90, max: 110 }}\n/>\n```\n\n---\n\n## PerformanceCapability\n\nShows detailed capability histogram for a selected channel in Performance Mode. Includes a stats overlay panel.\n\n### Props Interface\n\n```typescript\ninterface PerformanceCapabilityProps extends BaseChartProps {\n /** Single channel result to display (null shows placeholder) */\n channel: ChannelResult | null;\n /** Specification limits for reference lines */\n specs: SpecLimits;\n}\n```\n\n### Display Behavior\n\n| State | Display |\n| ---------------- | ------------------------------------------------------ |\n| Channel provided | Histogram with stats overlay panel |\n| Channel is null | Placeholder: \"Click on a channel to see its histogram\" |\n\n### Stats Overlay\n\nA semi-transparent panel in the top-right corner showing:\n\n- Channel label\n- Health badge (colored by health status)\n- Sample size (n)\n- Standard deviation (σ)\n- Cpk value (bold)\n\n### Bar Coloring\n\nBar color is determined by position relative to spec limits:\n\n| Condition | Color |\n| --------------- | ----------------------------- |\n| Within spec | Green (`chartColors.pass`) |\n| At or above USL | Red (`chartColors.fail`) |\n| At or below LSL | Amber (`chartColors.warning`) |\n\n### Health Badge Colors\n\n| Health | Badge Color |\n| ----------- | ----------------------------- |\n| `critical` | Red (`chartColors.fail`) |\n| `warning` | Amber (`chartColors.warning`) |\n| `capable` | Green (`chartColors.pass`) |\n| `excellent` | Blue (`chartColors.mean`) |\n\n### Example\n\n```tsx\nimport PerformanceCapability from '@variscout/charts/PerformanceCapability';\n\n\u003CPerformanceCapability channel={selectedChannel} specs={{ usl: 105, lsl: 95 }} />;\n```\n\n---\n\n## Visual Elements\n\n| Element | Standard CapabilityHistogram | PerformanceCapability |\n| ------------------ | ---------------------------- | ------------------------------ |\n| **Histogram bars** | 15 bins, spec-colored | 15 bins, spec-colored |\n| **LSL line** | Dashed red, labeled above | Dashed red, labeled left |\n| **USL line** | Dashed red, labeled above | Dashed red, labeled right |\n| **Target line** | Dashed green, labeled above | Not shown |\n| **Mean line** | Solid blue, labeled below | Solid blue, labeled above (μ=) |\n| **Stats overlay** | Not shown | Top-right panel |\n| **Grid** | Not shown | Horizontal rows |\n| **Y-axis label** | Not shown | \"Count\" |\n\n---\n\n## Data Flow\n\n### Standard CapabilityHistogram\n\n```\nDataContext (PWA/Azure)\n |\nDashboard.tsx / StatsPanel.tsx\n | data: number[], mean from stats\nCapabilityHistogram (responsive wrapper)\n | D3 bin() for histogram\nCapabilityHistogramBase (renders SVG)\n```\n\n### PerformanceCapability\n\n```\nDataContext (PWA/Azure)\n | analyzePerformanceData()\nPerformanceDashboard.tsx\n | channel: ChannelResult | null\nPerformanceCapability (responsive wrapper)\n | calculateHistogram(channel.values)\nPerformanceCapabilityBase (renders SVG)\n```\n\n---\n\n## Cross-App Usage\n\n### PWA and Azure\n\nUse the responsive wrapper (auto-sizing with `withParentSize`):\n\n```tsx\nimport CapabilityHistogram from '@variscout/charts/CapabilityHistogram';\nimport PerformanceCapability from '@variscout/charts/PerformanceCapability';\n\n// Standard Histogram\n\u003Cdiv className=\"h-[300px]\">\n \u003CCapabilityHistogram\n data={values}\n specs={specs}\n mean={mean}\n />\n\u003C/div>\n\n// Performance Capability\n\u003Cdiv className=\"h-[300px]\">\n \u003CPerformanceCapability\n channel={selectedChannel}\n specs={specs}\n />\n\u003C/div>\n```\n\n---\n\n## Colors and Theming\n\n### Bar Colors\n\nBars are colored based on their position relative to spec limits (see Bar Coloring sections above).\n\n### Theme-Aware Colors\n\nPerformanceCapability uses `useChartTheme()` for automatic light/dark adaptation:\n\n```typescript\nconst { chrome } = useChartTheme();\n\n// Chrome colors adapt to theme:\n// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, chrome.tooltipBg\n```\n\nStandard CapabilityHistogram uses hardcoded dark theme colors from `chromeColors`.\n\n### Reference Line Colors\n\n```typescript\n// Spec limits (USL/LSL)\nstroke={chartColors.spec} // red-500 dashed\n\n// Target line\nstroke={chartColors.target} // green-500 dashed\n\n// Mean line\nstroke={chartColors.meanAlt} // blue-400 solid (standard)\nstroke={chartColors.mean} // blue-500 solid (performance)\n```\n\n---\n\n## Histogram Calculation\n\nPerformanceCapability uses a custom histogram function:\n\n```typescript\nfunction calculateHistogram(values: number[], numBins: number): HistogramBin[] {\n // 1. Find min/max of values\n // 2. Calculate bin width = (max - min) / numBins\n // 3. Initialize bins with x0, x1, count = 0\n // 4. Assign each value to appropriate bin\n // 5. Return bins array\n}\n```\n\nBoth components use 15 bins (constant `NUM_BINS = 15`).\n\n---\n\n## Exports\n\n```typescript\n// Responsive wrappers (auto-sizing)\nimport CapabilityHistogram from '@variscout/charts/CapabilityHistogram';\nimport PerformanceCapability from '@variscout/charts/PerformanceCapability';\n\n// Base components (manual sizing)\nimport { CapabilityHistogramBase } from '@variscout/charts/CapabilityHistogram';\nimport { PerformanceCapabilityBase } from '@variscout/charts/PerformanceCapability';\n\n// Types\nimport type { CapabilityHistogramProps, PerformanceCapabilityProps } from '@variscout/charts';\n```\n\n---\n\n## See Also\n\n- [Overview](./overview.md) - Chart design system overview and selection guide\n- [Colors](./colors.md) - Chart color constants and health classification\n- [Responsive](./responsive.md) - Breakpoints and scaling utilities\n- [Hooks](./hooks.md) - useChartLayout\n- [Performance Mode](./performance-mode.md) - Full Performance Mode documentation\n- [IChart](./ichart.md) - Time-series control charts", + "src/content/docs/06-design-system/charts/capability.md", + "925f27d6390c42bd", + { "html": 9860, "metadata": 9861 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"capability-histograms\">Capability Histograms\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#capability-histograms\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability Histograms”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Distribution histograms with specification limit overlays for capability analysis.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout provides two capability histogram variants for different analysis contexts:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Context\u003C/th>\u003Cth>Data Source\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>CapabilityHistogram\u003C/strong>\u003C/td>\u003Ctd>Distribution vs spec limits\u003C/td>\u003Ctd>Standard Analysis\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number[]\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>PerformanceCapability\u003C/strong>\u003C/td>\u003Ctd>Single channel histogram\u003C/td>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ChannelResult\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/CapabilityHistogram.tsx\u003C/code>, \u003Ccode dir=\"auto\">packages/charts/src/PerformanceCapability.tsx\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"standard-capabilityhistogram\">Standard CapabilityHistogram\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#standard-capabilityhistogram\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard CapabilityHistogram”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shows data distribution as a histogram with specification limits and mean reference line. Used to visualize process capability and identify out-of-spec data.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-interface\">Props Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> CapabilityHistogramProps \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extends\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">BaseChartProps\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Raw numeric values */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Specification limits */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Mean value for reference line */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Override X-axis domain (for locking scale to full dataset) - data values axis */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">xDomainOverride\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">YAxisDomain\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface CapabilityHistogramProps extends BaseChartProps { /** Raw numeric values */ data: number[]; /** Specification limits */ specs: SpecLimits; /** Mean value for reference line */ mean: number; /** Override X-axis domain (for locking scale to full dataset) - data values axis */ xDomainOverride?: YAxisDomain;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"binning-algorithm\">Binning Algorithm\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#binning-algorithm\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Binning Algorithm”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Uses D3’s \u003Ccode dir=\"auto\">bin()\u003C/code> function with 15 bins:\u003C/p>\n\u003Cul>\n\u003Cli>Domain extends to include spec limits if outside data range\u003C/li>\n\u003Cli>Respects \u003Ccode dir=\"auto\">xDomainOverride\u003C/code> when provided (for Y-axis lock feature)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"bar-coloring\">Bar Coloring\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#bar-coloring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Bar Coloring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Bar color is determined by position relative to spec limits:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Condition\u003C/th>\u003Cth>Color\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Bin midpoint within spec\u003C/td>\u003Ctd>Green (\u003Ccode dir=\"auto\">chartColors.pass\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Bin midpoint >= USL\u003C/td>\u003Ctd>Red (\u003Ccode dir=\"auto\">chartColors.fail\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Bin midpoint <= LSL\u003C/td>\u003Ctd>Red (\u003Ccode dir=\"auto\">chartColors.fail\u003C/code>)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> CapabilityHistogram \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/CapabilityHistogram\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">CapabilityHistogram\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measurementValues\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">105\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">95\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, target: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">mean\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">99.5\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import CapabilityHistogram from '@variscout/charts/CapabilityHistogram';\u003CCapabilityHistogram data={measurementValues} specs={{ usl: 105, lsl: 95, target: 100 }} mean={99.5}/>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"x-axis-lock-mode\">X-Axis Lock Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#x-axis-lock-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “X-Axis Lock Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Locks X-axis scale to a fixed range (useful during drill-down):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">CapabilityHistogram\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">mean\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">xDomainOverride\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ min: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">90\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, max: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">110\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CCapabilityHistogram data={filteredData} specs={specs} mean={mean} xDomainOverride={{ min: 90, max: 110 }}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performancecapability\">PerformanceCapability\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performancecapability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformanceCapability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shows detailed capability histogram for a selected channel in Performance Mode. Includes a stats overlay panel.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-interface-1\">Props Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-interface-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceCapabilityProps \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extends\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">BaseChartProps\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Single channel result to display (null shows placeholder) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChannelResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Specification limits for reference lines */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface PerformanceCapabilityProps extends BaseChartProps { /** Single channel result to display (null shows placeholder) */ channel: ChannelResult | null; /** Specification limits for reference lines */ specs: SpecLimits;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-behavior\">Display Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Behavior”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>State\u003C/th>\u003Cth>Display\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Channel provided\u003C/td>\u003Ctd>Histogram with stats overlay panel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Channel is null\u003C/td>\u003Ctd>Placeholder: “Click on a channel to see its histogram”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"stats-overlay\">Stats Overlay\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#stats-overlay\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Stats Overlay”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A semi-transparent panel in the top-right corner showing:\u003C/p>\n\u003Cul>\n\u003Cli>Channel label\u003C/li>\n\u003Cli>Health badge (colored by health status)\u003C/li>\n\u003Cli>Sample size (n)\u003C/li>\n\u003Cli>Standard deviation (σ)\u003C/li>\n\u003Cli>Cpk value (bold)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"bar-coloring-1\">Bar Coloring\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#bar-coloring-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Bar Coloring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Bar color is determined by position relative to spec limits:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Condition\u003C/th>\u003Cth>Color\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Within spec\u003C/td>\u003Ctd>Green (\u003Ccode dir=\"auto\">chartColors.pass\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>At or above USL\u003C/td>\u003Ctd>Red (\u003Ccode dir=\"auto\">chartColors.fail\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>At or below LSL\u003C/td>\u003Ctd>Amber (\u003Ccode dir=\"auto\">chartColors.warning\u003C/code>)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"health-badge-colors\">Health Badge Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#health-badge-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Health Badge Colors”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Health\u003C/th>\u003Cth>Badge Color\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">critical\u003C/code>\u003C/td>\u003Ctd>Red (\u003Ccode dir=\"auto\">chartColors.fail\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">warning\u003C/code>\u003C/td>\u003Ctd>Amber (\u003Ccode dir=\"auto\">chartColors.warning\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">capable\u003C/code>\u003C/td>\u003Ctd>Green (\u003Ccode dir=\"auto\">chartColors.pass\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">excellent\u003C/code>\u003C/td>\u003Ctd>Blue (\u003Ccode dir=\"auto\">chartColors.mean\u003C/code>)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-1\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceCapability \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceCapability\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceCapability\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedChannel\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">105\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">95\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import PerformanceCapability from '@variscout/charts/PerformanceCapability';\u003CPerformanceCapability channel={selectedChannel} specs={{ usl: 105, lsl: 95 }} />;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visual-elements\">Visual Elements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visual-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Elements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Standard CapabilityHistogram\u003C/th>\u003Cth>PerformanceCapability\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Histogram bars\u003C/strong>\u003C/td>\u003Ctd>15 bins, spec-colored\u003C/td>\u003Ctd>15 bins, spec-colored\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>LSL line\u003C/strong>\u003C/td>\u003Ctd>Dashed red, labeled above\u003C/td>\u003Ctd>Dashed red, labeled left\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>USL line\u003C/strong>\u003C/td>\u003Ctd>Dashed red, labeled above\u003C/td>\u003Ctd>Dashed red, labeled right\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Target line\u003C/strong>\u003C/td>\u003Ctd>Dashed green, labeled above\u003C/td>\u003Ctd>Not shown\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mean line\u003C/strong>\u003C/td>\u003Ctd>Solid blue, labeled below\u003C/td>\u003Ctd>Solid blue, labeled above (μ=)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Stats overlay\u003C/strong>\u003C/td>\u003Ctd>Not shown\u003C/td>\u003Ctd>Top-right panel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Grid\u003C/strong>\u003C/td>\u003Ctd>Not shown\u003C/td>\u003Ctd>Horizontal rows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Y-axis label\u003C/strong>\u003C/td>\u003Ctd>Not shown\u003C/td>\u003Ctd>”Count”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-flow\">Data Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-capabilityhistogram-1\">Standard CapabilityHistogram\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-capabilityhistogram-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard CapabilityHistogram”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext (PWA/Azure)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Dashboard.tsx / StatsPanel.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| data: number[], mean from stats\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CapabilityHistogram (responsive wrapper)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| D3 bin() for histogram\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CapabilityHistogramBase (renders SVG)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DataContext (PWA/Azure) |Dashboard.tsx / StatsPanel.tsx | data: number[], mean from statsCapabilityHistogram (responsive wrapper) | D3 bin() for histogramCapabilityHistogramBase (renders SVG)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performancecapability-1\">PerformanceCapability\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performancecapability-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformanceCapability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext (PWA/Azure)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| analyzePerformanceData()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceDashboard.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| channel: ChannelResult | null\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceCapability (responsive wrapper)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| calculateHistogram(channel.values)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceCapabilityBase (renders SVG)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DataContext (PWA/Azure) | analyzePerformanceData()PerformanceDashboard.tsx | channel: ChannelResult | nullPerformanceCapability (responsive wrapper) | calculateHistogram(channel.values)PerformanceCapabilityBase (renders SVG)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-app-usage\">Cross-App Usage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-app-usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-App Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-and-azure\">PWA and Azure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-and-azure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA and Azure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use the responsive wrapper (auto-sizing with \u003Ccode dir=\"auto\">withParentSize\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> CapabilityHistogram \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/CapabilityHistogram\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceCapability \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceCapability\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard Histogram\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[300px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">CapabilityHistogram\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">mean\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Performance Capability\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[300px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceCapability\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedChannel\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import CapabilityHistogram from '@variscout/charts/CapabilityHistogram';import PerformanceCapability from '@variscout/charts/PerformanceCapability';// Standard Histogram\u003Cdiv className="h-[300px]"> \u003CCapabilityHistogram data={values} specs={specs} mean={mean} />\u003C/div>// Performance Capability\u003Cdiv className="h-[300px]"> \u003CPerformanceCapability channel={selectedChannel} specs={specs} />\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"colors-and-theming\">Colors and Theming\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#colors-and-theming\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Colors and Theming”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"bar-colors\">Bar Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#bar-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Bar Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Bars are colored based on their position relative to spec limits (see Bar Coloring sections above).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"theme-aware-colors\">Theme-Aware Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#theme-aware-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theme-Aware Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>PerformanceCapability uses \u003Ccode dir=\"auto\">useChartTheme()\u003C/code> for automatic light/dark adaptation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chrome colors adapt to theme:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, chrome.tooltipBg\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { chrome } = useChartTheme();// Chrome colors adapt to theme:// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, chrome.tooltipBg\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Standard CapabilityHistogram uses hardcoded dark theme colors from \u003Ccode dir=\"auto\">chromeColors\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"reference-line-colors\">Reference Line Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#reference-line-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reference Line Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Spec limits (USL/LSL)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.spec} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// red-500 dashed\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Target line\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.target} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// green-500 dashed\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mean line\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.meanAlt} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// blue-400 solid (standard)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.mean} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// blue-500 solid (performance)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Spec limits (USL/LSL)stroke={chartColors.spec} // red-500 dashed// Target linestroke={chartColors.target} // green-500 dashed// Mean linestroke={chartColors.meanAlt} // blue-400 solid (standard)stroke={chartColors.mean} // blue-500 solid (performance)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"histogram-calculation\">Histogram Calculation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#histogram-calculation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Histogram Calculation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>PerformanceCapability uses a custom histogram function:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateHistogram\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">[], \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">numBins\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">HistogramBin\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[] {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Find min/max of values\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Calculate bin width = (max - min) / numBins\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Initialize bins with x0, x1, count = 0\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 4. Assign each value to appropriate bin\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 5. Return bins array\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"function calculateHistogram(values: number[], numBins: number): HistogramBin[] { // 1. Find min/max of values // 2. Calculate bin width = (max - min) / numBins // 3. Initialize bins with x0, x1, count = 0 // 4. Assign each value to appropriate bin // 5. Return bins array}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Both components use 15 bins (constant \u003Ccode dir=\"auto\">NUM_BINS = 15\u003C/code>).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"exports\">Exports\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#exports\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Responsive wrappers (auto-sizing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> CapabilityHistogram \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/CapabilityHistogram\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceCapability \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceCapability\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Base components (manual sizing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { CapabilityHistogramBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/CapabilityHistogram\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { PerformanceCapabilityBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceCapability\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Types\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { CapabilityHistogramProps, PerformanceCapabilityProps } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Responsive wrappers (auto-sizing)import CapabilityHistogram from '@variscout/charts/CapabilityHistogram';import PerformanceCapability from '@variscout/charts/PerformanceCapability';// Base components (manual sizing)import { CapabilityHistogramBase } from '@variscout/charts/CapabilityHistogram';import { PerformanceCapabilityBase } from '@variscout/charts/PerformanceCapability';// Typesimport type { CapabilityHistogramProps, PerformanceCapabilityProps } from '@variscout/charts';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview and selection guide\u003C/li>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - Chart color constants and health classification\u003C/li>\n\u003Cli>\u003Ca href=\"./responsive.md\">Responsive\u003C/a> - Breakpoints and scaling utilities\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - useChartLayout\u003C/li>\n\u003Cli>\u003Ca href=\"./performance-mode.md\">Performance Mode\u003C/a> - Full Performance Mode documentation\u003C/li>\n\u003Cli>\u003Ca href=\"./ichart.md\">IChart\u003C/a> - Time-series control charts\u003C/li>\n\u003C/ul>", + { + "headings": 9862, + "localImagePaths": 9918, + "remoteImagePaths": 9919, + "frontmatter": 9920, + "imagePaths": 9921 + }, + [ + 9863, 9865, 9866, 9869, 9870, 9873, 9876, 9877, 9880, 9883, 9884, 9885, 9888, 9890, 9893, 9895, + 9898, 9899, 9901, 9903, 9904, 9905, 9906, 9909, 9910, 9913, 9916, 9917 + ], + { "depth": 30, "slug": 9864, "text": 9852 }, + "capability-histograms", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 9867, "text": 9868 }, + "standard-capabilityhistogram", + "Standard CapabilityHistogram", + { "depth": 79, "slug": 9737, "text": 9738 }, + { "depth": 79, "slug": 9871, "text": 9872 }, + "binning-algorithm", + "Binning Algorithm", + { "depth": 79, "slug": 9874, "text": 9875 }, + "bar-coloring", + "Bar Coloring", + { "depth": 79, "slug": 7536, "text": 7537 }, + { "depth": 79, "slug": 9878, "text": 9879 }, + "x-axis-lock-mode", + "X-Axis Lock Mode", + { "depth": 33, "slug": 9881, "text": 9882 }, + "performancecapability", + "PerformanceCapability", + { "depth": 79, "slug": 9764, "text": 9738 }, + { "depth": 79, "slug": 9766, "text": 9767 }, + { "depth": 79, "slug": 9886, "text": 9887 }, + "stats-overlay", + "Stats Overlay", + { "depth": 79, "slug": 9889, "text": 9875 }, + "bar-coloring-1", + { "depth": 79, "slug": 9891, "text": 9892 }, + "health-badge-colors", + "Health Badge Colors", + { "depth": 79, "slug": 9894, "text": 7537 }, + "example-1", + { "depth": 33, "slug": 9896, "text": 9897 }, + "visual-elements", + "Visual Elements", + { "depth": 33, "slug": 9776, "text": 9777 }, + { "depth": 79, "slug": 9900, "text": 9868 }, + "standard-capabilityhistogram-1", + { "depth": 79, "slug": 9902, "text": 9882 }, + "performancecapability-1", + { "depth": 33, "slug": 9801, "text": 9802 }, + { "depth": 79, "slug": 9804, "text": 9805 }, + { "depth": 33, "slug": 9807, "text": 9808 }, + { "depth": 79, "slug": 9907, "text": 9908 }, + "bar-colors", + "Bar Colors", + { "depth": 79, "slug": 9813, "text": 9814 }, + { "depth": 79, "slug": 9911, "text": 9912 }, + "reference-line-colors", + "Reference Line Colors", + { "depth": 33, "slug": 9914, "text": 9915 }, + "histogram-calculation", + "Histogram Calculation", + { "depth": 33, "slug": 1723, "text": 1724 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 9852 }, + [], + "06-design-system/charts/colors", + { "id": 9922, "data": 9924, "body": 9929, "filePath": 9930, "digest": 9931, "rendered": 9932 }, + { + "title": 9925, + "editUrl": 16, + "head": 9926, + "template": 18, + "sidebar": 9927, + "pagefind": 16, + "draft": 20 + }, + "Chart Colors", + [], + { "hidden": 20, "attrs": 9928 }, + {}, + "# Chart Colors\n\nData visualization colors for VariScout charts.\n\n## Implementation\n\nAll chart colors are centralized in `packages/charts/src/colors.ts`. **Never hardcode hex values in chart components** - always import from the colors module.\n\n```typescript\nimport { chartColors, chromeColors, operatorColors } from './colors';\n\n// Data point colors\nfill={chartColors.pass} // #22c55e - within spec\nfill={chartColors.fail} // #ef4444 - above USL\nfill={chartColors.warning} // #f59e0b - below LSL\n\n// Line colors\nstroke={chartColors.mean} // #3b82f6 - center line\nstroke={chartColors.spec} // #ef4444 - spec limits\n\n// Multi-series\nfill={operatorColors[index]} // 8-color array for categories\n\n// UI chrome\nfill={chromeColors.tooltipBg} // #1e293b\nfill={chromeColors.labelSecondary} // #94a3b8\n```\n\n## Data Point Colors\n\n### I-Chart Color Scheme (Minitab-style)\n\nThe I-Chart uses a simplified 2-color scheme following Minitab conventions:\n\n| Status | Color | Hex | Conditions |\n| -------------- | ----- | --------- | ----------------------------------------------------- |\n| In-control | Blue | `#3b82f6` | All checks pass |\n| Out-of-control | Red | `#ef4444` | Any violation (spec, control limits, or Nelson rules) |\n\n**Violation checks (in order):**\n\n1. Spec limit violations: `value > USL` or `value \u003C LSL`\n2. Control limit violations: `value > UCL` or `value \u003C LCL`\n3. Nelson Rule 2: 9+ consecutive points on same side of center line\n\n```tsx\nconst getPointColor = (value: number, index: number): string => {\n // Spec limit violations -> Red\n if (usl !== undefined && value > usl) return chartColors.fail;\n if (lsl !== undefined && value \u003C lsl) return chartColors.fail;\n\n // Control limit violations -> Red\n if (value > ucl || value \u003C lcl) return chartColors.fail;\n\n // Nelson Rule 2 violations -> Red\n if (nelsonRule2Violations.has(index)) return chartColors.fail;\n\n // In-control -> Blue\n return chartColors.mean;\n};\n```\n\n### Nelson Rule 2 Detection\n\nNelson Rule 2 identifies when 9 or more consecutive points fall on the same side of the center line (mean). This indicates a shift in the process, even if individual points remain within control limits.\n\n**Implementation:** `getNelsonRule2ViolationPoints()` in `@variscout/core/stats.ts`\n\n**Staged mode:** Nelson Rule 2 is computed per-stage using each stage's mean.\n\n### Direction Color Semantics\n\nWhen a [characteristic type](../../../03-features/analysis/characteristic-types.md) is set, control violation colors gain directional meaning:\n\n- **Green** = favorable signal (process moved toward quality goal)\n- **Red** = harmful signal (process moved away from goal)\n- **Orange** = spec violation (always harmful, regardless of direction)\n\nThis applies to I-Chart dots and Boxplot category fills. The color palette itself doesn't change — the assignment logic changes based on whether a deviation is toward or away from the quality target.\n\n## Line Colors\n\n| Element | Hex | Style | Usage |\n| ---------- | --------- | ------------ | ---------------- |\n| USL | `#ef4444` | Dashed (6,3) | Upper spec limit |\n| LSL | `#f59e0b` | Dashed (6,3) | Lower spec limit |\n| Target | `#22c55e` | Dashed (4,4) | Target value |\n| UCL/LCL | `#06b6d4` | Dashed (4,4) | Control limits |\n| Mean/CL | `#64748b` | Solid | Center line |\n| Regression | `#3b82f6` | Solid | Linear fit |\n| Quadratic | `#8b5cf6` | Solid | Polynomial fit |\n\n## Grid & Axis\n\n| Element | Hex | Opacity | Usage |\n| ------------ | --------- | ------- | --------------- |\n| Grid rows | `#334155` | 50% | Horizontal grid |\n| Grid columns | `#334155` | 30% | Vertical grid |\n| Axis stroke | `#64748b` | 100% | Axis lines |\n| Tick stroke | `#64748b` | 100% | Tick marks |\n| Axis labels | `#94a3b8` | 100% | Axis text |\n\n## Category Colors\n\nFor multi-series charts (Boxplot, InteractionPlot):\n\n```tsx\nconst CATEGORY_COLORS = [\n '#3b82f6', // blue-500\n '#22c55e', // green-500\n '#f59e0b', // amber-500\n '#ef4444', // red-500\n '#8b5cf6', // violet-500\n '#ec4899', // pink-500\n '#06b6d4', // cyan-500\n '#84cc16', // lime-500\n];\n```\n\n## Pareto Chart\n\n| Element | Hex | Usage |\n| --------------- | --------- | --------------------- |\n| Default bar | `#3b82f6` | Unselected bars |\n| Selected bar | `#0ea5e9` | Currently filtered |\n| Unselected bar | `#475569` | When filtering active |\n| Cumulative line | `#f97316` | 80% reference |\n| 80% threshold | `#f97316` | Horizontal line |\n\n## Tooltip\n\n```tsx\nconst tooltipStyle = {\n background: '#1e293b',\n border: '1px solid #334155',\n color: '#f1f5f9',\n fontSize: 12,\n padding: '8px 12px',\n};\n```\n\n## Branding Bar\n\n| Element | Hex | Usage |\n| ----------- | --------- | ---------------- |\n| Background | `#334155` | 60% opacity |\n| Accent bar | `#3b82f6` | Left edge marker |\n| Text | `#94a3b8` | Branding text |\n| Sample size | `#64748b` | \"n = X\" text |\n\n## SVG Usage Examples\n\n```tsx\nimport { chartColors, chromeColors } from './colors';\n\n// Grid\n\u003CGridRows stroke={chromeColors.gridLine} strokeOpacity={0.5} />\n\n// Spec lines\n\u003Cline\n stroke={chartColors.spec}\n strokeWidth={1.5}\n strokeDasharray=\"6,3\"\n/>\n\n// Data points with status\n\u003CCircle\n fill={value > usl ? chartColors.fail : value \u003C lsl ? chartColors.warning : chartColors.pass}\n stroke=\"#fff\"\n strokeWidth={1}\n/>\n```\n\n## Executive Color Palette\n\nVariScout supports an executive chart mode designed for consulting-grade reports (McKinsey, Bain, BCG style). The executive palette prioritizes clarity, authority, and high data-ink ratio.\n\n### executiveColors\n\nMuted, professional tones that replace the standard `chartColors` in executive mode:\n\n```typescript\nimport { executiveColors } from '@variscout/charts';\n\nexecutiveColors.pass; // #10b981 - emerald-500, refined green\nexecutiveColors.fail; // #ef4444 - red-500, standard red\nexecutiveColors.warning; // #f59e0b - amber-500\nexecutiveColors.violation; // #ea580c - orange-600, deep orange\n\nexecutiveColors.mean; // #0f172a - slate-900, nearly black for authority\nexecutiveColors.meanAlt; // #7c3aed - violet-600\nexecutiveColors.target; // #10b981 - emerald-500\nexecutiveColors.spec; // #94a3b8 - slate-400, subtle (don't distract)\nexecutiveColors.control; // #64748b - slate-500, subtle control limits\n\nexecutiveColors.linear; // #0f172a - slate-900\nexecutiveColors.quadratic; // #475569 - slate-600\nexecutiveColors.cumulative; // #475569 - slate-600, distinct from bars\nexecutiveColors.threshold80; // #94a3b8 - slate-400\n```\n\n### executiveChrome\n\nLight-mode-only chrome for executive reports (executive reports are rarely dark mode):\n\n```typescript\nimport { executiveChrome } from '@variscout/charts';\n\nexecutiveChrome.tooltipBg; // #ffffff - white\nexecutiveChrome.gridLine; // #e2e8f0 - slate-200, very subtle\nexecutiveChrome.barBackground; // #cbd5e1 - slate-300\n\nexecutiveChrome.labelPrimary; // #334155 - slate-700\nexecutiveChrome.labelSecondary; // #64748b - slate-500\nexecutiveChrome.axisPrimary; // #cbd5e1 - slate-300, subtle axis\nexecutiveChrome.axisSecondary; // #e2e8f0 - slate-200\nexecutiveChrome.pointStroke; // #ffffff - white stroke for separation\n\nexecutiveChrome.boxDefault; // #94a3b8 - slate-400\nexecutiveChrome.boxBorder; // #475569 - slate-600\nexecutiveChrome.ciband; // #e2e8f0 - slate-200\n```\n\n### getChartColors(mode)\n\nReturns the appropriate data color palette:\n\n```typescript\nimport { getChartColors } from '@variscout/charts';\n\nconst colors = getChartColors('executive'); // returns executiveColors\nconst colors = getChartColors('technical'); // returns chartColors (default)\n```\n\n### getChromeColors(isDark, mode)\n\nReturns theme-aware chrome colors with optional mode parameter:\n\n```typescript\nimport { getChromeColors } from '@variscout/charts';\n\n// Technical mode (default) - respects dark/light theme\ngetChromeColors(true); // dark chrome (chromeColors)\ngetChromeColors(false); // light chrome (chromeColorsLight)\n\n// Executive mode - always returns executiveChrome regardless of isDark\ngetChromeColors(true, 'executive'); // executiveChrome\ngetChromeColors(false, 'executive'); // executiveChrome\n```\n\n### Enabling Executive Mode\n\nSet `data-chart-mode=\"executive\"` on the `\u003Chtml>` element. The `useChartTheme` hook automatically detects this attribute and switches all chart colors to the executive palette.\n\n## Design Principles\n\nColors are centralized in `packages/charts/src/colors.ts` for:\n\n1. **Consistency** - Single source of truth for all charts\n2. **Maintainability** - Change colors in one place\n3. **Type Safety** - TypeScript const assertions prevent typos\n4. **Portability** - Charts work in any context (PWA, Azure, Website)\n\nWhen adding new charts, import from the colors module to maintain consistency.\n\n## Cross-Platform Usage\n\nAll apps must import chart colors from `@variscout/charts`:\n\n```typescript\n// PWA, Azure, Website\nimport { chartColors } from '@variscout/charts';\n\n// Use in components\nfill={chartColors.pass} // #22c55e\nstroke={chartColors.spec} // #ef4444\n```\n\n**Do NOT hardcode hex values in chart components.** Always use the centralized color constants to ensure visual consistency across all platforms.\n\n| App | Import From | Usage |\n| ------- | ------------------- | ---------------------------------- |\n| PWA | `@variscout/charts` | Chart components in Dashboard |\n| Azure | `@variscout/charts` | Chart components in Dashboard |\n| Website | `@variscout/charts` | React Islands (IChartIsland, etc.) |\n\n---\n\n## See Also\n\n- [Overview](./overview.md) - Chart design system overview and selection guide\n- [Executive Mode](./executive-mode.md) - Consulting-grade chart styling\n- [Responsive](./responsive.md) - Breakpoints and scaling utilities\n- [Hooks](./hooks.md) - useChartTheme for theme-aware colors\n- [IChart](./ichart.md) - I-Chart point coloring implementation", + "src/content/docs/06-design-system/charts/colors.md", + "a9281bcfc97c0ee5", + { "html": 9933, "metadata": 9934 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"chart-colors\">Chart Colors\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#chart-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Data visualization colors for VariScout charts.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation\">Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All chart colors are centralized in \u003Ccode dir=\"auto\">packages/charts/src/colors.ts\u003C/code>. \u003Cstrong>Never hardcode hex values in chart components\u003C/strong> - always import from the colors module.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { chartColors, chromeColors, operatorColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./colors\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Data point colors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.pass} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #22c55e - within spec\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.fail} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #ef4444 - above USL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.warning} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #f59e0b - below LSL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Line colors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.mean} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #3b82f6 - center line\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.spec} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #ef4444 - spec limits\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Multi-series\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{operatorColors[index]} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 8-color array for categories\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// UI chrome\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill={chromeColors.tooltipBg} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #1e293b\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill={chromeColors.labelSecondary} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #94a3b8\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { chartColors, chromeColors, operatorColors } from './colors';// Data point colorsfill={chartColors.pass} // #22c55e - within specfill={chartColors.fail} // #ef4444 - above USLfill={chartColors.warning} // #f59e0b - below LSL// Line colorsstroke={chartColors.mean} // #3b82f6 - center linestroke={chartColors.spec} // #ef4444 - spec limits// Multi-seriesfill={operatorColors[index]} // 8-color array for categories// UI chromefill={chromeColors.tooltipBg} // #1e293bfill={chromeColors.labelSecondary} // #94a3b8\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-point-colors\">Data Point Colors\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-point-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Point Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"i-chart-color-scheme-minitab-style\">I-Chart Color Scheme (Minitab-style)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#i-chart-color-scheme-minitab-style\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “I-Chart Color Scheme (Minitab-style)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The I-Chart uses a simplified 2-color scheme following Minitab conventions:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Status\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Conditions\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>In-control\u003C/td>\u003Ctd>Blue\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#3b82f6\u003C/code>\u003C/td>\u003Ctd>All checks pass\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Out-of-control\u003C/td>\u003Ctd>Red\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ef4444\u003C/code>\u003C/td>\u003Ctd>Any violation (spec, control limits, or Nelson rules)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Violation checks (in order):\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Spec limit violations: \u003Ccode dir=\"auto\">value > USL\u003C/code> or \u003Ccode dir=\"auto\">value < LSL\u003C/code>\u003C/li>\n\u003Cli>Control limit violations: \u003Ccode dir=\"auto\">value > UCL\u003C/code> or \u003Ccode dir=\"auto\">value < LCL\u003C/code>\u003C/li>\n\u003Cli>Nelson Rule 2: 9+ consecutive points on same side of center line\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointColor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Spec limit violations -> Red\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(usl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> !== \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> && \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> > \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">usl)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">fail\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(lsl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> !== \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> && \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> < \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">lsl)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">fail\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Control limit violations -> Red\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> > \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ucl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> || \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> < \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">lcl)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">fail\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Nelson Rule 2 violations -> Red\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(nelsonRule2Violations\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">has\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(index))\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">fail\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// In-control -> Blue\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mean\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const getPointColor = (value: number, index: number): string => { // Spec limit violations -> Red if (usl !== undefined && value > usl) return chartColors.fail; if (lsl !== undefined && value \u003C lsl) return chartColors.fail; // Control limit violations -> Red if (value > ucl || value \u003C lcl) return chartColors.fail; // Nelson Rule 2 violations -> Red if (nelsonRule2Violations.has(index)) return chartColors.fail; // In-control -> Blue return chartColors.mean;};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"nelson-rule-2-detection\">Nelson Rule 2 Detection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#nelson-rule-2-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Nelson Rule 2 Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Nelson Rule 2 identifies when 9 or more consecutive points fall on the same side of the center line (mean). This indicates a shift in the process, even if individual points remain within control limits.\u003C/p>\n\u003Cp>\u003Cstrong>Implementation:\u003C/strong> \u003Ccode dir=\"auto\">getNelsonRule2ViolationPoints()\u003C/code> in \u003Ccode dir=\"auto\">@variscout/core/stats.ts\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>Staged mode:\u003C/strong> Nelson Rule 2 is computed per-stage using each stage’s mean.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"direction-color-semantics\">Direction Color Semantics\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#direction-color-semantics\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Direction Color Semantics”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When a \u003Ca href=\"../../../03-features/analysis/characteristic-types.md\">characteristic type\u003C/a> is set, control violation colors gain directional meaning:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Green\u003C/strong> = favorable signal (process moved toward quality goal)\u003C/li>\n\u003Cli>\u003Cstrong>Red\u003C/strong> = harmful signal (process moved away from goal)\u003C/li>\n\u003Cli>\u003Cstrong>Orange\u003C/strong> = spec violation (always harmful, regardless of direction)\u003C/li>\n\u003C/ul>\n\u003Cp>This applies to I-Chart dots and Boxplot category fills. The color palette itself doesn’t change — the assignment logic changes based on whether a deviation is toward or away from the quality target.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"line-colors\">Line Colors\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#line-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Line Colors”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Style\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>USL\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ef4444\u003C/code>\u003C/td>\u003Ctd>Dashed (6,3)\u003C/td>\u003Ctd>Upper spec limit\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LSL\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f59e0b\u003C/code>\u003C/td>\u003Ctd>Dashed (6,3)\u003C/td>\u003Ctd>Lower spec limit\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Target\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#22c55e\u003C/code>\u003C/td>\u003Ctd>Dashed (4,4)\u003C/td>\u003Ctd>Target value\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UCL/LCL\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#06b6d4\u003C/code>\u003C/td>\u003Ctd>Dashed (4,4)\u003C/td>\u003Ctd>Control limits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mean/CL\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>Solid\u003C/td>\u003Ctd>Center line\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regression\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#3b82f6\u003C/code>\u003C/td>\u003Ctd>Solid\u003C/td>\u003Ctd>Linear fit\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Quadratic\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#8b5cf6\u003C/code>\u003C/td>\u003Ctd>Solid\u003C/td>\u003Ctd>Polynomial fit\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"grid--axis\">Grid & Axis\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#grid--axis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Grid & Axis”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Opacity\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Grid rows\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#334155\u003C/code>\u003C/td>\u003Ctd>50%\u003C/td>\u003Ctd>Horizontal grid\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Grid columns\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#334155\u003C/code>\u003C/td>\u003Ctd>30%\u003C/td>\u003Ctd>Vertical grid\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Axis stroke\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>100%\u003C/td>\u003Ctd>Axis lines\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tick stroke\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>100%\u003C/td>\u003Ctd>Tick marks\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Axis labels\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003Ctd>100%\u003C/td>\u003Ctd>Axis text\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"category-colors\">Category Colors\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#category-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Category Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For multi-series charts (Boxplot, InteractionPlot):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">CATEGORY_COLORS\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> =\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#3b82f6\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// blue-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#22c55e\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// green-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#f59e0b\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// amber-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ef4444\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// red-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#8b5cf6\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// violet-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ec4899\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// pink-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#06b6d4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// cyan-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#84cc16\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// lime-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">];\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const CATEGORY_COLORS = [ '#3b82f6', // blue-500 '#22c55e', // green-500 '#f59e0b', // amber-500 '#ef4444', // red-500 '#8b5cf6', // violet-500 '#ec4899', // pink-500 '#06b6d4', // cyan-500 '#84cc16', // lime-500];\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pareto-chart\">Pareto Chart\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pareto-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pareto Chart”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Default bar\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#3b82f6\u003C/code>\u003C/td>\u003Ctd>Unselected bars\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Selected bar\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#0ea5e9\u003C/code>\u003C/td>\u003Ctd>Currently filtered\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Unselected bar\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#475569\u003C/code>\u003C/td>\u003Ctd>When filtering active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cumulative line\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f97316\u003C/code>\u003C/td>\u003Ctd>80% reference\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>80% threshold\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f97316\u003C/code>\u003C/td>\u003Ctd>Horizontal line\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tooltip\">Tooltip\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tooltip\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tooltip”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tooltipStyle\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">background: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#1e293b\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">border: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">1px solid #334155\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">color: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#f1f5f9\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">12\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">padding: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">8px 12px\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const tooltipStyle = { background: '#1e293b', border: '1px solid #334155', color: '#f1f5f9', fontSize: 12, padding: '8px 12px',};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"branding-bar\">Branding Bar\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#branding-bar\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Branding Bar”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Background\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#334155\u003C/code>\u003C/td>\u003Ctd>60% opacity\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Accent bar\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#3b82f6\u003C/code>\u003C/td>\u003Ctd>Left edge marker\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Text\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003Ctd>Branding text\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sample size\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>”n = X” text\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"svg-usage-examples\">SVG Usage Examples\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#svg-usage-examples\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SVG Usage Examples”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { chartColors, chromeColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./colors\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Grid\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">GridRows\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chromeColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">gridLine\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Spec lines\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">line\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">spec\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.5\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeDasharray\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">6,3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Data points with status\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Circle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">usl\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">fail\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\"><\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">lsl\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">warning\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">pass\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#fff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { chartColors, chromeColors } from './colors';// Grid\u003CGridRows stroke={chromeColors.gridLine} strokeOpacity={0.5} />// Spec lines\u003Cline stroke={chartColors.spec} strokeWidth={1.5} strokeDasharray="6,3"/>// Data points with status\u003CCircle fill={value > usl ? chartColors.fail : value \u003C lsl ? chartColors.warning : chartColors.pass} stroke="#fff" strokeWidth={1}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"executive-color-palette\">Executive Color Palette\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#executive-color-palette\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Executive Color Palette”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout supports an executive chart mode designed for consulting-grade reports (McKinsey, Bain, BCG style). The executive palette prioritizes clarity, authority, and high data-ink ratio.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"executivecolors\">executiveColors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#executivecolors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “executiveColors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Muted, professional tones that replace the standard \u003Ccode dir=\"auto\">chartColors\u003C/code> in executive mode:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { executiveColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">pass\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #10b981 - emerald-500, refined green\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">fail\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #ef4444 - red-500, standard red\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">warning\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #f59e0b - amber-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">violation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #ea580c - orange-600, deep orange\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #0f172a - slate-900, nearly black for authority\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">meanAlt\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #7c3aed - violet-600\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">target\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #10b981 - emerald-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">spec\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #94a3b8 - slate-400, subtle (don't distract)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">control\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #64748b - slate-500, subtle control limits\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">linear\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #0f172a - slate-900\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">quadratic\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #475569 - slate-600\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">cumulative\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #475569 - slate-600, distinct from bars\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">threshold80\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #94a3b8 - slate-400\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { executiveColors } from '@variscout/charts';executiveColors.pass; // #10b981 - emerald-500, refined greenexecutiveColors.fail; // #ef4444 - red-500, standard redexecutiveColors.warning; // #f59e0b - amber-500executiveColors.violation; // #ea580c - orange-600, deep orangeexecutiveColors.mean; // #0f172a - slate-900, nearly black for authorityexecutiveColors.meanAlt; // #7c3aed - violet-600executiveColors.target; // #10b981 - emerald-500executiveColors.spec; // #94a3b8 - slate-400, subtle (don't distract)executiveColors.control; // #64748b - slate-500, subtle control limitsexecutiveColors.linear; // #0f172a - slate-900executiveColors.quadratic; // #475569 - slate-600executiveColors.cumulative; // #475569 - slate-600, distinct from barsexecutiveColors.threshold80; // #94a3b8 - slate-400\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"executivechrome\">executiveChrome\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#executivechrome\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “executiveChrome”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Light-mode-only chrome for executive reports (executive reports are rarely dark mode):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { executiveChrome } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">tooltipBg\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #ffffff - white\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">gridLine\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #e2e8f0 - slate-200, very subtle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">barBackground\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #cbd5e1 - slate-300\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">labelPrimary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #334155 - slate-700\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">labelSecondary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #64748b - slate-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">axisPrimary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #cbd5e1 - slate-300, subtle axis\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">axisSecondary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #e2e8f0 - slate-200\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">pointStroke\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #ffffff - white stroke for separation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">boxDefault\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #94a3b8 - slate-400\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">boxBorder\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #475569 - slate-600\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">executiveChrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">ciband\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #e2e8f0 - slate-200\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { executiveChrome } from '@variscout/charts';executiveChrome.tooltipBg; // #ffffff - whiteexecutiveChrome.gridLine; // #e2e8f0 - slate-200, very subtleexecutiveChrome.barBackground; // #cbd5e1 - slate-300executiveChrome.labelPrimary; // #334155 - slate-700executiveChrome.labelSecondary; // #64748b - slate-500executiveChrome.axisPrimary; // #cbd5e1 - slate-300, subtle axisexecutiveChrome.axisSecondary; // #e2e8f0 - slate-200executiveChrome.pointStroke; // #ffffff - white stroke for separationexecutiveChrome.boxDefault; // #94a3b8 - slate-400executiveChrome.boxBorder; // #475569 - slate-600executiveChrome.ciband; // #e2e8f0 - slate-200\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"getchartcolorsmode\">getChartColors(mode)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#getchartcolorsmode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “getChartColors(mode)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Returns the appropriate data color palette:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { getChartColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">colors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChartColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">executive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// returns executiveColors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">colors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChartColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">technical\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// returns chartColors (default)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { getChartColors } from '@variscout/charts';const colors = getChartColors('executive'); // returns executiveColorsconst colors = getChartColors('technical'); // returns chartColors (default)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"getchromecolorsisdark-mode\">getChromeColors(isDark, mode)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#getchromecolorsisdark-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “getChromeColors(isDark, mode)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Returns theme-aware chrome colors with optional mode parameter:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { getChromeColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Technical mode (default) - respects dark/light theme\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChromeColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// dark chrome (chromeColors)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChromeColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// light chrome (chromeColorsLight)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Executive mode - always returns executiveChrome regardless of isDark\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChromeColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">executive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// executiveChrome\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChromeColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">executive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// executiveChrome\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { getChromeColors } from '@variscout/charts';// Technical mode (default) - respects dark/light themegetChromeColors(true); // dark chrome (chromeColors)getChromeColors(false); // light chrome (chromeColorsLight)// Executive mode - always returns executiveChrome regardless of isDarkgetChromeColors(true, 'executive'); // executiveChromegetChromeColors(false, 'executive'); // executiveChrome\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"enabling-executive-mode\">Enabling Executive Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#enabling-executive-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Enabling Executive Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Set \u003Ccode dir=\"auto\">data-chart-mode=\"executive\"\u003C/code> on the \u003Ccode dir=\"auto\"><html>\u003C/code> element. The \u003Ccode dir=\"auto\">useChartTheme\u003C/code> hook automatically detects this attribute and switches all chart colors to the executive palette.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"design-principles\">Design Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#design-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Design Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Colors are centralized in \u003Ccode dir=\"auto\">packages/charts/src/colors.ts\u003C/code> for:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Consistency\u003C/strong> - Single source of truth for all charts\u003C/li>\n\u003Cli>\u003Cstrong>Maintainability\u003C/strong> - Change colors in one place\u003C/li>\n\u003Cli>\u003Cstrong>Type Safety\u003C/strong> - TypeScript const assertions prevent typos\u003C/li>\n\u003Cli>\u003Cstrong>Portability\u003C/strong> - Charts work in any context (PWA, Azure, Website)\u003C/li>\n\u003C/ol>\n\u003Cp>When adding new charts, import from the colors module to maintain consistency.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-platform-usage\">Cross-Platform Usage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-platform-usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Platform Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All apps must import chart colors from \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PWA, Azure, Website\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { chartColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Use in components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.pass} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #22c55e\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.spec} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #ef4444\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// PWA, Azure, Websiteimport { chartColors } from '@variscout/charts';// Use in componentsfill={chartColors.pass} // #22c55estroke={chartColors.spec} // #ef4444\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Do NOT hardcode hex values in chart components.\u003C/strong> Always use the centralized color constants to ensure visual consistency across all platforms.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>App\u003C/th>\u003Cth>Import From\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/td>\u003Ctd>Chart components in Dashboard\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/td>\u003Ctd>Chart components in Dashboard\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Website\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/charts\u003C/code>\u003C/td>\u003Ctd>React Islands (IChartIsland, etc.)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview and selection guide\u003C/li>\n\u003Cli>\u003Ca href=\"./executive-mode.md\">Executive Mode\u003C/a> - Consulting-grade chart styling\u003C/li>\n\u003Cli>\u003Ca href=\"./responsive.md\">Responsive\u003C/a> - Breakpoints and scaling utilities\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - useChartTheme for theme-aware colors\u003C/li>\n\u003Cli>\u003Ca href=\"./ichart.md\">IChart\u003C/a> - I-Chart point coloring implementation\u003C/li>\n\u003C/ul>", + { + "headings": 9935, + "localImagePaths": 9993, + "remoteImagePaths": 9994, + "frontmatter": 9995, + "imagePaths": 9996 + }, + [ + 9936, 9938, 9939, 9942, 9945, 9948, 9951, 9954, 9957, 9960, 9961, 9964, 9967, 9970, 9973, 9976, + 9979, 9982, 9985, 9988, 9989, 9992 + ], + { "depth": 30, "slug": 9937, "text": 9925 }, + "chart-colors", + { "depth": 33, "slug": 1885, "text": 1886 }, + { "depth": 33, "slug": 9940, "text": 9941 }, + "data-point-colors", + "Data Point Colors", + { "depth": 79, "slug": 9943, "text": 9944 }, + "i-chart-color-scheme-minitab-style", + "I-Chart Color Scheme (Minitab-style)", + { "depth": 79, "slug": 9946, "text": 9947 }, + "nelson-rule-2-detection", + "Nelson Rule 2 Detection", + { "depth": 79, "slug": 9949, "text": 9950 }, + "direction-color-semantics", + "Direction Color Semantics", + { "depth": 33, "slug": 9952, "text": 9953 }, + "line-colors", + "Line Colors", + { "depth": 33, "slug": 9955, "text": 9956 }, + "grid--axis", + "Grid & Axis", + { "depth": 33, "slug": 9958, "text": 9959 }, + "category-colors", + "Category Colors", + { "depth": 33, "slug": 6618, "text": 6606 }, + { "depth": 33, "slug": 9962, "text": 9963 }, + "tooltip", + "Tooltip", + { "depth": 33, "slug": 9965, "text": 9966 }, + "branding-bar", + "Branding Bar", + { "depth": 33, "slug": 9968, "text": 9969 }, + "svg-usage-examples", + "SVG Usage Examples", + { "depth": 33, "slug": 9971, "text": 9972 }, + "executive-color-palette", + "Executive Color Palette", + { "depth": 79, "slug": 9974, "text": 9975 }, + "executivecolors", + "executiveColors", + { "depth": 79, "slug": 9977, "text": 9978 }, + "executivechrome", + "executiveChrome", + { "depth": 79, "slug": 9980, "text": 9981 }, + "getchartcolorsmode", + "getChartColors(mode)", + { "depth": 79, "slug": 9983, "text": 9984 }, + "getchromecolorsisdark-mode", + "getChromeColors(isDark, mode)", + { "depth": 79, "slug": 9986, "text": 9987 }, + "enabling-executive-mode", + "Enabling Executive Mode", + { "depth": 33, "slug": 998, "text": 999 }, + { "depth": 33, "slug": 9990, "text": 9991 }, + "cross-platform-usage", + "Cross-Platform Usage", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 9925 }, + [], + "06-design-system/charts/executive-mode", + { + "id": 9997, + "data": 9999, + "body": 10004, + "filePath": 10005, + "digest": 10006, + "rendered": 10007 + }, + { + "title": 10000, + "editUrl": 16, + "head": 10001, + "template": 18, + "sidebar": 10002, + "pagefind": 16, + "draft": 20 + }, + "Executive Mode", + [], + { "hidden": 20, "attrs": 10003 }, + {}, + "# Executive Mode\n\nConsulting-grade chart styling for professional reports, following top-tier management consulting standards (McKinsey, Bain, BCG).\n\n## Philosophy\n\n- **Data-First**: The data is the hero. Chrome (axes, grids, borders) should recede.\n- **Clean & Minimal**: Remove unnecessary decorations. High data-ink ratio.\n- **Authoritative**: Strong, high-contrast colors for data; subtle neutrals for context.\n- **Typography**: Professional sans-serif fonts (Inter) with clear hierarchy.\n\n## Enabling Executive Mode\n\nSet `data-chart-mode=\"executive\"` on the `\u003Chtml>` element:\n\n```html\n\u003Chtml data-chart-mode=\"executive\" data-theme=\"light\">\u003C/html>\n```\n\nThe `useChartTheme` hook detects this attribute automatically and switches all chart colors to the executive palette. See [hooks.md](./hooks.md) for the full `useChartTheme` API.\n\n## Color Palette\n\nExecutive mode uses `executiveColors` for data and `executiveChrome` for UI chrome, both defined in `packages/charts/src/colors.ts`.\n\n### Status Colors\n\n| Role | Color | Hex | Note |\n| ------------- | ----------- | --------- | ---------------------------- |\n| **Pass** | Emerald | `#10b981` | Muted, professional green |\n| **Fail** | Red | `#ef4444` | Standard red for clarity |\n| **Warning** | Amber | `#f59e0b` | Standard warning color |\n| **Violation** | Deep Orange | `#ea580c` | Distinct from simple warning |\n\n### Data & Reference Lines\n\n| Role | Color | Hex | Note |\n| ------------------ | ---------- | --------- | ------------------------------------- |\n| **Primary / Mean** | Navy/Black | `#0f172a` | Nearly black for authority |\n| **Target** | Emerald | `#10b981` | Matching pass state |\n| **Spec Limits** | Slate | `#94a3b8` | Subtle, context only (don't distract) |\n| **Control Limits** | Slate | `#64748b` | Slightly darker context |\n| **Linear Fit** | Navy/Black | `#0f172a` | Authority line |\n| **Quadratic Fit** | Slate | `#475569` | Secondary analysis |\n| **Cumulative** | Slate | `#475569` | Distinct from bars |\n\n### Chrome (UI Elements)\n\nExecutive chrome is **light-mode only** (executive reports are rarely dark mode):\n\n| Element | Hex | Note |\n| ------------------ | --------- | ----------------------- |\n| Tooltip background | `#ffffff` | White |\n| Grid lines | `#e2e8f0` | Very subtle (slate-200) |\n| Axis primary | `#cbd5e1` | Subtle axis (slate-300) |\n| Axis secondary | `#e2e8f0` | Nearly invisible |\n| Label primary | `#334155` | Readable (slate-700) |\n| Label secondary | `#64748b` | Secondary text |\n| Point stroke | `#ffffff` | White for separation |\n| Box fill | `#94a3b8` | Neutral slate |\n| Box border | `#475569` | Darker contrast |\n\n## Typography\n\n- **Font Family**: `Inter`, `system-ui`, `sans-serif`\n- **Axis Labels**: Inter Medium (500), distinct from data\n- **Tick Labels**: Inter Medium (500) with `fontFamily: 'Inter, sans-serif'`\n- **Signatures**: Professional sans-serif watermark, not handwritten\n\n## Layout Principles\n\n1. **Grid Lines**: Extremely subtle (slate-200), dashed with reduced opacity (`strokeDasharray=\"2,4\"`, `strokeOpacity={0.5}`)\n2. **Axes**: Minimalist. Left axis stroke set to `transparent` in executive mode to remove bounding box\n3. **Whitespace**: Generous padding around the chart to let data breathe\n4. **Data Points**: Smaller radius (3px vs 4px standard), thicker stroke (1.5px) for crisp definition\n5. **Data Line**: Thicker (1.5px) with lower opacity (0.3) for subtle connection\n\n## Implementation Details\n\n### Color Resolution in useChartTheme\n\n```typescript\nconst { isDark, mode, chrome, colors, fontScale } = useChartTheme();\n\n// When mode === 'executive':\n// chrome = executiveChrome (always, regardless of isDark)\n// colors = executiveColors\n\n// When mode === 'technical':\n// chrome = isDark ? chromeColors : chromeColorsLight\n// colors = chartColors\n```\n\n### Conditional Rendering in Charts\n\nCharts apply executive styling conditionally:\n\n```tsx\nconst { chrome, mode } = useChartTheme();\nconst isExecutive = mode === 'executive';\n\n// Grid: dashed + low opacity in executive\n\u003CGridRows\n stroke={chrome.gridLine}\n strokeDasharray={isExecutive ? '2,4' : undefined}\n strokeOpacity={isExecutive ? 0.5 : 1}\n/>\n\n// Axes: hidden stroke in executive\n\u003CAxisLeft\n stroke={isExecutive ? 'transparent' : chrome.axisPrimary}\n tickLabelProps={() => ({\n fontFamily: isExecutive ? 'Inter, sans-serif' : 'monospace',\n fontWeight: isExecutive ? 500 : 400,\n })}\n/>\n```\n\n### Function API\n\n```typescript\nimport { getChartColors, getChromeColors } from '@variscout/charts';\n\n// Get data colors\nconst colors = getChartColors('executive'); // executiveColors\nconst colors = getChartColors('technical'); // chartColors (default)\n\n// Get chrome colors (executive ignores isDark)\nconst chrome = getChromeColors(true, 'executive'); // executiveChrome\nconst chrome = getChromeColors(false, 'executive'); // executiveChrome\nconst chrome = getChromeColors(true, 'technical'); // chromeColors (dark)\nconst chrome = getChromeColors(false, 'technical'); // chromeColorsLight\n```\n\n## Background Colors\n\n- **Azure App**: Pure white (`#ffffff`) background recommended for executive reports\n- **PWA**: Context-aware (supports both dark/light themes in technical mode)\n\n---\n\n## See Also\n\n- [Colors](./colors.md) - Full color constant reference including executive palette\n- [Hooks](./hooks.md) - useChartTheme hook API\n- [Overview](./overview.md) - Chart design system overview", + "src/content/docs/06-design-system/charts/executive-mode.md", + "4b5375446268c45b", + { "html": 10008, "metadata": 10009 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"executive-mode\">Executive Mode\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#executive-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Executive Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Consulting-grade chart styling for professional reports, following top-tier management consulting standards (McKinsey, Bain, BCG).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy\">Philosophy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Data-First\u003C/strong>: The data is the hero. Chrome (axes, grids, borders) should recede.\u003C/li>\n\u003Cli>\u003Cstrong>Clean & Minimal\u003C/strong>: Remove unnecessary decorations. High data-ink ratio.\u003C/li>\n\u003Cli>\u003Cstrong>Authoritative\u003C/strong>: Strong, high-contrast colors for data; subtle neutrals for context.\u003C/li>\n\u003Cli>\u003Cstrong>Typography\u003C/strong>: Professional sans-serif fonts (Inter) with clear hierarchy.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"enabling-executive-mode\">Enabling Executive Mode\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#enabling-executive-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Enabling Executive Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Set \u003Ccode dir=\"auto\">data-chart-mode=\"executive\"\u003C/code> on the \u003Ccode dir=\"auto\"><html>\u003C/code> element:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">html\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data-chart-mode\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">executive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data-theme\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">light\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\">></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">html\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Chtml data-chart-mode="executive" data-theme="light">\u003C/html>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">useChartTheme\u003C/code> hook detects this attribute automatically and switches all chart colors to the executive palette. See \u003Ca href=\"./hooks.md\">hooks.md\u003C/a> for the full \u003Ccode dir=\"auto\">useChartTheme\u003C/code> API.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"color-palette\">Color Palette\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#color-palette\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color Palette”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Executive mode uses \u003Ccode dir=\"auto\">executiveColors\u003C/code> for data and \u003Ccode dir=\"auto\">executiveChrome\u003C/code> for UI chrome, both defined in \u003Ccode dir=\"auto\">packages/charts/src/colors.ts\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"status-colors\">Status Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#status-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Status Colors”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Note\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Pass\u003C/strong>\u003C/td>\u003Ctd>Emerald\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#10b981\u003C/code>\u003C/td>\u003Ctd>Muted, professional green\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Fail\u003C/strong>\u003C/td>\u003Ctd>Red\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ef4444\u003C/code>\u003C/td>\u003Ctd>Standard red for clarity\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Warning\u003C/strong>\u003C/td>\u003Ctd>Amber\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f59e0b\u003C/code>\u003C/td>\u003Ctd>Standard warning color\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Violation\u003C/strong>\u003C/td>\u003Ctd>Deep Orange\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ea580c\u003C/code>\u003C/td>\u003Ctd>Distinct from simple warning\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data--reference-lines\">Data & Reference Lines\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data--reference-lines\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data & Reference Lines”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Role\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Note\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Primary / Mean\u003C/strong>\u003C/td>\u003Ctd>Navy/Black\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#0f172a\u003C/code>\u003C/td>\u003Ctd>Nearly black for authority\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Target\u003C/strong>\u003C/td>\u003Ctd>Emerald\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#10b981\u003C/code>\u003C/td>\u003Ctd>Matching pass state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Spec Limits\u003C/strong>\u003C/td>\u003Ctd>Slate\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003Ctd>Subtle, context only (don’t distract)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Control Limits\u003C/strong>\u003C/td>\u003Ctd>Slate\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>Slightly darker context\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Linear Fit\u003C/strong>\u003C/td>\u003Ctd>Navy/Black\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#0f172a\u003C/code>\u003C/td>\u003Ctd>Authority line\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Quadratic Fit\u003C/strong>\u003C/td>\u003Ctd>Slate\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#475569\u003C/code>\u003C/td>\u003Ctd>Secondary analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Cumulative\u003C/strong>\u003C/td>\u003Ctd>Slate\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#475569\u003C/code>\u003C/td>\u003Ctd>Distinct from bars\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"chrome-ui-elements\">Chrome (UI Elements)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#chrome-ui-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chrome (UI Elements)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Executive chrome is \u003Cstrong>light-mode only\u003C/strong> (executive reports are rarely dark mode):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Note\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Tooltip background\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ffffff\u003C/code>\u003C/td>\u003Ctd>White\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Grid lines\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#e2e8f0\u003C/code>\u003C/td>\u003Ctd>Very subtle (slate-200)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Axis primary\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#cbd5e1\u003C/code>\u003C/td>\u003Ctd>Subtle axis (slate-300)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Axis secondary\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#e2e8f0\u003C/code>\u003C/td>\u003Ctd>Nearly invisible\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Label primary\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#334155\u003C/code>\u003C/td>\u003Ctd>Readable (slate-700)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Label secondary\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>Secondary text\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Point stroke\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ffffff\u003C/code>\u003C/td>\u003Ctd>White for separation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Box fill\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003Ctd>Neutral slate\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Box border\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#475569\u003C/code>\u003C/td>\u003Ctd>Darker contrast\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"typography\">Typography\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#typography\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Typography”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Font Family\u003C/strong>: \u003Ccode dir=\"auto\">Inter\u003C/code>, \u003Ccode dir=\"auto\">system-ui\u003C/code>, \u003Ccode dir=\"auto\">sans-serif\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Axis Labels\u003C/strong>: Inter Medium (500), distinct from data\u003C/li>\n\u003Cli>\u003Cstrong>Tick Labels\u003C/strong>: Inter Medium (500) with \u003Ccode dir=\"auto\">fontFamily: 'Inter, sans-serif'\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Signatures\u003C/strong>: Professional sans-serif watermark, not handwritten\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"layout-principles\">Layout Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#layout-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layout Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Grid Lines\u003C/strong>: Extremely subtle (slate-200), dashed with reduced opacity (\u003Ccode dir=\"auto\">strokeDasharray=\"2,4\"\u003C/code>, \u003Ccode dir=\"auto\">strokeOpacity={0.5}\u003C/code>)\u003C/li>\n\u003Cli>\u003Cstrong>Axes\u003C/strong>: Minimalist. Left axis stroke set to \u003Ccode dir=\"auto\">transparent\u003C/code> in executive mode to remove bounding box\u003C/li>\n\u003Cli>\u003Cstrong>Whitespace\u003C/strong>: Generous padding around the chart to let data breathe\u003C/li>\n\u003Cli>\u003Cstrong>Data Points\u003C/strong>: Smaller radius (3px vs 4px standard), thicker stroke (1.5px) for crisp definition\u003C/li>\n\u003Cli>\u003Cstrong>Data Line\u003C/strong>: Thicker (1.5px) with lower opacity (0.3) for subtle connection\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation-details\">Implementation Details\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-details\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation Details”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"color-resolution-in-usecharttheme\">Color Resolution in useChartTheme\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#color-resolution-in-usecharttheme\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color Resolution in useChartTheme”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isDark\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mode\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">colors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fontScale\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// When mode === 'executive':\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chrome = executiveChrome (always, regardless of isDark)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// colors = executiveColors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// When mode === 'technical':\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chrome = isDark ? chromeColors : chromeColorsLight\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// colors = chartColors\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { isDark, mode, chrome, colors, fontScale } = useChartTheme();// When mode === 'executive':// chrome = executiveChrome (always, regardless of isDark)// colors = executiveColors// When mode === 'technical':// chrome = isDark ? chromeColors : chromeColorsLight// colors = chartColors\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"conditional-rendering-in-charts\">Conditional Rendering in Charts\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#conditional-rendering-in-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Conditional Rendering in Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Charts apply executive styling conditionally:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mode\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isExecutive\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mode\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> === \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">executive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Grid: dashed + low opacity in executive\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">GridRows\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">gridLine\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeDasharray\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isExecutive\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">2,4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isExecutive\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.5\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Axes: hidden stroke in executive\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">AxisLeft\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isExecutive\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">transparent\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">axisPrimary\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">tickLabelProps\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">fontFamily: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isExecutive\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Inter, sans-serif\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">monospace\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">fontWeight: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isExecutive\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">500\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">400\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { chrome, mode } = useChartTheme();const isExecutive = mode === 'executive';// Grid: dashed + low opacity in executive\u003CGridRows stroke={chrome.gridLine} strokeDasharray={isExecutive ? '2,4' : undefined} strokeOpacity={isExecutive ? 0.5 : 1}/>// Axes: hidden stroke in executive\u003CAxisLeft stroke={isExecutive ? 'transparent' : chrome.axisPrimary} tickLabelProps={() => ({ fontFamily: isExecutive ? 'Inter, sans-serif' : 'monospace', fontWeight: isExecutive ? 500 : 400, })}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"function-api\">Function API\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#function-api\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Function API”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { getChartColors, getChromeColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Get data colors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">colors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChartColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">executive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// executiveColors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">colors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChartColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">technical\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chartColors (default)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Get chrome colors (executive ignores isDark)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChromeColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">executive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// executiveChrome\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChromeColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">executive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// executiveChrome\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChromeColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">technical\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chromeColors (dark)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getChromeColors\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">technical\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chromeColorsLight\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { getChartColors, getChromeColors } from '@variscout/charts';// Get data colorsconst colors = getChartColors('executive'); // executiveColorsconst colors = getChartColors('technical'); // chartColors (default)// Get chrome colors (executive ignores isDark)const chrome = getChromeColors(true, 'executive'); // executiveChromeconst chrome = getChromeColors(false, 'executive'); // executiveChromeconst chrome = getChromeColors(true, 'technical'); // chromeColors (dark)const chrome = getChromeColors(false, 'technical'); // chromeColorsLight\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"background-colors\">Background Colors\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#background-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Background Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Azure App\u003C/strong>: Pure white (\u003Ccode dir=\"auto\">#ffffff\u003C/code>) background recommended for executive reports\u003C/li>\n\u003Cli>\u003Cstrong>PWA\u003C/strong>: Context-aware (supports both dark/light themes in technical mode)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - Full color constant reference including executive palette\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - useChartTheme hook API\u003C/li>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview\u003C/li>\n\u003C/ul>", + { + "headings": 10010, + "localImagePaths": 10049, + "remoteImagePaths": 10050, + "frontmatter": 10051, + "imagePaths": 10052 + }, + [ + 10011, 10013, 10014, 10015, 10018, 10021, 10024, 10027, 10030, 10033, 10036, 10039, 10042, + 10045, 10048 + ], + { "depth": 30, "slug": 10012, "text": 10000 }, + "executive-mode", + { "depth": 33, "slug": 965, "text": 966 }, + { "depth": 33, "slug": 9986, "text": 9987 }, + { "depth": 33, "slug": 10016, "text": 10017 }, + "color-palette", + "Color Palette", + { "depth": 79, "slug": 10019, "text": 10020 }, + "status-colors", + "Status Colors", + { "depth": 79, "slug": 10022, "text": 10023 }, + "data--reference-lines", + "Data & Reference Lines", + { "depth": 79, "slug": 10025, "text": 10026 }, + "chrome-ui-elements", + "Chrome (UI Elements)", + { "depth": 33, "slug": 10028, "text": 10029 }, + "typography", + "Typography", + { "depth": 33, "slug": 10031, "text": 10032 }, + "layout-principles", + "Layout Principles", + { "depth": 33, "slug": 10034, "text": 10035 }, + "implementation-details", + "Implementation Details", + { "depth": 79, "slug": 10037, "text": 10038 }, + "color-resolution-in-usecharttheme", + "Color Resolution in useChartTheme", + { "depth": 79, "slug": 10040, "text": 10041 }, + "conditional-rendering-in-charts", + "Conditional Rendering in Charts", + { "depth": 79, "slug": 10043, "text": 10044 }, + "function-api", + "Function API", + { "depth": 33, "slug": 10046, "text": 10047 }, + "background-colors", + "Background Colors", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 10000 }, + [], + "06-design-system/charts/hooks", + { + "id": 10053, + "data": 10055, + "body": 10060, + "filePath": 10061, + "digest": 10062, + "rendered": 10063 + }, + { + "title": 10056, + "editUrl": 16, + "head": 10057, + "template": 18, + "sidebar": 10058, + "pagefind": 16, + "draft": 20 + }, + "Chart Hooks", + [], + { "hidden": 20, "attrs": 10059 }, + {}, + "# Chart Hooks\n\nReact hooks for chart layout, tooltips, and selection state in `@variscout/charts`.\n\n## Overview\n\n| Hook | Purpose |\n| ------------------- | ------------------------------------------------------------- |\n| `useChartLayout` | Consolidated layout calculations (margins, fonts, dimensions) |\n| `useChartTooltip` | Unified tooltip positioning |\n| `useSelectionState` | Selection state and opacity management |\n| `useChartTheme` | Theme-aware colors with executive mode support |\n| `useMultiSelection` | Minitab-style brushing and multi-point selection |\n\n**Source:** `packages/charts/src/hooks/`, `packages/charts/src/useChartTheme.ts`\n\n---\n\n## useChartLayout\n\nConsolidates all common chart initialization logic into a single hook.\n\n**Source:** `packages/charts/src/hooks/useChartLayout.ts`\n\n### Options\n\n```typescript\ninterface UseChartLayoutOptions {\n parentWidth: number; // Container width in pixels\n parentHeight: number; // Container height in pixels\n chartType: ChartType; // 'ichart' | 'boxplot' | 'pareto' | 'histogram' | 'scatter'\n showBranding?: boolean; // Show source bar (default: true)\n marginOverride?: ChartMargins; // Bypass responsive margins\n fontsOverride?: ChartFonts; // Bypass responsive fonts\n}\n```\n\n### Returns\n\n```typescript\ninterface ChartLayout {\n fonts: ChartFonts; // Scaled font sizes\n margin: ChartMargins; // Chart margins\n sourceBarHeight: number; // Height of branding bar\n width: number; // Inner chart width\n height: number; // Inner chart height\n fontScale: number; // Font scale from theme\n}\n```\n\n### Usage\n\n```tsx\nimport { useChartLayout } from '@variscout/charts';\n\nconst MyChart: React.FC\u003C{ parentWidth: number; parentHeight: number }> = ({\n parentWidth,\n parentHeight,\n}) => {\n const { fonts, margin, width, height, sourceBarHeight } = useChartLayout({\n parentWidth,\n parentHeight,\n chartType: 'ichart',\n showBranding: true,\n });\n\n return (\n \u003Csvg width={parentWidth} height={parentHeight}>\n \u003CGroup left={margin.left} top={margin.top}>\n {/* Chart content using width, height, fonts */}\n \u003C/Group>\n \u003C/svg>\n );\n};\n```\n\n### What It Combines\n\n1. **Font scale** from `useChartTheme()` (theme-aware)\n2. **Source bar height** from `getSourceBarHeight(showBranding)`\n3. **Responsive margins** from `getResponsiveMargins(width, chartType)`\n4. **Scaled fonts** from `getScaledFonts(width, fontScale)`\n5. **Inner dimensions** calculated from parent size minus margins\n\n---\n\n## useChartTooltip\n\nUnified tooltip positioning with two positioning methods.\n\n**Source:** `packages/charts/src/hooks/useChartTooltip.ts`\n\n### Returns\n\n```typescript\ninterface UseChartTooltipReturn\u003CT> {\n tooltipData: T | undefined;\n tooltipLeft: number | undefined;\n tooltipTop: number | undefined;\n tooltipOpen: boolean;\n showTooltipAtPoint: (event: React.MouseEvent, data: T) => void;\n showTooltipAtCoords: (x: number, y: number, data: T) => void;\n hideTooltip: () => void;\n usesLocalPoint: boolean;\n}\n```\n\n### Two Positioning Methods\n\n#### `showTooltipAtPoint(event, data)`\n\nUses `localPoint()` from mouse event. Tooltip follows cursor.\n\n```tsx\nconst { showTooltipAtPoint, hideTooltip, tooltipLeft, tooltipTop, tooltipData } =\n useChartTooltip\u003CMyData>();\n\n\u003CCircle\n onMouseMove={(e) => showTooltipAtPoint(e, data)}\n onMouseLeave={hideTooltip}\n/>\n\n// No margin offset needed when rendering\n\u003CTooltipWithBounds left={tooltipLeft} top={tooltipTop}>\n {tooltipData?.label}\n\u003C/TooltipWithBounds>\n```\n\n#### `showTooltipAtCoords(x, y, data)`\n\nUses scale values directly. Tooltip appears at data point.\n\n```tsx\nconst { showTooltipAtCoords, hideTooltip, tooltipLeft, tooltipTop, usesLocalPoint, margin } =\n useChartTooltip\u003CMyData>();\n\n\u003CCircle\n onMouseOver={() => showTooltipAtCoords(xScale(d.x), yScale(d.y), d)}\n onMouseLeave={hideTooltip}\n/>\n\n// Requires margin offset when rendering\n\u003CTooltipWithBounds\n left={usesLocalPoint ? tooltipLeft : margin.left + (tooltipLeft ?? 0)}\n top={usesLocalPoint ? tooltipTop : margin.top + (tooltipTop ?? 0)}\n>\n {tooltipData?.label}\n\u003C/TooltipWithBounds>\n```\n\n### `usesLocalPoint` Flag\n\nThe hook tracks which method was used so you can conditionally apply margin offsets:\n\n```tsx\nconst offsetLeft = usesLocalPoint ? tooltipLeft : margin.left + (tooltipLeft ?? 0);\nconst offsetTop = usesLocalPoint ? tooltipTop : margin.top + (tooltipTop ?? 0);\n```\n\n---\n\n## useSelectionState\n\nManages selection state and opacity for chart elements.\n\n**Source:** `packages/charts/src/hooks/useSelectionState.ts`\n\n### Options\n\n```typescript\ninterface UseSelectionStateOptions {\n selectedKeys: string[]; // Currently selected keys\n}\n```\n\n### Returns\n\n```typescript\ninterface UseSelectionStateReturn {\n isSelected: (key: string) => boolean;\n hasSelection: boolean;\n getOpacity: (key: string) => number;\n}\n```\n\n### Opacity Values\n\n```typescript\nexport const selectionOpacity = {\n selected: 1, // Active/selected items\n dimmed: 0.3, // Unselected when selection exists\n};\n```\n\n### Usage\n\n```tsx\nimport { useSelectionState, chartColors, chromeColors } from '@variscout/charts';\n\nconst { isSelected, hasSelection, getOpacity } = useSelectionState({\n selectedKeys: selectedBars,\n});\n\n{\n data.map(d => (\n \u003CBar\n key={d.key}\n fill={isSelected(d.key) ? chartColors.selected : chromeColors.boxDefault}\n opacity={getOpacity(d.key)}\n onClick={() => onSelect(d.key)}\n />\n ));\n}\n```\n\n### Behavior\n\n| Condition | `getOpacity(key)` Result |\n| ------------------------------------- | ------------------------ |\n| No selection exists | 1 (full opacity) |\n| Key is selected | 1 (full opacity) |\n| Key not selected, but other items are | 0.3 (dimmed) |\n\n---\n\n## useChartTheme\n\nProvides theme-aware chart colors with automatic updates when the theme changes.\n\n**Source:** `packages/charts/src/useChartTheme.ts`\n\n### Interface\n\n```typescript\ninterface ChartThemeColors {\n /** Whether dark theme is active */\n isDark: boolean;\n /** Current chart mode */\n mode: 'technical' | 'executive';\n /** Chrome colors for current theme and mode */\n chrome: ChromeColorValues;\n /** Data colors for current mode */\n colors: Record\u003CChartColor, string>;\n /** Font scale multiplier (from data-chart-scale attribute) */\n fontScale: number;\n}\n```\n\n### Usage\n\n```tsx\nimport { useChartTheme } from '@variscout/charts';\n\nconst MyChart = () => {\n const { isDark, mode, chrome, colors, fontScale } = useChartTheme();\n\n // Use chrome.xxx for UI elements (adapts to theme + mode):\n // chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\n\n // Use colors.xxx for data elements (adapts to mode):\n // colors.pass, colors.fail, colors.mean, colors.spec, etc.\n\n const isExecutive = mode === 'executive';\n};\n```\n\n### Observed Attributes\n\nThe hook watches three `\u003Chtml>` element attributes via `MutationObserver`:\n\n| Attribute | Values | Purpose |\n| ------------------ | ------------------------------ | --------------------- |\n| `data-theme` | `'light'` or `'dark'` | Theme switching |\n| `data-chart-mode` | `'technical'` or `'executive'` | Color palette mode |\n| `data-chart-scale` | Numeric string (e.g. `'1.2'`) | Font scale multiplier |\n\n### Color Resolution\n\n| Mode | isDark | chrome source | colors source |\n| ----------- | ------ | ------------------- | ----------------- |\n| `technical` | true | `chromeColors` | `chartColors` |\n| `technical` | false | `chromeColorsLight` | `chartColors` |\n| `executive` | any | `executiveChrome` | `executiveColors` |\n\n---\n\n## useMultiSelection\n\nMinitab-style brushing and multi-point selection for scatter/time-series charts.\n\n**Source:** `packages/charts/src/hooks/useMultiSelection.ts`\n\n### Options\n\n```typescript\ninterface UseMultiSelectionOptions\u003CT> {\n /** Chart data points */\n data: T[];\n /** X-axis scale (visx/d3 scale) */\n xScale: ChartScale;\n /** Y-axis scale (visx/d3 scale) */\n yScale: ChartScale;\n /** Currently selected point indices (controlled state) */\n selectedPoints: Set\u003Cnumber>;\n /** Callback when selection changes */\n onSelectionChange: (indices: Set\u003Cnumber>) => void;\n /** Accessor for X value (default: d => d.x) */\n getX?: (d: T, index: number) => number;\n /** Accessor for Y value (default: d => d.y) */\n getY?: (d: T, index: number) => number;\n /** Enable brush selection (default: true) */\n enableBrush?: boolean;\n}\n```\n\n### Returns\n\n```typescript\ninterface UseMultiSelectionResult {\n brushExtent: BrushExtent | null;\n isBrushing: boolean;\n handleBrushStart: (event: React.MouseEvent\u003CSVGElement>) => void;\n handleBrushMove: (event: React.MouseEvent\u003CSVGElement>) => void;\n handleBrushEnd: () => void;\n handlePointClick: (index: number, event: React.MouseEvent) => void;\n isPointSelected: (index: number) => boolean;\n getPointOpacity: (index: number) => number;\n getPointSize: (index: number) => number;\n getPointStrokeWidth: (index: number) => number;\n}\n```\n\n### Interaction Modes\n\n| Action | Behavior |\n| ---------------- | -------------------------------- |\n| Drag region | Select all points within brush |\n| Click | Replace selection with one point |\n| Ctrl/Cmd + click | Toggle point in/out of selection |\n| Shift + click | Add point to selection |\n\n### Visual Styling\n\n| State | Opacity | Size | Stroke Width |\n| ----------------------- | ------- | ---- | ------------ |\n| No selection exists | 1.0 | 4 | 1 |\n| Selected | 1.0 | 6 | 2 |\n| Unselected (has others) | 0.3 | 4 | 1 |\n\n### Usage\n\n```tsx\nimport { useMultiSelection } from '@variscout/charts';\n\nconst {\n brushExtent,\n isBrushing,\n handleBrushStart,\n handleBrushMove,\n handleBrushEnd,\n handlePointClick,\n isPointSelected,\n getPointOpacity,\n getPointSize,\n getPointStrokeWidth,\n} = useMultiSelection({\n data,\n xScale,\n yScale,\n selectedPoints,\n onSelectionChange,\n enableBrush: true,\n});\n\n// Wire up SVG event handlers\n\u003Csvg\n onMouseDown={handleBrushStart}\n onMouseMove={handleBrushMove}\n onMouseUp={handleBrushEnd}\n onMouseLeave={handleBrushEnd}\n>\n {data.map((d, i) => (\n \u003CCircle\n r={getPointSize(i)}\n opacity={getPointOpacity(i)}\n strokeWidth={getPointStrokeWidth(i)}\n onClick={e => handlePointClick(i, e)}\n />\n ))}\n\u003C/svg>;\n```\n\nCurrently used by the **IChart** component for `enableBrushSelection` mode.\n\n---\n\n## useChartCopy\n\nCopy chart to clipboard or download as PNG/SVG with fixed, presentation-ready dimensions. All exports temporarily resize the chart container off-screen, wait for visx ResizeObserver re-render, then capture — producing identical output from dashboard cards and focused views.\n\n**Source:** `packages/hooks/src/useChartCopy.ts`\n\n### Options\n\n```typescript\ninterface UseChartCopyOptions {\n /** Return background color for the screenshot. Called at copy time. Defaults to #0f172a. */\n getBackgroundColor?: () => string;\n}\n```\n\n### Returns\n\n```typescript\ninterface UseChartCopyReturn {\n copyFeedback: string | null;\n handleCopyChart: (containerId: string, chartName: string) => Promise\u003Cvoid>;\n handleDownloadPng: (containerId: string, chartName: string) => Promise\u003Cvoid>;\n handleDownloadSvg: (containerId: string, chartName: string) => void;\n}\n```\n\n### Fixed Export Dimensions\n\nAll charts export at fixed dimensions regardless of current container size:\n\n| Chart | Width | Height | Actual (x2) |\n| ------------- | ----- | ------ | ----------- |\n| `ichart` | 1200 | 540 | 2400 x 1080 |\n| `boxplot` | 1200 | 800 | 2400 x 1600 |\n| `pareto` | 1200 | 720 | 2400 x 1440 |\n| `histogram` | 800 | 600 | 1600 x 1200 |\n| `probability` | 800 | 700 | 1600 x 1400 |\n| `stats` | 1200 | 400 | 2400 x 800 |\n| `dashboard` | 1600 | auto | 3200 x auto |\n\nUnknown chart names fall back to 1200 x 675. The `EXPORT_SIZES` map is exported from `@variscout/hooks` for reference.\n\n**Auto-height mode**: When `height` is `0` in EXPORT_SIZES (used by `dashboard`), `withFixedSize` sets `height: auto; overflow: visible` instead of a fixed pixel height. This captures the full scrollable content without clipping. At 1600px width, the `lg:flex-row` breakpoint is active so charts render side-by-side.\n\n### Usage\n\n```tsx\nimport { useChartCopy } from '@variscout/hooks';\n\nconst { copyFeedback, handleCopyChart, handleDownloadPng, handleDownloadSvg } = useChartCopy({\n getBackgroundColor: () => isDark ? '#0f172a' : '#ffffff',\n});\n\n// Copy to clipboard (1-click)\n\u003Cbutton onClick={() => handleCopyChart('ichart-card', 'ichart')}>\n {copyFeedback === 'ichart' ? \u003CCheck size={14} /> : \u003CCopy size={14} />}\n\u003C/button>\n\n// Download menu (via ChartDownloadMenu from @variscout/ui)\n\u003CChartDownloadMenu\n containerId=\"boxplot-card\"\n chartName=\"boxplot\"\n onDownloadPng={handleDownloadPng}\n onDownloadSvg={handleDownloadSvg}\n/>\n```\n\n### Dashboard Export\n\nThe full dashboard can be exported as a single image for PowerPoint slides. Copy/Download buttons sit in the sticky nav bar:\n\n```tsx\n// Dashboard export uses the same hook — just pass 'dashboard' as chartName\n\u003Cbutton onClick={() => handleCopyChart('dashboard-export-container', 'dashboard')}>\n {copyFeedback === 'dashboard' ? \u003CCheck size={14} /> : \u003CCopy size={14} />}\n\u003C/button>\n\u003Cbutton onClick={() => handleDownloadPng('dashboard-export-container', 'dashboard')}>\n \u003CDownload size={14} />\n\u003C/button>\n```\n\nNo SVG export for dashboard (multi-SVG composition doesn't serialize cleanly).\n\n### How Fixed-Size Export Works\n\n1. Sets `data-exporting=\"true\"` on the container (hides UI-only elements via CSS)\n2. Saves current `style.cssText` and locks parent `min-height`\n3. Moves container off-screen at fixed export dimensions (`position: fixed; left: -9999px`)\n4. Waits for visx ResizeObserver + React re-render (~100ms: double rAF + setTimeout)\n5. Captures with `html-to-image` at `pixelRatio: 2`\n6. Restores original styles and parent lock (even on error)\n\n---\n\n## Import Pattern\n\n```typescript\nimport {\n useChartLayout,\n useChartTooltip,\n useSelectionState,\n selectionOpacity,\n useChartTheme,\n} from '@variscout/charts';\n\nimport { useMultiSelection } from '@variscout/charts/hooks/useMultiSelection';\n```\n\n---\n\n## Complete Example\n\n```tsx\nimport {\n useChartLayout,\n useChartTooltip,\n useSelectionState,\n ChartTooltip,\n} from '@variscout/charts';\n\nconst MyChart: React.FC\u003CProps> = ({ parentWidth, parentHeight, data, selectedKeys }) => {\n // Layout\n const { fonts, margin, width, height } = useChartLayout({\n parentWidth,\n parentHeight,\n chartType: 'boxplot',\n });\n\n // Tooltip\n const { tooltipData, tooltipOpen, tooltipLeft, tooltipTop, showTooltipAtPoint, hideTooltip } =\n useChartTooltip\u003CDataPoint>();\n\n // Selection\n const { getOpacity } = useSelectionState({ selectedKeys });\n\n return (\n \u003Cdiv style={{ position: 'relative' }}>\n \u003Csvg width={parentWidth} height={parentHeight}>\n \u003CGroup left={margin.left} top={margin.top}>\n {data.map(d => (\n \u003CBar\n key={d.key}\n opacity={getOpacity(d.key)}\n onMouseMove={e => showTooltipAtPoint(e, d)}\n onMouseLeave={hideTooltip}\n />\n ))}\n \u003C/Group>\n \u003C/svg>\n\n \u003CChartTooltip\n data={tooltipData}\n isOpen={tooltipOpen}\n left={tooltipLeft}\n top={tooltipTop}\n fonts={fonts}\n >\n {d => (\n \u003Cdiv>\n {d.label}: {d.value}\n \u003C/div>\n )}\n \u003C/ChartTooltip>\n \u003C/div>\n );\n};\n```\n\n---\n\n## See Also\n\n- [Overview](./overview.md) - Chart design system overview and selection guide\n- [Colors](./colors.md) - `useChartTheme` hook for theme-aware colors\n- [Responsive](./responsive.md) - Underlying responsive utilities\n- [Shared Components](./shared-components.md) - ChartTooltip component", + "src/content/docs/06-design-system/charts/hooks.md", + "dc1db8b3a3775da0", + { "html": 10064, "metadata": 10065 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"chart-hooks\">Chart Hooks\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#chart-hooks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Hooks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>React hooks for chart layout, tooltips, and selection state in \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Hook\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useChartLayout\u003C/code>\u003C/td>\u003Ctd>Consolidated layout calculations (margins, fonts, dimensions)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useChartTooltip\u003C/code>\u003C/td>\u003Ctd>Unified tooltip positioning\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useSelectionState\u003C/code>\u003C/td>\u003Ctd>Selection state and opacity management\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useChartTheme\u003C/code>\u003C/td>\u003Ctd>Theme-aware colors with executive mode support\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useMultiSelection\u003C/code>\u003C/td>\u003Ctd>Minitab-style brushing and multi-point selection\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/hooks/\u003C/code>, \u003Ccode dir=\"auto\">packages/charts/src/useChartTheme.ts\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usechartlayout\">useChartLayout\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usechartlayout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useChartLayout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Consolidates all common chart initialization logic into a single hook.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/hooks/useChartLayout.ts\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"options\">Options\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#options\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Options”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> UseChartLayoutOptions {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Container width in pixels\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Container height in pixels\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartType\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 'ichart' | 'boxplot' | 'pareto' | 'histogram' | 'scatter'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showBranding\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Show source bar (default: true)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">marginOverride\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartMargins\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Bypass responsive margins\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontsOverride\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartFonts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Bypass responsive fonts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface UseChartLayoutOptions { parentWidth: number; // Container width in pixels parentHeight: number; // Container height in pixels chartType: ChartType; // 'ichart' | 'boxplot' | 'pareto' | 'histogram' | 'scatter' showBranding?: boolean; // Show source bar (default: true) marginOverride?: ChartMargins; // Bypass responsive margins fontsOverride?: ChartFonts; // Bypass responsive fonts}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"returns\">Returns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#returns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Returns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChartLayout {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fonts\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartFonts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Scaled font sizes\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartMargins\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart margins\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">sourceBarHeight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Height of branding bar\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Inner chart width\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Inner chart height\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontScale\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Font scale from theme\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ChartLayout { fonts: ChartFonts; // Scaled font sizes margin: ChartMargins; // Chart margins sourceBarHeight: number; // Height of branding bar width: number; // Inner chart width height: number; // Inner chart height fontScale: number; // Font scale from theme}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage\">Usage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useChartLayout } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">MyChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FC\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><{ \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">; \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sourceBarHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartLayout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">chartType: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ichart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">showBranding: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6;--1:#8844AE\">svg\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Group\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">left\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">left\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">top\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">top\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Chart content using width, height, fonts */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Group\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">svg\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useChartLayout } from '@variscout/charts';const MyChart: React.FC\u003C{ parentWidth: number; parentHeight: number }> = ({ parentWidth, parentHeight,}) => { const { fonts, margin, width, height, sourceBarHeight } = useChartLayout({ parentWidth, parentHeight, chartType: 'ichart', showBranding: true, }); return ( \u003Csvg width={parentWidth} height={parentHeight}> \u003CGroup left={margin.left} top={margin.top}> {/* Chart content using width, height, fonts */} \u003C/Group> \u003C/svg> );};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-it-combines\">What It Combines\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-it-combines\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What It Combines”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Font scale\u003C/strong> from \u003Ccode dir=\"auto\">useChartTheme()\u003C/code> (theme-aware)\u003C/li>\n\u003Cli>\u003Cstrong>Source bar height\u003C/strong> from \u003Ccode dir=\"auto\">getSourceBarHeight(showBranding)\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Responsive margins\u003C/strong> from \u003Ccode dir=\"auto\">getResponsiveMargins(width, chartType)\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Scaled fonts\u003C/strong> from \u003Ccode dir=\"auto\">getScaledFonts(width, fontScale)\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Inner dimensions\u003C/strong> calculated from parent size minus margins\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usecharttooltip\">useChartTooltip\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usecharttooltip\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useChartTooltip”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Unified tooltip positioning with two positioning methods.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/hooks/useChartTooltip.ts\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"returns-1\">Returns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#returns-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Returns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> UseChartTooltipReturn<\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">T\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipData\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">T\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipLeft\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipTop\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipOpen\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showTooltipAtPoint\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">event\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">MouseEvent\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">data\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#FFCB8B\">T\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showTooltipAtCoords\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">x\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">y\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">data\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#FFCB8B\">T\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hideTooltip\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">usesLocalPoint\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface UseChartTooltipReturn\u003CT> { tooltipData: T | undefined; tooltipLeft: number | undefined; tooltipTop: number | undefined; tooltipOpen: boolean; showTooltipAtPoint: (event: React.MouseEvent, data: T) => void; showTooltipAtCoords: (x: number, y: number, data: T) => void; hideTooltip: () => void; usesLocalPoint: boolean;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"two-positioning-methods\">Two Positioning Methods\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#two-positioning-methods\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two Positioning Methods”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"showtooltipatpointevent-data\">\u003Ccode dir=\"auto\">showTooltipAtPoint(event, data)\u003C/code>\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#showtooltipatpointevent-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “showTooltipAtPoint(event, data)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Uses \u003Ccode dir=\"auto\">localPoint()\u003C/code> from mouse event. Tooltip follows cursor.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showTooltipAtPoint\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hideTooltip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tooltipLeft\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tooltipTop\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tooltipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } =\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTooltip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">MyData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Circle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseMove\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showTooltipAtPoint\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(e\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseLeave\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">hideTooltip\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// No margin offset needed when rendering\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">TooltipWithBounds\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">left\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipLeft\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">top\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipTop\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">label\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">TooltipWithBounds\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { showTooltipAtPoint, hideTooltip, tooltipLeft, tooltipTop, tooltipData } = useChartTooltip\u003CMyData>();\u003CCircle onMouseMove={(e) => showTooltipAtPoint(e, data)} onMouseLeave={hideTooltip}/>// No margin offset needed when rendering\u003CTooltipWithBounds left={tooltipLeft} top={tooltipTop}> {tooltipData?.label}\u003C/TooltipWithBounds>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"showtooltipatcoordsx-y-data\">\u003Ccode dir=\"auto\">showTooltipAtCoords(x, y, data)\u003C/code>\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#showtooltipatcoordsx-y-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “showTooltipAtCoords(x, y, data)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Uses scale values directly. Tooltip appears at data point.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showTooltipAtCoords\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hideTooltip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tooltipLeft\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tooltipTop\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">usesLocalPoint\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } =\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTooltip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">MyData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Circle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseOver\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showTooltipAtCoords\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">xScale\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">x\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">yScale\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">y\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">d)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseLeave\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">hideTooltip\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Requires margin offset when rendering\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">TooltipWithBounds\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">left\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">usesLocalPoint\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipLeft\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">left\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">+\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(tooltipLeft\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">??\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">top\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">usesLocalPoint\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipTop\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">top\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">+\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(tooltipTop\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">??\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">label\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">TooltipWithBounds\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { showTooltipAtCoords, hideTooltip, tooltipLeft, tooltipTop, usesLocalPoint, margin } = useChartTooltip\u003CMyData>();\u003CCircle onMouseOver={() => showTooltipAtCoords(xScale(d.x), yScale(d.y), d)} onMouseLeave={hideTooltip}/>// Requires margin offset when rendering\u003CTooltipWithBounds left={usesLocalPoint ? tooltipLeft : margin.left + (tooltipLeft ?? 0)} top={usesLocalPoint ? tooltipTop : margin.top + (tooltipTop ?? 0)}> {tooltipData?.label}\u003C/TooltipWithBounds>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"useslocalpoint-flag\">\u003Ccode dir=\"auto\">usesLocalPoint\u003C/code> Flag\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#useslocalpoint-flag\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “usesLocalPoint Flag”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The hook tracks which method was used so you can conditionally apply margin offsets:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">offsetLeft\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">usesLocalPoint\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> ? \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipLeft\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> : \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">left\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> + \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(tooltipLeft\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> ?? \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">offsetTop\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">usesLocalPoint\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> ? \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipTop\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> : \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">top\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> + \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(tooltipTop\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> ?? \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const offsetLeft = usesLocalPoint ? tooltipLeft : margin.left + (tooltipLeft ?? 0);const offsetTop = usesLocalPoint ? tooltipTop : margin.top + (tooltipTop ?? 0);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"useselectionstate\">useSelectionState\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#useselectionstate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useSelectionState”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Manages selection state and opacity for chart elements.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/hooks/useSelectionState.ts\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"options-1\">Options\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#options-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Options”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> UseSelectionStateOptions {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedKeys\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Currently selected keys\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface UseSelectionStateOptions { selectedKeys: string[]; // Currently selected keys}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"returns-2\">Returns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#returns-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Returns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> UseSelectionStateReturn {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isSelected\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">hasSelection\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getOpacity\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface UseSelectionStateReturn { isSelected: (key: string) => boolean; hasSelection: boolean; getOpacity: (key: string) => number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"opacity-values\">Opacity Values\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#opacity-values\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Opacity Values”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectionOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">selected: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Active/selected items\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">dimmed: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.3\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Unselected when selection exists\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export const selectionOpacity = { selected: 1, // Active/selected items dimmed: 0.3, // Unselected when selection exists};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-1\">Usage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useSelectionState, chartColors, chromeColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isSelected\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hasSelection\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useSelectionState\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">selectedKeys: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedBars\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">d\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Bar\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">key\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isSelected\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">key\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">selected\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chromeColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">boxDefault\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">opacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getOpacity\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">key\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onSelect\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">key\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useSelectionState, chartColors, chromeColors } from '@variscout/charts';const { isSelected, hasSelection, getOpacity } = useSelectionState({ selectedKeys: selectedBars,});{ data.map(d => ( \u003CBar key={d.key} fill={isSelected(d.key) ? chartColors.selected : chromeColors.boxDefault} opacity={getOpacity(d.key)} onClick={() => onSelect(d.key)} /> ));}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"behavior\">Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Behavior”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Condition\u003C/th>\u003Cth>\u003Ccode dir=\"auto\">getOpacity(key)\u003C/code> Result\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No selection exists\u003C/td>\u003Ctd>1 (full opacity)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Key is selected\u003C/td>\u003Ctd>1 (full opacity)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Key not selected, but other items are\u003C/td>\u003Ctd>0.3 (dimmed)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usecharttheme\">useChartTheme\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usecharttheme\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useChartTheme”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Provides theme-aware chart colors with automatic updates when the theme changes.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/useChartTheme.ts\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interface\">Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChartThemeColors {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Whether dark theme is active */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isDark\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Current chart mode */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mode\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">technical\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">executive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Chrome colors for current theme and mode */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chrome\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChromeColorValues\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Data colors for current mode */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">colors\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Record\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartColor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Font scale multiplier (from data-chart-scale attribute) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontScale\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ChartThemeColors { /** Whether dark theme is active */ isDark: boolean; /** Current chart mode */ mode: 'technical' | 'executive'; /** Chrome colors for current theme and mode */ chrome: ChromeColorValues; /** Data colors for current mode */ colors: Record\u003CChartColor, string>; /** Font scale multiplier (from data-chart-scale attribute) */ fontScale: number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-2\">Usage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useChartTheme } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">MyChart\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isDark\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">mode\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">colors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fontScale\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Use chrome.xxx for UI elements (adapts to theme + mode):\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Use colors.xxx for data elements (adapts to mode):\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// colors.pass, colors.fail, colors.mean, colors.spec, etc.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isExecutive\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mode\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> === \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">executive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useChartTheme } from '@variscout/charts';const MyChart = () => { const { isDark, mode, chrome, colors, fontScale } = useChartTheme(); // Use chrome.xxx for UI elements (adapts to theme + mode): // chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc. // Use colors.xxx for data elements (adapts to mode): // colors.pass, colors.fail, colors.mean, colors.spec, etc. const isExecutive = mode === 'executive';};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"observed-attributes\">Observed Attributes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#observed-attributes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Observed Attributes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The hook watches three \u003Ccode dir=\"auto\"><html>\u003C/code> element attributes via \u003Ccode dir=\"auto\">MutationObserver\u003C/code>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Attribute\u003C/th>\u003Cth>Values\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">data-theme\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">'light'\u003C/code> or \u003Ccode dir=\"auto\">'dark'\u003C/code>\u003C/td>\u003Ctd>Theme switching\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">data-chart-mode\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">'technical'\u003C/code> or \u003Ccode dir=\"auto\">'executive'\u003C/code>\u003C/td>\u003Ctd>Color palette mode\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">data-chart-scale\u003C/code>\u003C/td>\u003Ctd>Numeric string (e.g. \u003Ccode dir=\"auto\">'1.2'\u003C/code>)\u003C/td>\u003Ctd>Font scale multiplier\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"color-resolution\">Color Resolution\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#color-resolution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color Resolution”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Mode\u003C/th>\u003Cth>isDark\u003C/th>\u003Cth>chrome source\u003C/th>\u003Cth>colors source\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">technical\u003C/code>\u003C/td>\u003Ctd>true\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chromeColors\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">technical\u003C/code>\u003C/td>\u003Ctd>false\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chromeColorsLight\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">executive\u003C/code>\u003C/td>\u003Ctd>any\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">executiveChrome\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">executiveColors\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usemultiselection\">useMultiSelection\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usemultiselection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useMultiSelection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Minitab-style brushing and multi-point selection for scatter/time-series charts.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/hooks/useMultiSelection.ts\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"options-2\">Options\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#options-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Options”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> UseMultiSelectionOptions<\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">T\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Chart data points */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">T\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** X-axis scale (visx/d3 scale) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">xScale\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartScale\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Y-axis scale (visx/d3 scale) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yScale\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartScale\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Currently selected point indices (controlled state) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback when selection changes */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onSelectionChange\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">indices\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Accessor for X value (default: d => d.x) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getX\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">d\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">T\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">index\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Accessor for Y value (default: d => d.y) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getY\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">d\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">T\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">index\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Enable brush selection (default: true) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">enableBrush\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface UseMultiSelectionOptions\u003CT> { /** Chart data points */ data: T[]; /** X-axis scale (visx/d3 scale) */ xScale: ChartScale; /** Y-axis scale (visx/d3 scale) */ yScale: ChartScale; /** Currently selected point indices (controlled state) */ selectedPoints: Set\u003Cnumber>; /** Callback when selection changes */ onSelectionChange: (indices: Set\u003Cnumber>) => void; /** Accessor for X value (default: d => d.x) */ getX?: (d: T, index: number) => number; /** Accessor for Y value (default: d => d.y) */ getY?: (d: T, index: number) => number; /** Enable brush selection (default: true) */ enableBrush?: boolean;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"returns-3\">Returns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#returns-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Returns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> UseMultiSelectionResult {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">brushExtent\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">BrushExtent\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isBrushing\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleBrushStart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">event\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">MouseEvent\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SVGElement\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleBrushMove\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">event\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">MouseEvent\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SVGElement\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleBrushEnd\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handlePointClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">event\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#FFCB8B\">MouseEvent\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isPointSelected\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointOpacity\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointSize\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointStrokeWidth\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface UseMultiSelectionResult { brushExtent: BrushExtent | null; isBrushing: boolean; handleBrushStart: (event: React.MouseEvent\u003CSVGElement>) => void; handleBrushMove: (event: React.MouseEvent\u003CSVGElement>) => void; handleBrushEnd: () => void; handlePointClick: (index: number, event: React.MouseEvent) => void; isPointSelected: (index: number) => boolean; getPointOpacity: (index: number) => number; getPointSize: (index: number) => number; getPointStrokeWidth: (index: number) => number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interaction-modes\">Interaction Modes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interaction-modes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interaction Modes”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Action\u003C/th>\u003Cth>Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Drag region\u003C/td>\u003Ctd>Select all points within brush\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Click\u003C/td>\u003Ctd>Replace selection with one point\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Ctrl/Cmd + click\u003C/td>\u003Ctd>Toggle point in/out of selection\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shift + click\u003C/td>\u003Ctd>Add point to selection\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"visual-styling\">Visual Styling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#visual-styling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Styling”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>State\u003C/th>\u003Cth>Opacity\u003C/th>\u003Cth>Size\u003C/th>\u003Cth>Stroke Width\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No selection exists\u003C/td>\u003Ctd>1.0\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Selected\u003C/td>\u003Ctd>1.0\u003C/td>\u003Ctd>6\u003C/td>\u003Ctd>2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Unselected (has others)\u003C/td>\u003Ctd>0.3\u003C/td>\u003Ctd>4\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-3\">Usage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useMultiSelection } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">brushExtent\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isBrushing\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleBrushStart\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleBrushMove\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleBrushEnd\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handlePointClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isPointSelected\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointSize\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointStrokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">} = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useMultiSelection\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">xScale\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yScale\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onSelectionChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">enableBrush: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Wire up SVG event handlers\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">svg\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseDown\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleBrushStart\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseMove\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleBrushMove\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseUp\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleBrushEnd\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseLeave\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleBrushEnd\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">d\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">i\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Circle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">r\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointSize\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(i)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">opacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointOpacity\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(i)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointStrokeWidth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(i)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handlePointClick\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(i\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">e)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">svg\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useMultiSelection } from '@variscout/charts';const { brushExtent, isBrushing, handleBrushStart, handleBrushMove, handleBrushEnd, handlePointClick, isPointSelected, getPointOpacity, getPointSize, getPointStrokeWidth,} = useMultiSelection({ data, xScale, yScale, selectedPoints, onSelectionChange, enableBrush: true,});// Wire up SVG event handlers\u003Csvg onMouseDown={handleBrushStart} onMouseMove={handleBrushMove} onMouseUp={handleBrushEnd} onMouseLeave={handleBrushEnd}> {data.map((d, i) => ( \u003CCircle r={getPointSize(i)} opacity={getPointOpacity(i)} strokeWidth={getPointStrokeWidth(i)} onClick={e => handlePointClick(i, e)} /> ))}\u003C/svg>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Currently used by the \u003Cstrong>IChart\u003C/strong> component for \u003Ccode dir=\"auto\">enableBrushSelection\u003C/code> mode.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usechartcopy\">useChartCopy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usechartcopy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useChartCopy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Copy chart to clipboard or download as PNG/SVG with fixed, presentation-ready dimensions. All exports temporarily resize the chart container off-screen, wait for visx ResizeObserver re-render, then capture — producing identical output from dashboard cards and focused views.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/hooks/src/useChartCopy.ts\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"options-3\">Options\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#options-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Options”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> UseChartCopyOptions {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Return background color for the screenshot. Called at copy time. Defaults to #0f172a. */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getBackgroundColor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface UseChartCopyOptions { /** Return background color for the screenshot. Called at copy time. Defaults to #0f172a. */ getBackgroundColor?: () => string;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"returns-4\">Returns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#returns-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Returns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> UseChartCopyReturn {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">copyFeedback\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleCopyChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">containerId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">chartName\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Promise\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleDownloadPng\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">containerId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">chartName\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Promise\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleDownloadSvg\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">containerId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">chartName\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface UseChartCopyReturn { copyFeedback: string | null; handleCopyChart: (containerId: string, chartName: string) => Promise\u003Cvoid>; handleDownloadPng: (containerId: string, chartName: string) => Promise\u003Cvoid>; handleDownloadSvg: (containerId: string, chartName: string) => void;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"fixed-export-dimensions\">Fixed Export Dimensions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#fixed-export-dimensions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Fixed Export Dimensions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All charts export at fixed dimensions regardless of current container size:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Width\u003C/th>\u003Cth>Height\u003C/th>\u003Cth>Actual (x2)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ichart\u003C/code>\u003C/td>\u003Ctd>1200\u003C/td>\u003Ctd>540\u003C/td>\u003Ctd>2400 x 1080\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">boxplot\u003C/code>\u003C/td>\u003Ctd>1200\u003C/td>\u003Ctd>800\u003C/td>\u003Ctd>2400 x 1600\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">pareto\u003C/code>\u003C/td>\u003Ctd>1200\u003C/td>\u003Ctd>720\u003C/td>\u003Ctd>2400 x 1440\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">histogram\u003C/code>\u003C/td>\u003Ctd>800\u003C/td>\u003Ctd>600\u003C/td>\u003Ctd>1600 x 1200\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">probability\u003C/code>\u003C/td>\u003Ctd>800\u003C/td>\u003Ctd>700\u003C/td>\u003Ctd>1600 x 1400\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">stats\u003C/code>\u003C/td>\u003Ctd>1200\u003C/td>\u003Ctd>400\u003C/td>\u003Ctd>2400 x 800\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">dashboard\u003C/code>\u003C/td>\u003Ctd>1600\u003C/td>\u003Ctd>auto\u003C/td>\u003Ctd>3200 x auto\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Unknown chart names fall back to 1200 x 675. The \u003Ccode dir=\"auto\">EXPORT_SIZES\u003C/code> map is exported from \u003Ccode dir=\"auto\">@variscout/hooks\u003C/code> for reference.\u003C/p>\n\u003Cp>\u003Cstrong>Auto-height mode\u003C/strong>: When \u003Ccode dir=\"auto\">height\u003C/code> is \u003Ccode dir=\"auto\">0\u003C/code> in EXPORT_SIZES (used by \u003Ccode dir=\"auto\">dashboard\u003C/code>), \u003Ccode dir=\"auto\">withFixedSize\u003C/code> sets \u003Ccode dir=\"auto\">height: auto; overflow: visible\u003C/code> instead of a fixed pixel height. This captures the full scrollable content without clipping. At 1600px width, the \u003Ccode dir=\"auto\">lg:flex-row\u003C/code> breakpoint is active so charts render side-by-side.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-4\">Usage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useChartCopy } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/hooks\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">copyFeedback\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleCopyChart\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleDownloadPng\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleDownloadSvg\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartCopy\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getBackgroundColor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isDark\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> ? \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#0f172a\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> : \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ffffff\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Copy to clipboard (1-click)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleCopyChart\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ichart-card\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ichart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">copyFeedback \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ichart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Check\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">14\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Copy\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">14\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Download menu (via ChartDownloadMenu from @variscout/ui)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ChartDownloadMenu\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">containerId\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot-card\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">chartName\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onDownloadPng\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleDownloadPng\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onDownloadSvg\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleDownloadSvg\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useChartCopy } from '@variscout/hooks';const { copyFeedback, handleCopyChart, handleDownloadPng, handleDownloadSvg } = useChartCopy({ getBackgroundColor: () => isDark ? '#0f172a' : '#ffffff',});// Copy to clipboard (1-click)\u003Cbutton onClick={() => handleCopyChart('ichart-card', 'ichart')}> {copyFeedback === 'ichart' ? \u003CCheck size={14} /> : \u003CCopy size={14} />}\u003C/button>// Download menu (via ChartDownloadMenu from @variscout/ui)\u003CChartDownloadMenu containerId="boxplot-card" chartName="boxplot" onDownloadPng={handleDownloadPng} onDownloadSvg={handleDownloadSvg}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"dashboard-export\">Dashboard Export\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#dashboard-export\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dashboard Export”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The full dashboard can be exported as a single image for PowerPoint slides. Copy/Download buttons sit in the sticky nav bar:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Dashboard export uses the same hook — just pass 'dashboard' as chartName\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleCopyChart\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">dashboard-export-container\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">dashboard\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">copyFeedback \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">dashboard\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Check\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">14\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Copy\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">14\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleDownloadPng\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">dashboard-export-container\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">dashboard\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Download\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">14\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Dashboard export uses the same hook — just pass 'dashboard' as chartName\u003Cbutton onClick={() => handleCopyChart('dashboard-export-container', 'dashboard')}> {copyFeedback === 'dashboard' ? \u003CCheck size={14} /> : \u003CCopy size={14} />}\u003C/button>\u003Cbutton onClick={() => handleDownloadPng('dashboard-export-container', 'dashboard')}> \u003CDownload size={14} />\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>No SVG export for dashboard (multi-SVG composition doesn’t serialize cleanly).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"how-fixed-size-export-works\">How Fixed-Size Export Works\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#how-fixed-size-export-works\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How Fixed-Size Export Works”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Sets \u003Ccode dir=\"auto\">data-exporting=\"true\"\u003C/code> on the container (hides UI-only elements via CSS)\u003C/li>\n\u003Cli>Saves current \u003Ccode dir=\"auto\">style.cssText\u003C/code> and locks parent \u003Ccode dir=\"auto\">min-height\u003C/code>\u003C/li>\n\u003Cli>Moves container off-screen at fixed export dimensions (\u003Ccode dir=\"auto\">position: fixed; left: -9999px\u003C/code>)\u003C/li>\n\u003Cli>Waits for visx ResizeObserver + React re-render (~100ms: double rAF + setTimeout)\u003C/li>\n\u003Cli>Captures with \u003Ccode dir=\"auto\">html-to-image\u003C/code> at \u003Ccode dir=\"auto\">pixelRatio: 2\u003C/code>\u003C/li>\n\u003Cli>Restores original styles and parent lock (even on error)\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"import-pattern\">Import Pattern\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#import-pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Import Pattern”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useChartLayout,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useChartTooltip,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useSelectionState,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectionOpacity,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useChartTheme,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useMultiSelection } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/hooks/useMultiSelection\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useChartLayout, useChartTooltip, useSelectionState, selectionOpacity, useChartTheme,} from '@variscout/charts';import { useMultiSelection } from '@variscout/charts/hooks/useMultiSelection';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"complete-example\">Complete Example\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#complete-example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Complete Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useChartLayout,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useChartTooltip,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">useSelectionState,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ChartTooltip,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">MyChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FC\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Props\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">selectedKeys\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Layout\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartLayout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">chartType: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Tooltip\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tooltipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tooltipOpen\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tooltipLeft\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tooltipTop\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showTooltipAtPoint\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">hideTooltip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } =\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTooltip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DataPoint\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useSelectionState\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedKeys\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6;--1:#8844AE\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">style\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ position: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">relative\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">svg\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Group\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">left\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">left\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">top\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">top\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">d\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Bar\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">key\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">opacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getOpacity\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">key\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseMove\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">showTooltipAtPoint\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(e\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">d)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseLeave\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">hideTooltip\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Group\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">svg\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ChartTooltip\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">isOpen\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipOpen\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">left\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipLeft\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">top\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipTop\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fonts\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">d\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">label\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">d\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">value\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ChartTooltip\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useChartLayout, useChartTooltip, useSelectionState, ChartTooltip,} from '@variscout/charts';const MyChart: React.FC\u003CProps> = ({ parentWidth, parentHeight, data, selectedKeys }) => { // Layout const { fonts, margin, width, height } = useChartLayout({ parentWidth, parentHeight, chartType: 'boxplot', }); // Tooltip const { tooltipData, tooltipOpen, tooltipLeft, tooltipTop, showTooltipAtPoint, hideTooltip } = useChartTooltip\u003CDataPoint>(); // Selection const { getOpacity } = useSelectionState({ selectedKeys }); return ( \u003Cdiv style={{ position: 'relative' }}> \u003Csvg width={parentWidth} height={parentHeight}> \u003CGroup left={margin.left} top={margin.top}> {data.map(d => ( \u003CBar key={d.key} opacity={getOpacity(d.key)} onMouseMove={e => showTooltipAtPoint(e, d)} onMouseLeave={hideTooltip} /> ))} \u003C/Group> \u003C/svg> \u003CChartTooltip data={tooltipData} isOpen={tooltipOpen} left={tooltipLeft} top={tooltipTop} fonts={fonts} > {d => ( \u003Cdiv> {d.label}: {d.value} \u003C/div> )} \u003C/ChartTooltip> \u003C/div> );};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview and selection guide\u003C/li>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - \u003Ccode dir=\"auto\">useChartTheme\u003C/code> hook for theme-aware colors\u003C/li>\n\u003Cli>\u003Ca href=\"./responsive.md\">Responsive\u003C/a> - Underlying responsive utilities\u003C/li>\n\u003Cli>\u003Ca href=\"./shared-components.md\">Shared Components\u003C/a> - ChartTooltip component\u003C/li>\n\u003C/ul>", + { + "headings": 10066, + "localImagePaths": 10167, + "remoteImagePaths": 10168, + "frontmatter": 10169, + "imagePaths": 10170 + }, + [ + 10067, 10069, 10070, 10073, 10076, 10079, 10080, 10083, 10086, 10088, 10091, 10094, 10097, + 10100, 10103, 10105, 10107, 10110, 10112, 10115, 10116, 10119, 10121, 10124, 10127, 10130, + 10132, 10134, 10137, 10140, 10142, 10145, 10147, 10149, 10152, 10154, 10157, 10160, 10163, 10166 + ], + { "depth": 30, "slug": 10068, "text": 10056 }, + "chart-hooks", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 10071, "text": 10072 }, + "usechartlayout", + "useChartLayout", + { "depth": 79, "slug": 10074, "text": 10075 }, + "options", + "Options", + { "depth": 79, "slug": 10077, "text": 10078 }, + "returns", + "Returns", + { "depth": 79, "slug": 2008, "text": 2009 }, + { "depth": 79, "slug": 10081, "text": 10082 }, + "what-it-combines", + "What It Combines", + { "depth": 33, "slug": 10084, "text": 10085 }, + "usecharttooltip", + "useChartTooltip", + { "depth": 79, "slug": 10087, "text": 10078 }, + "returns-1", + { "depth": 79, "slug": 10089, "text": 10090 }, + "two-positioning-methods", + "Two Positioning Methods", + { "depth": 621, "slug": 10092, "text": 10093 }, + "showtooltipatpointevent-data", + "showTooltipAtPoint(event, data)", + { "depth": 621, "slug": 10095, "text": 10096 }, + "showtooltipatcoordsx-y-data", + "showTooltipAtCoords(x, y, data)", + { "depth": 79, "slug": 10098, "text": 10099 }, + "useslocalpoint-flag", + "usesLocalPoint Flag", + { "depth": 33, "slug": 10101, "text": 10102 }, + "useselectionstate", + "useSelectionState", + { "depth": 79, "slug": 10104, "text": 10075 }, + "options-1", + { "depth": 79, "slug": 10106, "text": 10078 }, + "returns-2", + { "depth": 79, "slug": 10108, "text": 10109 }, + "opacity-values", + "Opacity Values", + { "depth": 79, "slug": 10111, "text": 2009 }, + "usage-1", + { "depth": 79, "slug": 10113, "text": 10114 }, + "behavior", + "Behavior", + { "depth": 33, "slug": 8040, "text": 8041 }, + { "depth": 79, "slug": 10117, "text": 10118 }, + "interface", + "Interface", + { "depth": 79, "slug": 10120, "text": 2009 }, + "usage-2", + { "depth": 79, "slug": 10122, "text": 10123 }, + "observed-attributes", + "Observed Attributes", + { "depth": 79, "slug": 10125, "text": 10126 }, + "color-resolution", + "Color Resolution", + { "depth": 33, "slug": 10128, "text": 10129 }, + "usemultiselection", + "useMultiSelection", + { "depth": 79, "slug": 10131, "text": 10075 }, + "options-2", + { "depth": 79, "slug": 10133, "text": 10078 }, + "returns-3", + { "depth": 79, "slug": 10135, "text": 10136 }, + "interaction-modes", + "Interaction Modes", + { "depth": 79, "slug": 10138, "text": 10139 }, + "visual-styling", + "Visual Styling", + { "depth": 79, "slug": 10141, "text": 2009 }, + "usage-3", + { "depth": 33, "slug": 10143, "text": 10144 }, + "usechartcopy", + "useChartCopy", + { "depth": 79, "slug": 10146, "text": 10075 }, + "options-3", + { "depth": 79, "slug": 10148, "text": 10078 }, + "returns-4", + { "depth": 79, "slug": 10150, "text": 10151 }, + "fixed-export-dimensions", + "Fixed Export Dimensions", + { "depth": 79, "slug": 10153, "text": 2009 }, + "usage-4", + { "depth": 79, "slug": 10155, "text": 10156 }, + "dashboard-export", + "Dashboard Export", + { "depth": 79, "slug": 10158, "text": 10159 }, + "how-fixed-size-export-works", + "How Fixed-Size Export Works", + { "depth": 33, "slug": 10161, "text": 10162 }, + "import-pattern", + "Import Pattern", + { "depth": 33, "slug": 10164, "text": 10165 }, + "complete-example", + "Complete Example", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 10056 }, + [], + "06-design-system/charts/ichart", + { + "id": 10171, + "data": 10173, + "body": 10178, + "filePath": 10179, + "digest": 10180, + "rendered": 10181 + }, + { + "title": 10174, + "editUrl": 16, + "head": 10175, + "template": 18, + "sidebar": 10176, + "pagefind": 16, + "draft": 20 + }, + "Individual Control Charts (I-Chart)", + [], + { "hidden": 20, "attrs": 10177 }, + {}, + "# Individual Control Charts (I-Chart)\n\nTime-series control charts for individual measurements with control limits and specification limits.\n\n## Overview\n\nVariScout provides two I-Chart variants for different analysis contexts:\n\n| Component | Purpose | Context | Data Source |\n| --------------------- | ------------------------------ | ----------------- | ------------------- |\n| **IChart** | Time-series control monitoring | Standard Analysis | `IChartDataPoint[]` |\n| **PerformanceIChart** | Cpk scatter by channel | Performance Mode | `ChannelResult[]` |\n\n**Source:** `packages/charts/src/IChart.tsx`, `packages/charts/src/PerformanceIChart.tsx`\n\n---\n\n## Standard IChart\n\nDisplays individual measurements over time with control limits (UCL/LCL) and specification limits (USL/LSL). Follows Minitab conventions for control chart visualization.\n\n### Props Interface\n\n```typescript\ninterface IChartProps extends BaseChartProps {\n /** Data points with x (index), y (value), and optional stage */\n data: IChartDataPoint[];\n /** Statistical results (mean, stdDev, ucl, lcl) - used when not staged */\n stats: StatsResult | null;\n /** Staged statistics - when provided, renders per-stage control limits */\n stagedStats?: StagedStatsResult;\n /** Specification limits */\n specs: SpecLimits;\n /** Y-axis label */\n yAxisLabel?: string;\n /** Axis settings for manual scaling */\n axisSettings?: { min?: number; max?: number };\n /** Override Y-axis domain (for locking scale to full dataset) */\n yDomainOverride?: YAxisDomain;\n /** Callback when a point is clicked */\n onPointClick?: (index: number, originalIndex?: number) => void;\n /** Enable drag-to-select multi-point brushing */\n enableBrushSelection?: boolean;\n /** Currently selected point indices */\n selectedPoints?: Set\u003Cnumber>;\n /** Callback when selection changes */\n onSelectionChange?: (indices: Set\u003Cnumber>) => void;\n /** Sample size for branding bar */\n sampleSize?: number;\n /** Show Minitab-style labels next to limit lines (default: true) */\n showLimitLabels?: boolean;\n /** Callback when a spec limit label is clicked (for editing) */\n onSpecClick?: (spec: 'usl' | 'lsl' | 'target') => void;\n /** Callback when Y-axis area is clicked (for editing scale) */\n onYAxisClick?: (event?: React.MouseEvent) => void;\n}\n```\n\n### Data Structure\n\n```typescript\ninterface IChartDataPoint {\n /** X-axis value (typically index or time) */\n x: number;\n /** Y-axis value (measurement) */\n y: number;\n /** Original row index for drill-down navigation */\n originalIndex?: number;\n /** Stage identifier for staged I-Charts */\n stage?: string;\n}\n```\n\n### Display Modes\n\n#### Standard Mode (Single Stats)\n\nDefault view showing all data with unified control limits:\n\n```tsx\n\u003CIChart\n data={chartData}\n stats={statsResult}\n specs={{ usl: 105, lsl: 95, target: 100 }}\n yAxisLabel=\"Fill Weight (g)\"\n/>\n```\n\n#### Staged Mode\n\nWhen `stagedStats` is provided, the chart renders per-stage control limits with stage dividers:\n\n```tsx\n\u003CIChart data={chartData} stats={null} stagedStats={stagedStatsResult} specs={specs} />\n```\n\nFeatures in staged mode:\n\n- Vertical dashed stage dividers between stages\n- Stage labels above each section\n- Independent UCL/Mean/LCL per stage\n- Nelson Rule 2 detection computed per stage\n\n#### Visual Hierarchy (Staged Mode)\n\nStaged mode renders many reference lines (control limits per stage + spec limits + grid rows), which can create visual clutter. The chart applies a layered visual hierarchy so each element has a distinct weight:\n\n| Priority | Element | Style | Weight |\n| -------- | -------------- | --------------------------------------- | --------- |\n| 1 | Data points | Filled circles (r=4) | Dominant |\n| 2 | Stage means | Solid blue, 2px | Bold |\n| 3 | Stage UCL/LCL | Dashed (6,4), 0.8px, 60% opacity | Secondary |\n| 4 | Stage dividers | Dashed (4,4), 1px | Clear |\n| 5 | Spec limits | Dash-dot (8,3,2,3), 1.5px, 70% opacity | Reference |\n| 6 | Grid rows | 15% opacity (staged) / 40% (non-staged) | Minimal |\n\nThe dash-dot pattern on spec limits visually distinguishes the Voice of the Customer (spec limits) from the Voice of the Process (control limits), reinforcing the Two Voices model.\n\n#### Y-Axis Lock Mode\n\nLocks Y-axis scale to a fixed range (useful during drill-down to maintain reference):\n\n```tsx\n\u003CIChart\n data={filteredData}\n stats={filteredStats}\n specs={specs}\n yDomainOverride={{ min: 90, max: 110 }}\n/>\n```\n\n---\n\n## PerformanceIChart\n\nI-Chart for capability metrics (Cpk or Cp) across channels. Uses statistical control limits calculated from the capability distribution rather than health-based coloring.\n\n### Props Interface\n\n```typescript\ninterface PerformanceIChartProps extends BaseChartProps {\n /** Channel results with Cpk values */\n channels: ChannelResult[];\n /** Currently selected measure/channel */\n selectedMeasure?: string | null;\n /** Callback when a channel point is clicked */\n onChannelClick?: (channelId: string) => void;\n /** Which capability metric to display: 'cpk' (default) or 'cp' */\n capabilityMetric?: 'cp' | 'cpk';\n /** User-defined Cpk/Cp target line (default: 1.33) */\n cpkTarget?: number;\n}\n```\n\n### Features\n\n- **X-axis:** Channel index (1, 2, 3, ... n)\n- **Y-axis:** Cpk or Cp value\n- **Control limits:** UCL/LCL calculated from capability distribution (mean ± 3σ)\n- **Mean line:** Average capability across all channels (solid blue)\n- **Target line:** User-defined reference (default: 1.33, dashed green)\n- **Nelson Rule 2 detection:** Flags 9+ consecutive points on same side of mean\n\n### Display Behavior\n\n| State | Display |\n| ---------------- | ---------------------------------------------------- |\n| No selection | All channels as scatter points by Cpk/Cp |\n| Channel selected | Selected channel highlighted, others dimmed |\n| Empty channels | Placeholder: \"No channel performance data available\" |\n\n### Control Limit Lines\n\nThe chart displays statistical control limits calculated from the Cpk/Cp distribution:\n\n| Line | Calculation | Style | Meaning |\n| ------ | ----------- | ------------ | -------------------------------- |\n| UCL | mean + 3σ | Dashed gray | Upper Control Limit |\n| Mean | x̄ | Solid blue | Average capability |\n| LCL | mean - 3σ | Dashed gray | Lower Control Limit (min: 0) |\n| Target | User input | Dashed green | Reference target (default: 1.33) |\n\n### Control-Based Coloring\n\nPoint color reflects statistical control status (I-Chart style):\n\n| Status | Color | Condition |\n| -------------- | ------------------------- | ----------------------------------------- |\n| In-control | Blue (`chartColors.mean`) | Within UCL/LCL, no rule violations |\n| Out-of-control | Red (`chartColors.fail`) | Beyond UCL/LCL or Nelson Rule 2 violation |\n\n**Note:** This differs from the other Performance charts (Boxplot, Pareto, Capability) which use health-based 4-tier coloring.\n\n### Control Limit Calculation\n\nControl limits are calculated using functions from `@variscout/core`:\n\n```typescript\nimport { calculateCapabilityControlLimits, getCapabilityControlStatus } from '@variscout/core';\n\n// Calculate limits from Cpk/Cp distribution\nconst limits = calculateCapabilityControlLimits(channels, 'cpk');\n// Returns: { mean, stdDev, ucl, lcl, n }\n\n// Determine control status for each channel\nconst statusMap = getCapabilityControlStatus(channels, limits, 'cpk');\n// Returns: Map\u003CchannelId, { inControl, nelsonRule2Violation }>\n```\n\n### Example\n\n```tsx\nimport PerformanceIChart from '@variscout/charts/PerformanceIChart';\n\n\u003CPerformanceIChart\n channels={channelResults}\n selectedMeasure={selectedId}\n onChannelClick={handleChannelSelect}\n capabilityMetric=\"cpk\"\n cpkTarget={1.33}\n/>;\n```\n\n---\n\n## Statistical Elements\n\n| Element | Standard IChart | PerformanceIChart |\n| ------------------ | ---------------------------------------- | ----------------------------------------- |\n| **Data points** | Circles on time series | Circles by channel index |\n| **Data line** | Connecting line (dimmed) | Not shown |\n| **UCL/LCL** | Subtle dashed (0.8px, 60% opacity) | Dashed gray (mean ± 3σ of Cpk/Cp) |\n| **Mean line** | Bold solid blue (2px) | Solid blue (mean Cpk/Cp across channels) |\n| **Target line** | Dashed green line | Dashed green (user-defined, default 1.33) |\n| **Spec limits** | Dash-dot orange (1.5px, 70% opacity) | Not shown |\n| **Stage dividers** | Vertical dashed lines (if staged) | Not applicable |\n| **Grid** | Subtle rows (15% staged, 40% non-staged) | Horizontal rows |\n\n---\n\n## Point Coloring (Minitab 2-Color Scheme)\n\nStandard IChart uses a simple two-color scheme following Minitab conventions:\n\n| Condition | Color | Meaning |\n| ----------------------- | ----- | ---------------- |\n| Above USL or below LSL | Red | Out of spec |\n| Above UCL or below LCL | Red | Out of control |\n| Nelson Rule 2 violation | Red | Pattern detected |\n| All checks pass | Blue | In control |\n\n**Nelson Rule 2:** 9 or more consecutive points on the same side of the mean line.\n\n---\n\n## Data Flow\n\n### Standard IChart\n\n```\nDataContext (PWA/Azure)\n |\nDashboard.tsx\n | calculateStats() for control limits\nIChart (responsive wrapper)\n |\nIChartBase (renders SVG)\n | getStageBoundaries() if staged\n | getNelsonRule2ViolationPoints()\n```\n\n### PerformanceIChart\n\n```\nDataContext (PWA/Azure)\n | analyzePerformanceData()\nPerformanceDashboard.tsx\n | channels: ChannelResult[]\nPerformanceIChart (responsive wrapper)\n |\nPerformanceIChartBase (renders SVG)\n```\n\n---\n\n## Interactions\n\n### Click Behavior\n\n```tsx\n// Standard IChart - point selection\nonPointClick={(index, originalIndex) => {\n // Navigate to specific data row\n scrollToRow(originalIndex ?? index);\n}}\n\n// Clickable spec labels (for editing)\nonSpecClick={(spec) => {\n openSpecEditor(spec); // 'usl' | 'lsl' | 'target'\n}}\n\n// Clickable Y-axis (for editing scale)\nonYAxisClick={() => {\n openAxisEditor();\n}}\n\n// PerformanceIChart - channel selection\nonChannelClick={(channelId) => {\n setSelectedMeasure(prev => prev === channelId ? null : channelId);\n}}\n```\n\n### Hover Tooltip\n\nStandard IChart tooltip shows:\n\n- Observation number (#1, #2, etc.)\n- Stage name (if staged)\n- Value\n\nPerformanceIChart tooltip shows:\n\n- Channel label\n- Cp value\n- Cpk value\n- Sample size (n)\n- Mean\n- Control status (colored: \"In control\", \"Out of control\", or \"Nelson Rule 2 violation\")\n\n---\n\n## I-Chart Annotations\n\nThe I-Chart supports **free-floating text annotations** created via right-click on the chart area. Unlike Boxplot/Pareto annotations (which anchor to categories), I-Chart annotations use percentage-based positioning within the chart area.\n\n### Annotation Props (App Wrapper Level)\n\nThe annotation system is wired at the app wrapper level (PWA and Azure IChart wrappers), not in `IChartBase` directly:\n\n```typescript\ninterface IChartWrapperProps {\n // ... standard props ...\n\n /** Free-floating text annotations positioned by percentage */\n ichartAnnotations?: ChartAnnotation[];\n /** Callback to create a new annotation at a position (0.0-1.0) */\n onCreateAnnotation?: (anchorX: number, anchorY: number) => void;\n /** Callback when annotations are edited/moved/deleted */\n onAnnotationsChange?: (annotations: ChartAnnotation[]) => void;\n}\n```\n\n### How It Works\n\n1. User right-clicks anywhere on the I-Chart area\n2. The wrapper converts click coordinates to percentage-based position (0.0-1.0) using `getResponsiveMargins('ichart')`\n3. A new `ChartAnnotation` is created with `anchorX`/`anchorY` fields\n4. `ChartAnnotationLayer` (from `@variscout/ui`) renders draggable text notes as an HTML overlay\n\n### Position System\n\n| Field | Type | Description |\n| ---------------- | ------ | ---------------------------------------------------------- |\n| `anchorX` | number | Horizontal position (0.0 = left, 1.0 = right) |\n| `anchorY` | number | Vertical position (0.0 = top, 1.0 = bottom) |\n| `anchorCategory` | string | Self-referencing ID (I-Chart uses the annotation's own ID) |\n\nPercentage-based positions are data-independent, so annotations remain valid when data changes.\n\n### Clearing Annotations\n\nA clear button appears in the I-Chart card header when `ichartAnnotations.length > 0`. The `useAnnotations` hook from `@variscout/hooks` provides `clearAnnotations('ichart')` for this.\n\n---\n\n## Cross-App Usage\n\n### PWA and Azure\n\nUse the responsive wrapper (auto-sizing with `withParentSize`):\n\n```tsx\nimport IChart from '@variscout/charts/IChart';\nimport PerformanceIChart from '@variscout/charts/PerformanceIChart';\n\n// Standard IChart\n\u003Cdiv className=\"h-[400px]\">\n \u003CIChart\n data={chartData}\n stats={stats}\n specs={specs}\n onPointClick={handlePointClick}\n />\n\u003C/div>\n\n// Performance IChart\n\u003Cdiv className=\"h-[300px]\">\n \u003CPerformanceIChart\n channels={channels}\n onChannelClick={handleClick}\n />\n\u003C/div>\n```\n\n---\n\n## Colors and Theming\n\n### Point Colors\n\n| Variant | Condition | Fill Color |\n| --------------------- | ---------------------------------- | ------------------------- |\n| Standard (in-ctrl) | All checks pass | `chartColors.mean` (blue) |\n| Standard (violation) | Any violation | `chartColors.fail` (red) |\n| Performance (in-ctrl) | Within UCL/LCL, no rule violations | `chartColors.mean` (blue) |\n| Performance (out) | Beyond UCL/LCL or Nelson Rule 2 | `chartColors.fail` (red) |\n\n### Theme-Aware Colors\n\nPerformanceIChart uses `useChartTheme()` for automatic light/dark adaptation:\n\n```typescript\nconst { chrome } = useChartTheme();\n\n// Chrome colors adapt to theme:\n// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\n```\n\nStandard IChart uses hardcoded dark theme colors from `chromeColors`.\n\n### Reference Line Colors\n\n```typescript\n// Control limits (staged: subtler; non-staged: standard)\nstroke={chartColors.control} // cyan-500\nstrokeWidth={0.8} // staged (1 for non-staged)\nstrokeDasharray=\"6,4\" // staged (\"4,4\" for non-staged)\nstrokeOpacity={0.6} // staged (1 for non-staged)\n\n// Mean line (bold anchor)\nstroke={chartColors.mean} // blue-500 solid\nstrokeWidth={2} // staged (1.5 for non-staged)\n\n// Spec limits (USL/LSL) - dash-dot pattern\nstroke={chartColors.spec} // red-500\nstrokeWidth={1.5}\nstrokeDasharray=\"8,3,2,3\" // dash-dot (distinct from control dashes)\nstrokeOpacity={0.7}\n\n// Target line\nstroke={chartColors.target} // green-500 dotted\nstrokeWidth={1}\nstrokeDasharray=\"2,2\"\n```\n\n---\n\n## Exports\n\n```typescript\n// Responsive wrappers (auto-sizing)\nimport IChart from '@variscout/charts/IChart';\nimport PerformanceIChart from '@variscout/charts/PerformanceIChart';\n\n// Base components (manual sizing)\nimport { IChartBase } from '@variscout/charts/IChart';\nimport { PerformanceIChartBase } from '@variscout/charts/PerformanceIChart';\n\n// Types\nimport type { IChartProps, IChartDataPoint, PerformanceIChartProps } from '@variscout/charts';\n```\n\n---\n\n## See Also\n\n- [Overview](./overview.md) - Chart design system overview and selection guide\n- [Colors](./colors.md) - Chart color constants and health classification\n- [Responsive](./responsive.md) - Breakpoints and scaling utilities\n- [Hooks](./hooks.md) - useChartLayout, useChartTooltip\n- [Performance Mode](./performance-mode.md) - Full Performance Mode documentation\n- [Boxplot](./boxplot.md) - Distribution comparison charts", + "src/content/docs/06-design-system/charts/ichart.md", + "d6aa88194879cb92", + { "html": 10182, "metadata": 10183 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"individual-control-charts-i-chart\">Individual Control Charts (I-Chart)\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#individual-control-charts-i-chart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Individual Control Charts (I-Chart)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Time-series control charts for individual measurements with control limits and specification limits.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout provides two I-Chart variants for different analysis contexts:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Context\u003C/th>\u003Cth>Data Source\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>IChart\u003C/strong>\u003C/td>\u003Ctd>Time-series control monitoring\u003C/td>\u003Ctd>Standard Analysis\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">IChartDataPoint[]\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>PerformanceIChart\u003C/strong>\u003C/td>\u003Ctd>Cpk scatter by channel\u003C/td>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ChannelResult[]\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/IChart.tsx\u003C/code>, \u003Ccode dir=\"auto\">packages/charts/src/PerformanceIChart.tsx\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"standard-ichart\">Standard IChart\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#standard-ichart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard IChart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Displays individual measurements over time with control limits (UCL/LCL) and specification limits (USL/LSL). Follows Minitab conventions for control chart visualization.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-interface\">Props Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> IChartProps \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extends\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">BaseChartProps\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Data points with x (index), y (value), and optional stage */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">IChartDataPoint\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Statistical results (mean, stdDev, ucl, lcl) - used when not staged */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">StatsResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Staged statistics - when provided, renders per-stage control limits */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stagedStats\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">StagedStatsResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Specification limits */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Y-axis label */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yAxisLabel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Axis settings for manual scaling */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">axisSettings\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { min\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; max\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> };\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Override Y-axis domain (for locking scale to full dataset) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yDomainOverride\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">YAxisDomain\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback when a point is clicked */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onPointClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">originalIndex\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Enable drag-to-select multi-point brushing */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">enableBrushSelection\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Currently selected point indices */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedPoints\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback when selection changes */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onSelectionChange\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">indices\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Set\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Sample size for branding bar */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">sampleSize\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Show Minitab-style labels next to limit lines (default: true) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showLimitLabels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback when a spec limit label is clicked (for editing) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onSpecClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">spec\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">usl\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">lsl\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">target\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback when Y-axis area is clicked (for editing scale) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onYAxisClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">event\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#FFCB8B\">MouseEvent\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface IChartProps extends BaseChartProps { /** Data points with x (index), y (value), and optional stage */ data: IChartDataPoint[]; /** Statistical results (mean, stdDev, ucl, lcl) - used when not staged */ stats: StatsResult | null; /** Staged statistics - when provided, renders per-stage control limits */ stagedStats?: StagedStatsResult; /** Specification limits */ specs: SpecLimits; /** Y-axis label */ yAxisLabel?: string; /** Axis settings for manual scaling */ axisSettings?: { min?: number; max?: number }; /** Override Y-axis domain (for locking scale to full dataset) */ yDomainOverride?: YAxisDomain; /** Callback when a point is clicked */ onPointClick?: (index: number, originalIndex?: number) => void; /** Enable drag-to-select multi-point brushing */ enableBrushSelection?: boolean; /** Currently selected point indices */ selectedPoints?: Set\u003Cnumber>; /** Callback when selection changes */ onSelectionChange?: (indices: Set\u003Cnumber>) => void; /** Sample size for branding bar */ sampleSize?: number; /** Show Minitab-style labels next to limit lines (default: true) */ showLimitLabels?: boolean; /** Callback when a spec limit label is clicked (for editing) */ onSpecClick?: (spec: 'usl' | 'lsl' | 'target') => void; /** Callback when Y-axis area is clicked (for editing scale) */ onYAxisClick?: (event?: React.MouseEvent) => void;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-structure\">Data Structure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> IChartDataPoint {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** X-axis value (typically index or time) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">x\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Y-axis value (measurement) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">y\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Original row index for drill-down navigation */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">originalIndex\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Stage identifier for staged I-Charts */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stage\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface IChartDataPoint { /** X-axis value (typically index or time) */ x: number; /** Y-axis value (measurement) */ y: number; /** Original row index for drill-down navigation */ originalIndex?: number; /** Stage identifier for staged I-Charts */ stage?: string;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-modes\">Display Modes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-modes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Modes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"standard-mode-single-stats\">Standard Mode (Single Stats)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#standard-mode-single-stats\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Mode (Single Stats)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Default view showing all data with unified control limits:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">statsResult\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">105\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">95\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, target: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">yAxisLabel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Fill Weight (g)\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CIChart data={chartData} stats={statsResult} specs={{ usl: 105, lsl: 95, target: 100 }} yAxisLabel="Fill Weight (g)"/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"staged-mode\">Staged Mode\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#staged-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Staged Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When \u003Ccode dir=\"auto\">stagedStats\u003C/code> is provided, the chart renders per-stage control limits with stage dividers:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stagedStats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stagedStatsResult\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CIChart data={chartData} stats={null} stagedStats={stagedStatsResult} specs={specs} />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Features in staged mode:\u003C/p>\n\u003Cul>\n\u003Cli>Vertical dashed stage dividers between stages\u003C/li>\n\u003Cli>Stage labels above each section\u003C/li>\n\u003Cli>Independent UCL/Mean/LCL per stage\u003C/li>\n\u003Cli>Nelson Rule 2 detection computed per stage\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"visual-hierarchy-staged-mode\">Visual Hierarchy (Staged Mode)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#visual-hierarchy-staged-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Hierarchy (Staged Mode)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Staged mode renders many reference lines (control limits per stage + spec limits + grid rows), which can create visual clutter. The chart applies a layered visual hierarchy so each element has a distinct weight:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Priority\u003C/th>\u003Cth>Element\u003C/th>\u003Cth>Style\u003C/th>\u003Cth>Weight\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Data points\u003C/td>\u003Ctd>Filled circles (r=4)\u003C/td>\u003Ctd>Dominant\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Stage means\u003C/td>\u003Ctd>Solid blue, 2px\u003C/td>\u003Ctd>Bold\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Stage UCL/LCL\u003C/td>\u003Ctd>Dashed (6,4), 0.8px, 60% opacity\u003C/td>\u003Ctd>Secondary\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Stage dividers\u003C/td>\u003Ctd>Dashed (4,4), 1px\u003C/td>\u003Ctd>Clear\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Spec limits\u003C/td>\u003Ctd>Dash-dot (8,3,2,3), 1.5px, 70% opacity\u003C/td>\u003Ctd>Reference\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Grid rows\u003C/td>\u003Ctd>15% opacity (staged) / 40% (non-staged)\u003C/td>\u003Ctd>Minimal\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The dash-dot pattern on spec limits visually distinguishes the Voice of the Customer (spec limits) from the Voice of the Process (control limits), reinforcing the Two Voices model.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"y-axis-lock-mode\">Y-Axis Lock Mode\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#y-axis-lock-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Y-Axis Lock Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Locks Y-axis scale to a fixed range (useful during drill-down to maintain reference):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredStats\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">yDomainOverride\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ min: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">90\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, max: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">110\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CIChart data={filteredData} stats={filteredStats} specs={specs} yDomainOverride={{ min: 90, max: 110 }}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performanceichart\">PerformanceIChart\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performanceichart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformanceIChart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>I-Chart for capability metrics (Cpk or Cp) across channels. Uses statistical control limits calculated from the capability distribution rather than health-based coloring.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-interface-1\">Props Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-interface-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceIChartProps \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extends\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">BaseChartProps\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Channel results with Cpk values */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChannelResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Currently selected measure/channel */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback when a channel point is clicked */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">channelId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Which capability metric to display: 'cpk' (default) or 'cp' */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">capabilityMetric\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cp\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** User-defined Cpk/Cp target line (default: 1.33) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cpkTarget\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface PerformanceIChartProps extends BaseChartProps { /** Channel results with Cpk values */ channels: ChannelResult[]; /** Currently selected measure/channel */ selectedMeasure?: string | null; /** Callback when a channel point is clicked */ onChannelClick?: (channelId: string) => void; /** Which capability metric to display: 'cpk' (default) or 'cp' */ capabilityMetric?: 'cp' | 'cpk'; /** User-defined Cpk/Cp target line (default: 1.33) */ cpkTarget?: number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"features\">Features\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>X-axis:\u003C/strong> Channel index (1, 2, 3, … n)\u003C/li>\n\u003Cli>\u003Cstrong>Y-axis:\u003C/strong> Cpk or Cp value\u003C/li>\n\u003Cli>\u003Cstrong>Control limits:\u003C/strong> UCL/LCL calculated from capability distribution (mean ± 3σ)\u003C/li>\n\u003Cli>\u003Cstrong>Mean line:\u003C/strong> Average capability across all channels (solid blue)\u003C/li>\n\u003Cli>\u003Cstrong>Target line:\u003C/strong> User-defined reference (default: 1.33, dashed green)\u003C/li>\n\u003Cli>\u003Cstrong>Nelson Rule 2 detection:\u003C/strong> Flags 9+ consecutive points on same side of mean\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-behavior\">Display Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Behavior”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>State\u003C/th>\u003Cth>Display\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No selection\u003C/td>\u003Ctd>All channels as scatter points by Cpk/Cp\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Channel selected\u003C/td>\u003Ctd>Selected channel highlighted, others dimmed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Empty channels\u003C/td>\u003Ctd>Placeholder: “No channel performance data available”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"control-limit-lines\">Control Limit Lines\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#control-limit-lines\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Control Limit Lines”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The chart displays statistical control limits calculated from the Cpk/Cp distribution:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Line\u003C/th>\u003Cth>Calculation\u003C/th>\u003Cth>Style\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>UCL\u003C/td>\u003Ctd>mean + 3σ\u003C/td>\u003Ctd>Dashed gray\u003C/td>\u003Ctd>Upper Control Limit\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mean\u003C/td>\u003Ctd>x̄\u003C/td>\u003Ctd>Solid blue\u003C/td>\u003Ctd>Average capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LCL\u003C/td>\u003Ctd>mean - 3σ\u003C/td>\u003Ctd>Dashed gray\u003C/td>\u003Ctd>Lower Control Limit (min: 0)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Target\u003C/td>\u003Ctd>User input\u003C/td>\u003Ctd>Dashed green\u003C/td>\u003Ctd>Reference target (default: 1.33)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"control-based-coloring\">Control-Based Coloring\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#control-based-coloring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Control-Based Coloring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Point color reflects statistical control status (I-Chart style):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Status\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Condition\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>In-control\u003C/td>\u003Ctd>Blue (\u003Ccode dir=\"auto\">chartColors.mean\u003C/code>)\u003C/td>\u003Ctd>Within UCL/LCL, no rule violations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Out-of-control\u003C/td>\u003Ctd>Red (\u003Ccode dir=\"auto\">chartColors.fail\u003C/code>)\u003C/td>\u003Ctd>Beyond UCL/LCL or Nelson Rule 2 violation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Note:\u003C/strong> This differs from the other Performance charts (Boxplot, Pareto, Capability) which use health-based 4-tier coloring.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"control-limit-calculation\">Control Limit Calculation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#control-limit-calculation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Control Limit Calculation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Control limits are calculated using functions from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateCapabilityControlLimits, getCapabilityControlStatus } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Calculate limits from Cpk/Cp distribution\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">limits\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateCapabilityControlLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns: { mean, stdDev, ucl, lcl, n }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Determine control status for each channel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">statusMap\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getCapabilityControlStatus\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">limits\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns: Map<channelId, { inControl, nelsonRule2Violation }>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { calculateCapabilityControlLimits, getCapabilityControlStatus } from '@variscout/core';// Calculate limits from Cpk/Cp distributionconst limits = calculateCapabilityControlLimits(channels, 'cpk');// Returns: { mean, stdDev, ucl, lcl, n }// Determine control status for each channelconst statusMap = getCapabilityControlStatus(channels, limits, 'cpk');// Returns: Map\u003CchannelId, { inControl, nelsonRule2Violation }>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceIChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceIChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceIChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channelResults\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedId\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleChannelSelect\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">capabilityMetric\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">cpkTarget\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.33\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import PerformanceIChart from '@variscout/charts/PerformanceIChart';\u003CPerformanceIChart channels={channelResults} selectedMeasure={selectedId} onChannelClick={handleChannelSelect} capabilityMetric="cpk" cpkTarget={1.33}/>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"statistical-elements\">Statistical Elements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#statistical-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Statistical Elements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Standard IChart\u003C/th>\u003Cth>PerformanceIChart\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Data points\u003C/strong>\u003C/td>\u003Ctd>Circles on time series\u003C/td>\u003Ctd>Circles by channel index\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Data line\u003C/strong>\u003C/td>\u003Ctd>Connecting line (dimmed)\u003C/td>\u003Ctd>Not shown\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>UCL/LCL\u003C/strong>\u003C/td>\u003Ctd>Subtle dashed (0.8px, 60% opacity)\u003C/td>\u003Ctd>Dashed gray (mean ± 3σ of Cpk/Cp)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mean line\u003C/strong>\u003C/td>\u003Ctd>Bold solid blue (2px)\u003C/td>\u003Ctd>Solid blue (mean Cpk/Cp across channels)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Target line\u003C/strong>\u003C/td>\u003Ctd>Dashed green line\u003C/td>\u003Ctd>Dashed green (user-defined, default 1.33)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Spec limits\u003C/strong>\u003C/td>\u003Ctd>Dash-dot orange (1.5px, 70% opacity)\u003C/td>\u003Ctd>Not shown\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Stage dividers\u003C/strong>\u003C/td>\u003Ctd>Vertical dashed lines (if staged)\u003C/td>\u003Ctd>Not applicable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Grid\u003C/strong>\u003C/td>\u003Ctd>Subtle rows (15% staged, 40% non-staged)\u003C/td>\u003Ctd>Horizontal rows\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"point-coloring-minitab-2-color-scheme\">Point Coloring (Minitab 2-Color Scheme)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#point-coloring-minitab-2-color-scheme\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Point Coloring (Minitab 2-Color Scheme)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standard IChart uses a simple two-color scheme following Minitab conventions:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Condition\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Above USL or below LSL\u003C/td>\u003Ctd>Red\u003C/td>\u003Ctd>Out of spec\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Above UCL or below LCL\u003C/td>\u003Ctd>Red\u003C/td>\u003Ctd>Out of control\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Nelson Rule 2 violation\u003C/td>\u003Ctd>Red\u003C/td>\u003Ctd>Pattern detected\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>All checks pass\u003C/td>\u003Ctd>Blue\u003C/td>\u003Ctd>In control\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Nelson Rule 2:\u003C/strong> 9 or more consecutive points on the same side of the mean line.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-flow\">Data Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-ichart-1\">Standard IChart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-ichart-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard IChart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext (PWA/Azure)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Dashboard.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| calculateStats() for control limits\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">IChart (responsive wrapper)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">IChartBase (renders SVG)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| getStageBoundaries() if staged\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| getNelsonRule2ViolationPoints()\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DataContext (PWA/Azure) |Dashboard.tsx | calculateStats() for control limitsIChart (responsive wrapper) |IChartBase (renders SVG) | getStageBoundaries() if staged | getNelsonRule2ViolationPoints()\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performanceichart-1\">PerformanceIChart\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performanceichart-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformanceIChart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext (PWA/Azure)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| analyzePerformanceData()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceDashboard.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| channels: ChannelResult[]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceIChart (responsive wrapper)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceIChartBase (renders SVG)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DataContext (PWA/Azure) | analyzePerformanceData()PerformanceDashboard.tsx | channels: ChannelResult[]PerformanceIChart (responsive wrapper) |PerformanceIChartBase (renders SVG)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interactions\">Interactions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interactions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interactions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"click-behavior\">Click Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#click-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Click Behavior”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard IChart - point selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onPointClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{(index, originalIndex) => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Navigate to specific data row\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">scrollToRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(originalIndex \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">??\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> index);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Clickable spec labels (for editing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onSpecClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{(spec) => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">openSpecEditor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(spec); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 'usl' | 'lsl' | 'target'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Clickable Y-axis (for editing scale)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onYAxisClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{() => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">openAxisEditor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PerformanceIChart - channel selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{(channelId) => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedMeasure\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">prev\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> prev \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> channelId \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> channelId);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Standard IChart - point selectiononPointClick={(index, originalIndex) => { // Navigate to specific data row scrollToRow(originalIndex ?? index);}}// Clickable spec labels (for editing)onSpecClick={(spec) => { openSpecEditor(spec); // 'usl' | 'lsl' | 'target'}}// Clickable Y-axis (for editing scale)onYAxisClick={() => { openAxisEditor();}}// PerformanceIChart - channel selectiononChannelClick={(channelId) => { setSelectedMeasure(prev => prev === channelId ? null : channelId);}}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"hover-tooltip\">Hover Tooltip\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#hover-tooltip\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hover Tooltip”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standard IChart tooltip shows:\u003C/p>\n\u003Cul>\n\u003Cli>Observation number (#1, #2, etc.)\u003C/li>\n\u003Cli>Stage name (if staged)\u003C/li>\n\u003Cli>Value\u003C/li>\n\u003C/ul>\n\u003Cp>PerformanceIChart tooltip shows:\u003C/p>\n\u003Cul>\n\u003Cli>Channel label\u003C/li>\n\u003Cli>Cp value\u003C/li>\n\u003Cli>Cpk value\u003C/li>\n\u003Cli>Sample size (n)\u003C/li>\n\u003Cli>Mean\u003C/li>\n\u003Cli>Control status (colored: “In control”, “Out of control”, or “Nelson Rule 2 violation”)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"i-chart-annotations\">I-Chart Annotations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#i-chart-annotations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “I-Chart Annotations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The I-Chart supports \u003Cstrong>free-floating text annotations\u003C/strong> created via right-click on the chart area. Unlike Boxplot/Pareto annotations (which anchor to categories), I-Chart annotations use percentage-based positioning within the chart area.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"annotation-props-app-wrapper-level\">Annotation Props (App Wrapper Level)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#annotation-props-app-wrapper-level\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Annotation Props (App Wrapper Level)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The annotation system is wired at the app wrapper level (PWA and Azure IChart wrappers), not in \u003Ccode dir=\"auto\">IChartBase\u003C/code> directly:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> IChartWrapperProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ... standard props ...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Free-floating text annotations positioned by percentage */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ichartAnnotations\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartAnnotation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback to create a new annotation at a position (0.0-1.0) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onCreateAnnotation\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">anchorX\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">anchorY\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback when annotations are edited/moved/deleted */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onAnnotationsChange\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">annotations\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartAnnotation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface IChartWrapperProps { // ... standard props ... /** Free-floating text annotations positioned by percentage */ ichartAnnotations?: ChartAnnotation[]; /** Callback to create a new annotation at a position (0.0-1.0) */ onCreateAnnotation?: (anchorX: number, anchorY: number) => void; /** Callback when annotations are edited/moved/deleted */ onAnnotationsChange?: (annotations: ChartAnnotation[]) => void;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"how-it-works\">How It Works\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#how-it-works\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How It Works”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>User right-clicks anywhere on the I-Chart area\u003C/li>\n\u003Cli>The wrapper converts click coordinates to percentage-based position (0.0-1.0) using \u003Ccode dir=\"auto\">getResponsiveMargins('ichart')\u003C/code>\u003C/li>\n\u003Cli>A new \u003Ccode dir=\"auto\">ChartAnnotation\u003C/code> is created with \u003Ccode dir=\"auto\">anchorX\u003C/code>/\u003Ccode dir=\"auto\">anchorY\u003C/code> fields\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">ChartAnnotationLayer\u003C/code> (from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>) renders draggable text notes as an HTML overlay\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"position-system\">Position System\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#position-system\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Position System”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Field\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">anchorX\u003C/code>\u003C/td>\u003Ctd>number\u003C/td>\u003Ctd>Horizontal position (0.0 = left, 1.0 = right)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">anchorY\u003C/code>\u003C/td>\u003Ctd>number\u003C/td>\u003Ctd>Vertical position (0.0 = top, 1.0 = bottom)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">anchorCategory\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Self-referencing ID (I-Chart uses the annotation’s own ID)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Percentage-based positions are data-independent, so annotations remain valid when data changes.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"clearing-annotations\">Clearing Annotations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#clearing-annotations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Clearing Annotations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A clear button appears in the I-Chart card header when \u003Ccode dir=\"auto\">ichartAnnotations.length > 0\u003C/code>. The \u003Ccode dir=\"auto\">useAnnotations\u003C/code> hook from \u003Ccode dir=\"auto\">@variscout/hooks\u003C/code> provides \u003Ccode dir=\"auto\">clearAnnotations('ichart')\u003C/code> for this.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-app-usage\">Cross-App Usage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-app-usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-App Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-and-azure\">PWA and Azure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-and-azure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA and Azure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use the responsive wrapper (auto-sizing with \u003Ccode dir=\"auto\">withParentSize\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> IChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/IChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceIChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceIChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[400px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onPointClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handlePointClick\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Performance IChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[300px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceIChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleClick\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import IChart from '@variscout/charts/IChart';import PerformanceIChart from '@variscout/charts/PerformanceIChart';// Standard IChart\u003Cdiv className="h-[400px]"> \u003CIChart data={chartData} stats={stats} specs={specs} onPointClick={handlePointClick} />\u003C/div>// Performance IChart\u003Cdiv className="h-[300px]"> \u003CPerformanceIChart channels={channels} onChannelClick={handleClick} />\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"colors-and-theming\">Colors and Theming\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#colors-and-theming\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Colors and Theming”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"point-colors\">Point Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#point-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Point Colors”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variant\u003C/th>\u003Cth>Condition\u003C/th>\u003Cth>Fill Color\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Standard (in-ctrl)\u003C/td>\u003Ctd>All checks pass\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.mean\u003C/code> (blue)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Standard (violation)\u003C/td>\u003Ctd>Any violation\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.fail\u003C/code> (red)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance (in-ctrl)\u003C/td>\u003Ctd>Within UCL/LCL, no rule violations\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.mean\u003C/code> (blue)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance (out)\u003C/td>\u003Ctd>Beyond UCL/LCL or Nelson Rule 2\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.fail\u003C/code> (red)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"theme-aware-colors\">Theme-Aware Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#theme-aware-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theme-Aware Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>PerformanceIChart uses \u003Ccode dir=\"auto\">useChartTheme()\u003C/code> for automatic light/dark adaptation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chrome colors adapt to theme:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { chrome } = useChartTheme();// Chrome colors adapt to theme:// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Standard IChart uses hardcoded dark theme colors from \u003Ccode dir=\"auto\">chromeColors\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"reference-line-colors\">Reference Line Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#reference-line-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reference Line Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Control limits (staged: subtler; non-staged: standard)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.control} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// cyan-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.8\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// staged (1 for non-staged)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">strokeDasharray\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">6,4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// staged (\"4,4\" for non-staged)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">strokeOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.6\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// staged (1 for non-staged)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mean line (bold anchor)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.mean} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// blue-500 solid\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// staged (1.5 for non-staged)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Spec limits (USL/LSL) - dash-dot pattern\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.spec} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// red-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">strokeDasharray\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">8,3,2,3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// dash-dot (distinct from control dashes)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">strokeOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.7\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Target line\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.target} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// green-500 dotted\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">strokeDasharray\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">2,2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Control limits (staged: subtler; non-staged: standard)stroke={chartColors.control} // cyan-500strokeWidth={0.8} // staged (1 for non-staged)strokeDasharray="6,4" // staged ("4,4" for non-staged)strokeOpacity={0.6} // staged (1 for non-staged)// Mean line (bold anchor)stroke={chartColors.mean} // blue-500 solidstrokeWidth={2} // staged (1.5 for non-staged)// Spec limits (USL/LSL) - dash-dot patternstroke={chartColors.spec} // red-500strokeWidth={1.5}strokeDasharray="8,3,2,3" // dash-dot (distinct from control dashes)strokeOpacity={0.7}// Target linestroke={chartColors.target} // green-500 dottedstrokeWidth={1}strokeDasharray="2,2"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"exports\">Exports\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#exports\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Responsive wrappers (auto-sizing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> IChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/IChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceIChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceIChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Base components (manual sizing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { IChartBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/IChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { PerformanceIChartBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceIChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Types\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { IChartProps, IChartDataPoint, PerformanceIChartProps } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Responsive wrappers (auto-sizing)import IChart from '@variscout/charts/IChart';import PerformanceIChart from '@variscout/charts/PerformanceIChart';// Base components (manual sizing)import { IChartBase } from '@variscout/charts/IChart';import { PerformanceIChartBase } from '@variscout/charts/PerformanceIChart';// Typesimport type { IChartProps, IChartDataPoint, PerformanceIChartProps } from '@variscout/charts';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview and selection guide\u003C/li>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - Chart color constants and health classification\u003C/li>\n\u003Cli>\u003Ca href=\"./responsive.md\">Responsive\u003C/a> - Breakpoints and scaling utilities\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - useChartLayout, useChartTooltip\u003C/li>\n\u003Cli>\u003Ca href=\"./performance-mode.md\">Performance Mode\u003C/a> - Full Performance Mode documentation\u003C/li>\n\u003Cli>\u003Ca href=\"./boxplot.md\">Boxplot\u003C/a> - Distribution comparison charts\u003C/li>\n\u003C/ul>", + { + "headings": 10184, + "localImagePaths": 10255, + "remoteImagePaths": 10256, + "frontmatter": 10257, + "imagePaths": 10258 + }, + [ + 10185, 10187, 10188, 10191, 10192, 10193, 10194, 10197, 10200, 10203, 10204, 10207, 10208, + 10209, 10210, 10213, 10216, 10219, 10220, 10221, 10224, 10225, 10227, 10229, 10230, 10231, + 10232, 10235, 10238, 10239, 10242, 10245, 10246, 10247, 10248, 10251, 10252, 10253, 10254 + ], + { "depth": 30, "slug": 10186, "text": 10174 }, + "individual-control-charts-i-chart", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 10189, "text": 10190 }, + "standard-ichart", + "Standard IChart", + { "depth": 79, "slug": 9737, "text": 9738 }, + { "depth": 79, "slug": 3315, "text": 3316 }, + { "depth": 79, "slug": 980, "text": 981 }, + { "depth": 621, "slug": 10195, "text": 10196 }, + "standard-mode-single-stats", + "Standard Mode (Single Stats)", + { "depth": 621, "slug": 10198, "text": 10199 }, + "staged-mode", + "Staged Mode", + { "depth": 621, "slug": 10201, "text": 10202 }, + "visual-hierarchy-staged-mode", + "Visual Hierarchy (Staged Mode)", + { "depth": 621, "slug": 9758, "text": 9759 }, + { "depth": 33, "slug": 10205, "text": 10206 }, + "performanceichart", + "PerformanceIChart", + { "depth": 79, "slug": 9764, "text": 9738 }, + { "depth": 79, "slug": 1082, "text": 1070 }, + { "depth": 79, "slug": 9766, "text": 9767 }, + { "depth": 79, "slug": 10211, "text": 10212 }, + "control-limit-lines", + "Control Limit Lines", + { "depth": 79, "slug": 10214, "text": 10215 }, + "control-based-coloring", + "Control-Based Coloring", + { "depth": 79, "slug": 10217, "text": 10218 }, + "control-limit-calculation", + "Control Limit Calculation", + { "depth": 79, "slug": 7536, "text": 7537 }, + { "depth": 33, "slug": 9773, "text": 9774 }, + { "depth": 33, "slug": 10222, "text": 10223 }, + "point-coloring-minitab-2-color-scheme", + "Point Coloring (Minitab 2-Color Scheme)", + { "depth": 33, "slug": 9776, "text": 9777 }, + { "depth": 79, "slug": 10226, "text": 10190 }, + "standard-ichart-1", + { "depth": 79, "slug": 10228, "text": 10206 }, + "performanceichart-1", + { "depth": 33, "slug": 9783, "text": 9784 }, + { "depth": 79, "slug": 9792, "text": 9793 }, + { "depth": 79, "slug": 9795, "text": 9796 }, + { "depth": 33, "slug": 10233, "text": 10234 }, + "i-chart-annotations", + "I-Chart Annotations", + { "depth": 79, "slug": 10236, "text": 10237 }, + "annotation-props-app-wrapper-level", + "Annotation Props (App Wrapper Level)", + { "depth": 79, "slug": 1173, "text": 1174 }, + { "depth": 79, "slug": 10240, "text": 10241 }, + "position-system", + "Position System", + { "depth": 79, "slug": 10243, "text": 10244 }, + "clearing-annotations", + "Clearing Annotations", + { "depth": 33, "slug": 9801, "text": 9802 }, + { "depth": 79, "slug": 9804, "text": 9805 }, + { "depth": 33, "slug": 9807, "text": 9808 }, + { "depth": 79, "slug": 10249, "text": 10250 }, + "point-colors", + "Point Colors", + { "depth": 79, "slug": 9813, "text": 9814 }, + { "depth": 79, "slug": 9911, "text": 9912 }, + { "depth": 33, "slug": 1723, "text": 1724 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 10174 }, + [], + "06-design-system/charts/overview", + { + "id": 10259, + "data": 10261, + "body": 10266, + "filePath": 10267, + "digest": 10268, + "rendered": 10269 + }, + { + "title": 10262, + "editUrl": 16, + "head": 10263, + "template": 18, + "sidebar": 10264, + "pagefind": 16, + "draft": 20 + }, + "Chart Styling Overview", + [], + { "hidden": 20, "attrs": 10265 }, + {}, + "# Chart Styling Overview\n\nVariScout charts are built with [Visx](https://airbnb.io/visx/) and follow consistent styling patterns.\n\n## Architecture\n\nCharts are in the `@variscout/charts` package and are **props-based** (no context dependency):\n\n```tsx\ninterface ChartProps extends BaseChartProps {\n data: DataType[];\n specs?: SpecLimits;\n showBranding?: boolean;\n parentWidth: number;\n parentHeight: number;\n}\n```\n\n## Component Structure\n\nEach chart exports:\n\n- **Wrapped version** - Uses `withParentSize` for responsive sizing\n- **Base version** - Accepts explicit dimensions\n\n```tsx\nimport IChart, { IChartBase } from '@variscout/charts';\n\n// Auto-sizing (fills parent container)\n\u003CIChart data={data} specs={specs} />\n\n// Manual sizing\n\u003CIChartBase data={data} specs={specs} parentWidth={800} parentHeight={400} />\n```\n\n## Dark Theme\n\nAll charts use a dark theme matching the application:\n\n- Background: transparent (inherits from container)\n- Grid lines: `#334155` (slate-700) with 30-50% opacity\n- Axis lines: `#64748b` (slate-500)\n- Text: `#94a3b8` (slate-400)\n\n## Chart Types\n\n| Chart | Purpose | Key Features |\n| ------------------- | --------------------------- | --------------------------------------------------------------- |\n| **IChart** | Individual values over time | UCL/LCL lines, out-of-spec highlighting |\n| **Boxplot** | Distribution by category | Quartiles, whiskers, outliers, Violin Mode (density overlay) |\n| **ParetoChart** | Defect frequency/value | Sorted bars, cumulative line, 80% reference, aggregation toggle |\n| **Histogram** | Value distribution | Bins, normal curve overlay |\n| **ScatterPlot** | X-Y relationship | Regression line, R² display |\n| **ProbabilityPlot** | Normality assessment | Reference line, confidence bands |\n\n### I-Chart Data Point Coloring\n\nThe I-Chart uses a Minitab-style 2-color scheme for clarity:\n\n| Color | Hex | Condition |\n| ----- | --------- | --------------------------------------- |\n| Blue | `#3b82f6` | Point is in-control (passes all checks) |\n| Red | `#ef4444` | Point has any violation |\n\n**Violation check order:**\n\n1. Spec limit violations (`value > USL` or `value \u003C LSL`)\n2. Control limit violations (`value > UCL` or `value \u003C LCL`)\n3. Nelson Rule 2 (9+ consecutive points on same side of center line)\n\nSee [colors.md](colors.md) for implementation details and graded data handling.\n\n## Chart Annotations\n\nI-Chart, Boxplot, and Pareto charts support two types of chart annotations: **color highlights** (lightweight visual markers) and **observations** (text annotations backed by the Findings system).\n\n### Annotation Types\n\n| Type | Charts | Stored in | Creates a Finding? |\n| ----------------- | ------------------------ | ------------------------ | ------------------ |\n| Color highlights | Boxplot, Pareto | DisplayOptions | No |\n| Text observations | Boxplot, Pareto, I-Chart | Findings (AnalysisState) | Yes |\n\n**Color highlights** (red/amber/green) are lightweight visual markers on Boxplot boxes and Pareto bars. They do not create findings and are stored in DisplayOptions.\n\n**Text observations** create a Finding with `source` metadata linking it to the originating chart and category. The floating text box on the chart is a visual projection of the underlying Finding — editing either side keeps them in sync. The annotation box displays a small status dot reflecting the finding's investigation status (amber = observed, blue = investigating, purple = analyzed).\n\n### Anchor Types\n\n| Chart | Anchor Type | Highlights | How to Create |\n| ------- | ----------------- | ---------- | ------------------------------------------------------ |\n| Boxplot | Category-based | Yes | Right-click box → context menu → \"Add observation\" |\n| Pareto | Category-based | Yes | Right-click bar → context menu → \"Add observation\" |\n| I-Chart | Free-floating (%) | No | Right-click chart area → observation appears at cursor |\n\n**Category-based anchors** (Boxplot/Pareto): observations follow the named group and are hidden when that category is filtered out. Offsets reset to (0, 0) on data changes (snap back to anchor). The Finding carries a `source` field with chart type and category name.\n\n**Free-floating anchors** (I-Chart): observations are stored as a percentage position within the chart area. They remain at their visual position when data is filtered or the time range changes. I-Chart dot colors carry semantic meaning (blue = in-control, red = violation) and are never overridden by highlight colors.\n\n### Interaction Model\n\n| Platform | Interaction | Charts |\n| --------------- | ------------------------- | ------------------------ |\n| Desktop | Right-click context menu | Boxplot, Pareto, I-Chart |\n| Mobile (\u003C640px) | Tap → bottom action sheet | Boxplot, Pareto |\n\nMobile: `MobileCategorySheet` \"Pin as Finding\" action includes `source` metadata (chart type and category). I-Chart observations (free-floating text) are desktop-only.\n\n### Components\n\n| Component | Package | Purpose |\n| ----------------------- | --------------- | -------------------------------------------------------------------- |\n| `ChartAnnotationLayer` | `@variscout/ui` | HTML overlay for draggable text annotations (reads from `Finding[]`) |\n| `AnnotationBox` | `@variscout/ui` | Individual annotation (edit, drag, resize, status dot) |\n| `AnnotationContextMenu` | `@variscout/ui` | Right-click menu (highlight + add observation) |\n\n### Data Types\n\nText observations are stored as `Finding` objects (from `@variscout/core`) with a `source` field:\n\n```typescript\ninterface FindingSource {\n chartType: 'boxplot' | 'pareto' | 'ichart';\n category?: string; // category name (Boxplot/Pareto)\n anchorX?: number; // 0–1 fraction of chart width (I-Chart)\n anchorY?: number; // 0–1 fraction of chart height (I-Chart)\n}\n\n// Finding.source links the finding to its chart origin\ninterface Finding {\n id: string;\n text: string;\n status: FindingStatus;\n source?: FindingSource; // present for chart observations\n // ... other Finding fields\n}\n```\n\nColor highlights remain a separate lightweight type:\n\n```typescript\ntype HighlightColor = 'red' | 'amber' | 'green';\n// Stored in DisplayOptions.highlightedCategories\n```\n\n### Chart Base Props\n\nBoth `BoxplotBase` and `ParetoChartBase` accept:\n\n- `highlightedCategories?: Record\u003Cstring, HighlightColor>` — per-category fill color override\n- `onBoxContextMenu?: (key: string, event: React.MouseEvent) => void` — right-click handler (Boxplot)\n- `onBarContextMenu?: (key: string, event: React.MouseEvent) => void` — right-click handler (Pareto)\n\n`IChartBase` accepts:\n\n- `ichartAnnotations?: Finding[]` — findings with chart source to render as floating annotations\n- `onChartContextMenu?: (anchorX: number, anchorY: number, event: React.MouseEvent) => void` — right-click handler\n\n### Hook: `useAnnotations`\n\nShared hook from `@variscout/hooks` managing annotation state:\n\n- `contextMenu` state (open, position, category, chart type)\n- `handleContextMenu(chartType, key, event)` — opens context menu (Boxplot/Pareto)\n- `setHighlight(chartType, key, color)` — direct color setting (DisplayOptions)\n- `createObservation(chartType, key)` — creates a Finding with chart source metadata\n- `createIChartObservation(anchorX, anchorY)` — creates a Finding at % position with I-Chart source\n- `clearHighlights(chartType)` — clears color highlights for a chart\n- Data fingerprint offset reset (Boxplot/Pareto annotations snap back on data changes)\n\nText observations are persisted via the Findings system (AnalysisState), not DisplayOptions.\n\n---\n\n## Common Elements\n\n### Spec Limit Lines\n\n```tsx\n// USL (Upper Spec Limit) - Red dash-dot\n\u003Cline stroke=\"#ef4444\" strokeDasharray=\"8,3,2,3\" strokeWidth={1.5} strokeOpacity={0.7} />\n\n// LSL (Lower Spec Limit) - Amber dash-dot\n\u003Cline stroke=\"#f59e0b\" strokeDasharray=\"8,3,2,3\" strokeWidth={1.5} strokeOpacity={0.7} />\n\n// Target - Green dotted\n\u003Cline stroke=\"#22c55e\" strokeDasharray=\"2,2\" strokeWidth={1} />\n```\n\n### Control Lines\n\n```tsx\n// UCL/LCL (Control Limits) - staged mode (subtler)\n\u003Cline stroke=\"#3b82f6\" strokeDasharray=\"6,4\" strokeWidth={0.8} strokeOpacity={0.6} />\n\n// UCL/LCL (Control Limits) - non-staged mode\n\u003Cline stroke=\"#3b82f6\" strokeDasharray=\"4,4\" strokeWidth={1} />\n\n// Center line (Mean) - Bold in staged mode\n\u003Cline stroke=\"#64748b\" strokeWidth={2} /> // staged\n\u003Cline stroke=\"#64748b\" strokeWidth={1.5} /> // non-staged\n```\n\n### Limit Annotations (Minitab-style)\n\nI-Chart displays numeric values next to limit lines for at-a-glance reading:\n\n```tsx\n// Text annotation positioned right of chart\n\u003Ctext\n x={width + 4}\n y={yScale(value)}\n fill={lineColor}\n fontSize={fonts.statLabel}\n textAnchor=\"start\"\n dominantBaseline=\"middle\"\n>\n UCL: {value.toFixed(1)}\n\u003C/text>\n```\n\n**Annotation Types:**\n\n| Line | Color | Format | Clickable |\n| ------ | --------- | ------------ | --------- |\n| UCL | `#64748b` | \"UCL: 47.3\" | No |\n| Mean | `#3b82f6` | \"Mean: 42.1\" | No |\n| LCL | `#64748b` | \"LCL: 36.9\" | No |\n| USL | `#ef4444` | \"USL: 50.0\" | Yes |\n| LSL | `#ef4444` | \"LSL: 35.0\" | Yes |\n| Target | `#22c55e` | \"Tgt: 42.0\" | Yes |\n\n**Responsive Margin:**\n\nThe I-Chart right margin is increased to accommodate annotations:\n\n```tsx\n// In responsive.ts\nichart: { top: 40, right: 85, bottom: 60, left: 70 }\n```\n\n**Clickable Spec Editing:**\n\nSpec limit annotations (USL/LSL/Target) are clickable to open the spec editor:\n\n```tsx\n\u003Cg\n onClick={() => onSpecClick?.('usl')}\n style={{ cursor: onSpecClick ? 'pointer' : 'default' }}\n className=\"hover:opacity-80\"\n>\n \u003Cline ... />\n \u003Ctext>USL: {specs.usl.toFixed(1)}\u003C/text>\n\u003C/g>\n```\n\n**Accessing Spec Editor:**\n\nUsers can open the SpecEditor from multiple entry points:\n\n| Entry Point | Location | When Visible |\n| ------------------- | ------------------------------- | -------------------------------- |\n| \"+ Specs\" button | I-Chart header | When no specs defined |\n| \"+ Target\" button | I-Chart header | When specs defined but no target |\n| Click annotation | I-Chart (USL/LSL/Target labels) | When specs are defined |\n| Click specs display | StatsPanel bottom section | Always (secondary access) |\n| Menu item | MobileMenu → Analysis section | Mobile only |\n\nThe MobileMenu \"Edit Specification Limits\" option ensures mobile users have clear access to spec editing since the I-Chart header buttons may be less discoverable on small screens.\n\n### Y-Axis Scale Editing\n\nUsers can click the Y-axis tick area to open a popover for manual scale adjustment. This allows focusing on specific data ranges or ensuring consistent scales across analyses.\n\n**Entry Point:**\n\nThe I-Chart includes an invisible clickable rectangle over the Y-axis tick area:\n\n```tsx\n{\n onYAxisClick && (\n \u003Crect\n x={0}\n y={margin.top}\n width={margin.left}\n height={height - margin.top - margin.bottom}\n fill=\"transparent\"\n style={{ cursor: 'pointer' }}\n onClick={e => {\n const rect = e.currentTarget.getBoundingClientRect();\n onYAxisClick({ top: e.clientY - rect.top, left: margin.left });\n }}\n />\n );\n}\n```\n\n**YAxisPopover Component:**\n\nThe popover provides min/max inputs with validation. The popover provides min/max inputs with validation.\n\n```tsx\n\u003CYAxisPopover\n isOpen={yAxisPopoverOpen}\n onClose={() => setYAxisPopoverOpen(false)}\n currentMin={yAxisSettings.min}\n currentMax={yAxisSettings.max}\n autoMin={dataMin}\n autoMax={dataMax}\n onSave={setYAxisSettings}\n anchorPosition={popoverPosition}\n/>\n```\n\n**Behavior:**\n\n| Setting | Y-Scale Behavior |\n| ------------- | --------------------------------------- |\n| Both empty | Auto-scale from data (default) |\n| Min only | Fixed minimum, auto maximum |\n| Max only | Auto minimum, fixed maximum |\n| Both set | Fixed range (validation: min \u003C max) |\n| Reset to Auto | Clears overrides, returns to auto-scale |\n\n**Visual Indicator:**\n\nWhen custom scale is active, the chart shows a visual cue (implementation-specific) to indicate non-default scaling.\n\n### Tooltips\n\nUse Visx `useTooltip` with consistent styling:\n\n```tsx\n\u003CTooltipWithBounds\n style={{\n background: '#1e293b',\n border: '1px solid #334155',\n color: '#f1f5f9',\n fontSize: 12,\n padding: '8px 12px',\n }}\n>\n {content}\n\u003C/TooltipWithBounds>\n```\n\n### Branding Footer\n\n`ChartSourceBar` component adds branding:\n\n```tsx\n\u003CChartSourceBar\n width={width}\n top={height + margin.bottom - 18}\n n={dataLength}\n brandingText=\"VariScout Lite\"\n/>\n```\n\nHeight: 18px (included in bottom margin calculations)\n\n## Best Practices\n\n1. **Use responsive utilities** from `packages/charts/src/responsive.ts`\n2. **Include branding** unless chart is in a compact view\n3. **Add tooltips** for interactive elements\n4. **Handle empty states** gracefully - show actionable options when no data (see [feedback patterns](../patterns/feedback.md#actionable-empty-state))\n5. **Test at multiple sizes** using the responsive wrapper\n\n---\n\n## See Also\n\n- [Colors](./colors.md) - Data visualization color palette\n- [Responsive](./responsive.md) - Breakpoints and scaling utilities\n- [Hooks](./hooks.md) - React hooks API for charts\n- [Shared Components](./shared-components.md) - Reusable chart UI components", + "src/content/docs/06-design-system/charts/overview.md", + "7f92f30559bca4df", + { "html": 10270, "metadata": 10271 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"chart-styling-overview\">Chart Styling Overview\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#chart-styling-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Styling Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout charts are built with \u003Ca href=\"https://airbnb.io/visx/\">Visx\u003C/a> and follow consistent styling patterns.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"architecture\">Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Charts are in the \u003Ccode dir=\"auto\">@variscout/charts\u003C/code> package and are \u003Cstrong>props-based\u003C/strong> (no context dependency):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChartProps \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extends\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">BaseChartProps\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DataType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showBranding\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ChartProps extends BaseChartProps { data: DataType[]; specs?: SpecLimits; showBranding?: boolean; parentWidth: number; parentHeight: number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"component-structure\">Component Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#component-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Component Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each chart exports:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Wrapped version\u003C/strong> - Uses \u003Ccode dir=\"auto\">withParentSize\u003C/code> for responsive sizing\u003C/li>\n\u003Cli>\u003Cstrong>Base version\u003C/strong> - Accepts explicit dimensions\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> IChart, { IChartBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Auto-sizing (fills parent container)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Manual sizing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChartBase\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">800\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">400\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import IChart, { IChartBase } from '@variscout/charts';// Auto-sizing (fills parent container)\u003CIChart data={data} specs={specs} />// Manual sizing\u003CIChartBase data={data} specs={specs} parentWidth={800} parentHeight={400} />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dark-theme\">Dark Theme\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dark-theme\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dark Theme”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All charts use a dark theme matching the application:\u003C/p>\n\u003Cul>\n\u003Cli>Background: transparent (inherits from container)\u003C/li>\n\u003Cli>Grid lines: \u003Ccode dir=\"auto\">#334155\u003C/code> (slate-700) with 30-50% opacity\u003C/li>\n\u003Cli>Axis lines: \u003Ccode dir=\"auto\">#64748b\u003C/code> (slate-500)\u003C/li>\n\u003Cli>Text: \u003Ccode dir=\"auto\">#94a3b8\u003C/code> (slate-400)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-types\">Chart Types\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-types\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Types”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Key Features\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>IChart\u003C/strong>\u003C/td>\u003Ctd>Individual values over time\u003C/td>\u003Ctd>UCL/LCL lines, out-of-spec highlighting\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Boxplot\u003C/strong>\u003C/td>\u003Ctd>Distribution by category\u003C/td>\u003Ctd>Quartiles, whiskers, outliers, Violin Mode (density overlay)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>ParetoChart\u003C/strong>\u003C/td>\u003Ctd>Defect frequency/value\u003C/td>\u003Ctd>Sorted bars, cumulative line, 80% reference, aggregation toggle\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Histogram\u003C/strong>\u003C/td>\u003Ctd>Value distribution\u003C/td>\u003Ctd>Bins, normal curve overlay\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>ScatterPlot\u003C/strong>\u003C/td>\u003Ctd>X-Y relationship\u003C/td>\u003Ctd>Regression line, R² display\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>ProbabilityPlot\u003C/strong>\u003C/td>\u003Ctd>Normality assessment\u003C/td>\u003Ctd>Reference line, confidence bands\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"i-chart-data-point-coloring\">I-Chart Data Point Coloring\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#i-chart-data-point-coloring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “I-Chart Data Point Coloring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The I-Chart uses a Minitab-style 2-color scheme for clarity:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Color\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Condition\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Blue\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#3b82f6\u003C/code>\u003C/td>\u003Ctd>Point is in-control (passes all checks)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Red\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ef4444\u003C/code>\u003C/td>\u003Ctd>Point has any violation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Violation check order:\u003C/strong>\u003C/p>\n\u003Col>\n\u003Cli>Spec limit violations (\u003Ccode dir=\"auto\">value > USL\u003C/code> or \u003Ccode dir=\"auto\">value < LSL\u003C/code>)\u003C/li>\n\u003Cli>Control limit violations (\u003Ccode dir=\"auto\">value > UCL\u003C/code> or \u003Ccode dir=\"auto\">value < LCL\u003C/code>)\u003C/li>\n\u003Cli>Nelson Rule 2 (9+ consecutive points on same side of center line)\u003C/li>\n\u003C/ol>\n\u003Cp>See \u003Ca href=\"colors.md\">colors.md\u003C/a> for implementation details and graded data handling.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-annotations\">Chart Annotations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-annotations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Annotations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>I-Chart, Boxplot, and Pareto charts support two types of chart annotations: \u003Cstrong>color highlights\u003C/strong> (lightweight visual markers) and \u003Cstrong>observations\u003C/strong> (text annotations backed by the Findings system).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"annotation-types\">Annotation Types\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#annotation-types\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Annotation Types”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Charts\u003C/th>\u003Cth>Stored in\u003C/th>\u003Cth>Creates a Finding?\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Color highlights\u003C/td>\u003Ctd>Boxplot, Pareto\u003C/td>\u003Ctd>DisplayOptions\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Text observations\u003C/td>\u003Ctd>Boxplot, Pareto, I-Chart\u003C/td>\u003Ctd>Findings (AnalysisState)\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Color highlights\u003C/strong> (red/amber/green) are lightweight visual markers on Boxplot boxes and Pareto bars. They do not create findings and are stored in DisplayOptions.\u003C/p>\n\u003Cp>\u003Cstrong>Text observations\u003C/strong> create a Finding with \u003Ccode dir=\"auto\">source\u003C/code> metadata linking it to the originating chart and category. The floating text box on the chart is a visual projection of the underlying Finding — editing either side keeps them in sync. The annotation box displays a small status dot reflecting the finding’s investigation status (amber = observed, blue = investigating, purple = analyzed).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"anchor-types\">Anchor Types\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#anchor-types\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Anchor Types”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Anchor Type\u003C/th>\u003Cth>Highlights\u003C/th>\u003Cth>How to Create\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Category-based\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Right-click box → context menu → “Add observation”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto\u003C/td>\u003Ctd>Category-based\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Right-click bar → context menu → “Add observation”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>I-Chart\u003C/td>\u003Ctd>Free-floating (%)\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Right-click chart area → observation appears at cursor\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Category-based anchors\u003C/strong> (Boxplot/Pareto): observations follow the named group and are hidden when that category is filtered out. Offsets reset to (0, 0) on data changes (snap back to anchor). The Finding carries a \u003Ccode dir=\"auto\">source\u003C/code> field with chart type and category name.\u003C/p>\n\u003Cp>\u003Cstrong>Free-floating anchors\u003C/strong> (I-Chart): observations are stored as a percentage position within the chart area. They remain at their visual position when data is filtered or the time range changes. I-Chart dot colors carry semantic meaning (blue = in-control, red = violation) and are never overridden by highlight colors.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interaction-model\">Interaction Model\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interaction-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interaction Model”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Interaction\u003C/th>\u003Cth>Charts\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Desktop\u003C/td>\u003Ctd>Right-click context menu\u003C/td>\u003Ctd>Boxplot, Pareto, I-Chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mobile (<640px)\u003C/td>\u003Ctd>Tap → bottom action sheet\u003C/td>\u003Ctd>Boxplot, Pareto\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Mobile: \u003Ccode dir=\"auto\">MobileCategorySheet\u003C/code> “Pin as Finding” action includes \u003Ccode dir=\"auto\">source\u003C/code> metadata (chart type and category). I-Chart observations (free-floating text) are desktop-only.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"components\">Components\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Components”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Package\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChartAnnotationLayer\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>HTML overlay for draggable text annotations (reads from \u003Ccode dir=\"auto\">Finding[]\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">AnnotationBox\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Individual annotation (edit, drag, resize, status dot)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">AnnotationContextMenu\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Right-click menu (highlight + add observation)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-types\">Data Types\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-types\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Types”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Text observations are stored as \u003Ccode dir=\"auto\">Finding\u003C/code> objects (from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>) with a \u003Ccode dir=\"auto\">source\u003C/code> field:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FindingSource {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartType\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ichart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">category\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// category name (Boxplot/Pareto)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">anchorX\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 0–1 fraction of chart width (I-Chart)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">anchorY\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 0–1 fraction of chart height (I-Chart)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Finding.source links the finding to its chart origin\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Finding {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">status\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FindingStatus\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">source\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FindingSource\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// present for chart observations\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ... other Finding fields\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface FindingSource { chartType: 'boxplot' | 'pareto' | 'ichart'; category?: string; // category name (Boxplot/Pareto) anchorX?: number; // 0–1 fraction of chart width (I-Chart) anchorY?: number; // 0–1 fraction of chart height (I-Chart)}// Finding.source links the finding to its chart origininterface Finding { id: string; text: string; status: FindingStatus; source?: FindingSource; // present for chart observations // ... other Finding fields}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Color highlights remain a separate lightweight type:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> HighlightColor \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">red\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">amber\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">green\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Stored in DisplayOptions.highlightedCategories\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"type HighlightColor = 'red' | 'amber' | 'green';// Stored in DisplayOptions.highlightedCategories\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"chart-base-props\">Chart Base Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#chart-base-props\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Base Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both \u003Ccode dir=\"auto\">BoxplotBase\u003C/code> and \u003Ccode dir=\"auto\">ParetoChartBase\u003C/code> accept:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">highlightedCategories?: Record<string, HighlightColor>\u003C/code> — per-category fill color override\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">onBoxContextMenu?: (key: string, event: React.MouseEvent) => void\u003C/code> — right-click handler (Boxplot)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">onBarContextMenu?: (key: string, event: React.MouseEvent) => void\u003C/code> — right-click handler (Pareto)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Ccode dir=\"auto\">IChartBase\u003C/code> accepts:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">ichartAnnotations?: Finding[]\u003C/code> — findings with chart source to render as floating annotations\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">onChartContextMenu?: (anchorX: number, anchorY: number, event: React.MouseEvent) => void\u003C/code> — right-click handler\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"hook-useannotations\">Hook: \u003Ccode dir=\"auto\">useAnnotations\u003C/code>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#hook-useannotations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hook: useAnnotations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shared hook from \u003Ccode dir=\"auto\">@variscout/hooks\u003C/code> managing annotation state:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">contextMenu\u003C/code> state (open, position, category, chart type)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">handleContextMenu(chartType, key, event)\u003C/code> — opens context menu (Boxplot/Pareto)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">setHighlight(chartType, key, color)\u003C/code> — direct color setting (DisplayOptions)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">createObservation(chartType, key)\u003C/code> — creates a Finding with chart source metadata\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">createIChartObservation(anchorX, anchorY)\u003C/code> — creates a Finding at % position with I-Chart source\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">clearHighlights(chartType)\u003C/code> — clears color highlights for a chart\u003C/li>\n\u003Cli>Data fingerprint offset reset (Boxplot/Pareto annotations snap back on data changes)\u003C/li>\n\u003C/ul>\n\u003Cp>Text observations are persisted via the Findings system (AnalysisState), not DisplayOptions.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"common-elements\">Common Elements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#common-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Elements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"spec-limit-lines\">Spec Limit Lines\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#spec-limit-lines\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Spec Limit Lines”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// USL (Upper Spec Limit) - Red dash-dot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">line\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#ef4444\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeDasharray\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">8,3,2,3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.5\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.7\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// LSL (Lower Spec Limit) - Amber dash-dot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">line\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#f59e0b\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeDasharray\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">8,3,2,3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.5\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.7\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Target - Green dotted\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">line\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#22c55e\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeDasharray\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">2,2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// USL (Upper Spec Limit) - Red dash-dot\u003Cline stroke="#ef4444" strokeDasharray="8,3,2,3" strokeWidth={1.5} strokeOpacity={0.7} />// LSL (Lower Spec Limit) - Amber dash-dot\u003Cline stroke="#f59e0b" strokeDasharray="8,3,2,3" strokeWidth={1.5} strokeOpacity={0.7} />// Target - Green dotted\u003Cline stroke="#22c55e" strokeDasharray="2,2" strokeWidth={1} />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"control-lines\">Control Lines\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#control-lines\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Control Lines”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// UCL/LCL (Control Limits) - staged mode (subtler)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">line\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#3b82f6\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeDasharray\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">6,4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.8\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeOpacity\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0.6\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// UCL/LCL (Control Limits) - non-staged mode\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">line\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#3b82f6\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeDasharray\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">4,4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Center line (Mean) - Bold in staged mode\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">line\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#64748b\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// staged\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">line\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#64748b\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">strokeWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.5\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// non-staged\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// UCL/LCL (Control Limits) - staged mode (subtler)\u003Cline stroke="#3b82f6" strokeDasharray="6,4" strokeWidth={0.8} strokeOpacity={0.6} />// UCL/LCL (Control Limits) - non-staged mode\u003Cline stroke="#3b82f6" strokeDasharray="4,4" strokeWidth={1} />// Center line (Mean) - Bold in staged mode\u003Cline stroke="#64748b" strokeWidth={2} /> // staged\u003Cline stroke="#64748b" strokeWidth={1.5} /> // non-staged\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"limit-annotations-minitab-style\">Limit Annotations (Minitab-style)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#limit-annotations-minitab-style\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Limit Annotations (Minitab-style)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>I-Chart displays numeric values next to limit lines for at-a-glance reading:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Text annotation positioned right of chart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">text\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">x\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">+\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">4\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">y\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">yScale\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(value)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">lineColor\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fontSize\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">statLabel\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">textAnchor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">start\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">dominantBaseline\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">middle\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">UCL: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toFixed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Text annotation positioned right of chart\u003Ctext x={width + 4} y={yScale(value)} fill={lineColor} fontSize={fonts.statLabel} textAnchor="start" dominantBaseline="middle"> UCL: {value.toFixed(1)}\u003C/text>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Annotation Types:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Line\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Format\u003C/th>\u003Cth>Clickable\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>UCL\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>”UCL: 47.3”\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mean\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#3b82f6\u003C/code>\u003C/td>\u003Ctd>”Mean: 42.1”\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LCL\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>”LCL: 36.9”\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>USL\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ef4444\u003C/code>\u003C/td>\u003Ctd>”USL: 50.0”\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>LSL\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ef4444\u003C/code>\u003C/td>\u003Ctd>”LSL: 35.0”\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Target\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#22c55e\u003C/code>\u003C/td>\u003Ctd>”Tgt: 42.0”\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Responsive Margin:\u003C/strong>\u003C/p>\n\u003Cp>The I-Chart right margin is increased to accommodate annotations:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// In responsive.ts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ichart: { top: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">40\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, right: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">85\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, bottom: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">60\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, left: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">70\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// In responsive.tsichart: { top: 40, right: 85, bottom: 60, left: 70 }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Clickable Spec Editing:\u003C/strong>\u003C/p>\n\u003Cp>Spec limit annotations (USL/LSL/Target) are clickable to open the spec editor:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">g\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onSpecClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">usl\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">style\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ cursor: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onSpecClick\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pointer\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">default\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">hover:opacity-80\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">line\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#FFFFFF;--1:#984E4D\">...\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">USL: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">usl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toFixed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">g\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cg onClick={() => onSpecClick?.('usl')} style={{ cursor: onSpecClick ? 'pointer' : 'default' }} className="hover:opacity-80"> \u003Cline ... /> \u003Ctext>USL: {specs.usl.toFixed(1)}\u003C/text>\u003C/g>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Accessing Spec Editor:\u003C/strong>\u003C/p>\n\u003Cp>Users can open the SpecEditor from multiple entry points:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Entry Point\u003C/th>\u003Cth>Location\u003C/th>\u003Cth>When Visible\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>”+ Specs” button\u003C/td>\u003Ctd>I-Chart header\u003C/td>\u003Ctd>When no specs defined\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”+ Target” button\u003C/td>\u003Ctd>I-Chart header\u003C/td>\u003Ctd>When specs defined but no target\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Click annotation\u003C/td>\u003Ctd>I-Chart (USL/LSL/Target labels)\u003C/td>\u003Ctd>When specs are defined\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Click specs display\u003C/td>\u003Ctd>StatsPanel bottom section\u003C/td>\u003Ctd>Always (secondary access)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Menu item\u003C/td>\u003Ctd>MobileMenu → Analysis section\u003C/td>\u003Ctd>Mobile only\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The MobileMenu “Edit Specification Limits” option ensures mobile users have clear access to spec editing since the I-Chart header buttons may be less discoverable on small screens.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"y-axis-scale-editing\">Y-Axis Scale Editing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#y-axis-scale-editing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Y-Axis Scale Editing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Users can click the Y-axis tick area to open a popover for manual scale adjustment. This allows focusing on specific data ranges or ensuring consistent scales across analyses.\u003C/p>\n\u003Cp>\u003Cstrong>Entry Point:\u003C/strong>\u003C/p>\n\u003Cp>The I-Chart includes an invisible clickable rectangle over the Y-axis tick area:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onYAxisClick \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">rect\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">x\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">y\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">top\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">left\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">top\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">bottom\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">transparent\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">style\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ cursor: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pointer\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> {\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">rect\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">currentTarget\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getBoundingClientRect\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onYAxisClick\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ top: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">clientY\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">rect\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">top\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, left: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">left\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{ onYAxisClick && ( \u003Crect x={0} y={margin.top} width={margin.left} height={height - margin.top - margin.bottom} fill="transparent" style={{ cursor: 'pointer' }} onClick={e => { const rect = e.currentTarget.getBoundingClientRect(); onYAxisClick({ top: e.clientY - rect.top, left: margin.left }); }} /> );}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>YAxisPopover Component:\u003C/strong>\u003C/p>\n\u003Cp>The popover provides min/max inputs with validation. The popover provides min/max inputs with validation.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">YAxisPopover\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">isOpen\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yAxisPopoverOpen\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClose\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setYAxisPopoverOpen\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">currentMin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yAxisSettings\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">min\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">currentMax\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yAxisSettings\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">max\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">autoMin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">dataMin\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">autoMax\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">dataMax\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onSave\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setYAxisSettings\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">anchorPosition\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">popoverPosition\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CYAxisPopover isOpen={yAxisPopoverOpen} onClose={() => setYAxisPopoverOpen(false)} currentMin={yAxisSettings.min} currentMax={yAxisSettings.max} autoMin={dataMin} autoMax={dataMax} onSave={setYAxisSettings} anchorPosition={popoverPosition}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Behavior:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Setting\u003C/th>\u003Cth>Y-Scale Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Both empty\u003C/td>\u003Ctd>Auto-scale from data (default)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Min only\u003C/td>\u003Ctd>Fixed minimum, auto maximum\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Max only\u003C/td>\u003Ctd>Auto minimum, fixed maximum\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Both set\u003C/td>\u003Ctd>Fixed range (validation: min < max)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Reset to Auto\u003C/td>\u003Ctd>Clears overrides, returns to auto-scale\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Visual Indicator:\u003C/strong>\u003C/p>\n\u003Cp>When custom scale is active, the chart shows a visual cue (implementation-specific) to indicate non-default scaling.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tooltips\">Tooltips\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tooltips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tooltips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use Visx \u003Ccode dir=\"auto\">useTooltip\u003C/code> with consistent styling:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">TooltipWithBounds\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">style\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">background: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#1e293b\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">border: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">1px solid #334155\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">color: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#f1f5f9\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">fontSize: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">12\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">padding: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">8px 12px\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">content\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">TooltipWithBounds\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CTooltipWithBounds style={{ background: '#1e293b', border: '1px solid #334155', color: '#f1f5f9', fontSize: 12, padding: '8px 12px', }}> {content}\u003C/TooltipWithBounds>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"branding-footer\">Branding Footer\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#branding-footer\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Branding Footer”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">ChartSourceBar\u003C/code> component adds branding:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ChartSourceBar\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">top\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">+\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">bottom\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">-\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">18\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">n\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">dataLength\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">brandingText\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">VariScout Lite\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CChartSourceBar width={width} top={height + margin.bottom - 18} n={dataLength} brandingText="VariScout Lite"/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Height: 18px (included in bottom margin calculations)\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"best-practices\">Best Practices\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#best-practices\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Best Practices”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Use responsive utilities\u003C/strong> from \u003Ccode dir=\"auto\">packages/charts/src/responsive.ts\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Include branding\u003C/strong> unless chart is in a compact view\u003C/li>\n\u003Cli>\u003Cstrong>Add tooltips\u003C/strong> for interactive elements\u003C/li>\n\u003Cli>\u003Cstrong>Handle empty states\u003C/strong> gracefully - show actionable options when no data (see \u003Ca href=\"../patterns/feedback.md#actionable-empty-state\">feedback patterns\u003C/a>)\u003C/li>\n\u003Cli>\u003Cstrong>Test at multiple sizes\u003C/strong> using the responsive wrapper\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - Data visualization color palette\u003C/li>\n\u003Cli>\u003Ca href=\"./responsive.md\">Responsive\u003C/a> - Breakpoints and scaling utilities\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - React hooks API for charts\u003C/li>\n\u003Cli>\u003Ca href=\"./shared-components.md\">Shared Components\u003C/a> - Reusable chart UI components\u003C/li>\n\u003C/ul>", + { + "headings": 10272, + "localImagePaths": 10333, + "remoteImagePaths": 10334, + "frontmatter": 10335, + "imagePaths": 10336 + }, + [ + 10273, 10275, 10276, 10279, 10282, 10285, 10288, 10291, 10294, 10297, 10300, 10301, 10304, + 10307, 10310, 10313, 10316, 10319, 10322, 10325, 10328, 10331, 10332 + ], + { "depth": 30, "slug": 10274, "text": 10262 }, + "chart-styling-overview", + { "depth": 33, "slug": 1819, "text": 1820 }, + { "depth": 33, "slug": 10277, "text": 10278 }, + "component-structure", + "Component Structure", + { "depth": 33, "slug": 10280, "text": 10281 }, + "dark-theme", + "Dark Theme", + { "depth": 33, "slug": 10283, "text": 10284 }, + "chart-types", + "Chart Types", + { "depth": 79, "slug": 10286, "text": 10287 }, + "i-chart-data-point-coloring", + "I-Chart Data Point Coloring", + { "depth": 33, "slug": 10289, "text": 10290 }, + "chart-annotations", + "Chart Annotations", + { "depth": 79, "slug": 10292, "text": 10293 }, + "annotation-types", + "Annotation Types", + { "depth": 79, "slug": 10295, "text": 10296 }, + "anchor-types", + "Anchor Types", + { "depth": 79, "slug": 10298, "text": 10299 }, + "interaction-model", + "Interaction Model", + { "depth": 79, "slug": 2002, "text": 2003 }, + { "depth": 79, "slug": 10302, "text": 10303 }, + "data-types", + "Data Types", + { "depth": 79, "slug": 10305, "text": 10306 }, + "chart-base-props", + "Chart Base Props", + { "depth": 79, "slug": 10308, "text": 10309 }, + "hook-useannotations", + "Hook: useAnnotations", + { "depth": 33, "slug": 10311, "text": 10312 }, + "common-elements", + "Common Elements", + { "depth": 79, "slug": 10314, "text": 10315 }, + "spec-limit-lines", + "Spec Limit Lines", + { "depth": 79, "slug": 10317, "text": 10318 }, + "control-lines", + "Control Lines", + { "depth": 79, "slug": 10320, "text": 10321 }, + "limit-annotations-minitab-style", + "Limit Annotations (Minitab-style)", + { "depth": 79, "slug": 10323, "text": 10324 }, + "y-axis-scale-editing", + "Y-Axis Scale Editing", + { "depth": 79, "slug": 10326, "text": 10327 }, + "tooltips", + "Tooltips", + { "depth": 79, "slug": 10329, "text": 10330 }, + "branding-footer", + "Branding Footer", + { "depth": 33, "slug": 7460, "text": 7461 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 10262 }, + [], + "06-design-system/charts/pareto", + { + "id": 10337, + "data": 10339, + "body": 10344, + "filePath": 10345, + "digest": 10346, + "rendered": 10347 + }, + { + "title": 10340, + "editUrl": 16, + "head": 10341, + "template": 18, + "sidebar": 10342, + "pagefind": 16, + "draft": 20 + }, + "Pareto Charts", + [], + { "hidden": 20, "attrs": 10343 }, + {}, + "# Pareto Charts\n\nFrequency analysis and ranking charts with cumulative percentage lines.\n\n## Overview\n\nVariScout provides two Pareto chart variants for different analysis contexts:\n\n| Component | Purpose | Context | Data Source |\n| --------------------- | --------------------------- | ----------------- | -------------------------- |\n| **ParetoChart** | Category frequency analysis | Standard Analysis | Derived from `DataContext` |\n| **PerformancePareto** | Channel Cpk ranking | Performance Mode | `ChannelResult[]` (props) |\n\n**Source:** `packages/charts/src/ParetoChart.tsx` (shared), `packages/charts/src/PerformancePareto.tsx` (shared)\n\n---\n\n## Standard ParetoChart\n\nShows frequency distribution with bars sorted by count (highest first) and a cumulative percentage line. Classic Pareto analysis for identifying the \"vital few\" causes.\n\n### Props Interface\n\n```typescript\ninterface ParetoChartProps {\n /** Factor column name for grouping */\n factor: string;\n /** Parent container width (from withParentSize) */\n parentWidth: number;\n /** Parent container height (from withParentSize) */\n parentHeight: number;\n /** Callback for drill-down on bar click */\n onDrillDown?: (factor: string, value: string) => void;\n /** Show ghost bars comparing filtered to full population */\n showComparison?: boolean;\n /** Callback to toggle comparison view */\n onToggleComparison?: () => void;\n /** Callback to hide the Pareto panel */\n onHide?: () => void;\n /** Callback to open factor selector (not currently used — both apps use visible FactorSelector buttons) */\n onSelectFactor?: () => void;\n /** Callback to open Pareto file upload dialog */\n onUploadPareto?: () => void;\n /** Available factors for selection (determines if \"Select Factor\" button shows) */\n availableFactors?: string[];\n /** Aggregation mode: 'count' (occurrences) or 'value' (sum of outcome) */\n aggregation?: 'count' | 'value';\n /** Callback to toggle aggregation mode */\n onToggleAggregation?: () => void;\n}\n```\n\n### Internal Data Structure\n\nThe component derives Pareto data internally from `DataContext.filteredData`:\n\n```typescript\ninterface ParetoDataPoint {\n key: string; // Category identifier\n value: number; // Count or sum depending on aggregation mode\n cumulative: number; // Running total\n cumulativePercentage: number; // Cumulative % (0-100)\n}\n```\n\nData is automatically sorted by value (descending) with cumulative percentages calculated. In count mode, `value` represents the number of occurrences. In value mode, `value` represents the sum of the outcome column for each category.\n\n### Display Features\n\n- **Bars:** Count or sum per category based on aggregation mode (left Y-axis)\n- **Cumulative line:** Running percentage with circle markers\n- **80% threshold:** Dashed orange reference line\n- **Dual Y-axes:** Count/Sum (left) and Cumulative % (right)\n- **Y-axis label:** \"Count\" in count mode, outcome column name in value mode\n\n### Panel Controls\n\nThe Pareto chart includes optional control buttons in the top-right corner:\n\n| Button | Icon | Condition | Action |\n| ----------------------- | ---------- | ------------------------------------------------------------------------------- | ------------------------------------------------ |\n| **Hide** | EyeOff | `onHide` provided | Hides the Pareto panel from view |\n| **Aggregation** | Hash/Sigma | `onToggleAggregation` provided + `outcome` exists + not using separate data | Toggles count/value mode |\n| **Comparison** | Eye/EyeOff | Filters active + `onToggleComparison` provided + not using separate data | Toggles ghost bar comparison |\n| **Pre-aggregated hint** | Info | `allSingleRow` + count mode + `outcome` exists + `onToggleAggregation` provided | Clickable amber hint that switches to value mode |\n\nWhen both buttons are visible, the hide button appears to the left of the comparison toggle.\n\n### Comparison Mode\n\nWhen filters are active, the comparison toggle shows ghost bars representing the full population distribution:\n\n- **Ghost bars:** Dashed outline, 30% opacity, shows expected count based on overall distribution\n- **Solid bars:** Current filtered data\n- **Tooltip (with comparison):** Shows filtered %, overall %, and difference with directional arrow (↑/↓)\n\nThis helps identify whether a category is over- or under-represented in the filtered subset.\n\n### Aggregation Mode\n\nThe Pareto chart supports two aggregation modes for analyzing category importance:\n\n| Mode | Icon | Y-Axis Label | Bar Values |\n| --------- | ----- | ------------------- | ---------------------------------- |\n| **Count** | Hash | \"Count\" | Number of occurrences per category |\n| **Value** | Sigma | Outcome column name | Sum of outcome column per category |\n\n**Default behavior:** Count mode (shows frequency of each category).\n\n**Value mode:** When enabled, bars represent the sum of the outcome column for each category. This is useful for analyzing total impact (e.g., total cost, total downtime) rather than just frequency.\n\n**Auto-detection:** When every category has exactly 1 row in count mode (pre-aggregated data), `useParetoChartData` sets `allSingleRow: true`. The wrapper renders an amber hint (\"1 row each — try Σ\") that acts as a clickable shortcut to switch to value mode. The hint disappears once value mode is active.\n\n**Toggle button:**\n\n- Appears when `onToggleAggregation` is provided AND an `outcome` column exists\n- Hidden when using separate Pareto data (no underlying data to aggregate)\n- Hash icon (# ) in count mode, Sigma icon (Σ) in value mode\n- Purple highlight when value mode is active\n\n**Tooltip behavior:**\n\n- Count mode: Shows \"Count: N\"\n- Value mode: Shows \"{outcome column name}: N.N\" (one decimal place)\n\n**Y-axis label:**\n\n- Dynamically updates to show \"Count\" or the outcome column name/alias\n- Clickable to edit the column alias (same as other axis labels)\n\n### Empty State\n\nWhen no Pareto data is available (e.g. all categories filtered out), an actionable empty state is shown:\n\n- **Upload** button — visible if `onUploadPareto` provided. Opens ColumnMapping re-edit (factor management).\n- **Hide** button — visible if `onHide` provided. Hides the Pareto card from the dashboard grid.\n\nBoth PWA and Azure wire these two actions. The shared component also accepts `onSelectFactor` for a \"Select Factor\" button, but neither app passes it — factor selection uses the visible `FactorSelector` pill buttons in the card header instead.\n\n### Separate Pareto Data Mode\n\nWhen `paretoMode === 'separate'` in DataContext, the chart uses pre-aggregated data from `separateParetoData` instead of deriving counts from filtered data. An amber info banner indicates this mode: \"Using separate Pareto file (not linked to filters)\". Comparison mode is disabled when using separate data.\n\n### Example\n\n```tsx\nimport ParetoChart from './components/charts/ParetoChart';\n\n// Basic usage - data is derived from DataContext based on factor column\n\u003Cdiv className=\"h-[400px]\">\n \u003CParetoChart\n factor=\"Shift\"\n onDrillDown={(factor, value) => console.log('Drill:', factor, value)}\n />\n\u003C/div>\n\n// With panel controls and comparison\n\u003Cdiv className=\"h-[400px]\">\n \u003CParetoChart\n factor=\"Shift\"\n onDrillDown={handleDrillDown}\n showComparison={showComparison}\n onToggleComparison={() => setShowComparison(prev => !prev)}\n onHide={() => setParetoVisible(false)}\n onUploadPareto={() => setParetoUploadOpen(true)}\n />\n\u003C/div>\n\n// With aggregation mode control (count vs value)\n\u003Cdiv className=\"h-[400px]\">\n \u003CParetoChart\n factor=\"Reason\"\n onDrillDown={handleDrillDown}\n aggregation={paretoAggregation}\n onToggleAggregation={() => setParetoAggregation(\n paretoAggregation === 'count' ? 'value' : 'count'\n )}\n />\n\u003C/div>\n```\n\n### Selection Behavior\n\nClicking a bar either:\n\n1. Calls `onDrillDown(factor, value)` if provided, or\n2. Falls back to toggling the bar in `filters[factor]` via DataContext\n\nSelected bars are highlighted using `chartColors.selected`, unselected bars use `chrome.boxDefault`.\n\n---\n\n## PerformancePareto\n\nShows channels ranked by Cpk (worst first) in Pareto-style bar chart. Helps identify which channels need the most attention.\n\n### Props Interface\n\n```typescript\ninterface PerformanceParetoProps extends BaseChartProps {\n /** Channel results for ranking */\n channels: ChannelResult[];\n /** Currently selected measure/channel */\n selectedMeasure?: string | null;\n /** Maximum number of channels to display (default: 20) */\n maxDisplayed?: number;\n /** Callback when a bar is clicked */\n onChannelClick?: (channelId: string) => void;\n}\n```\n\n### Display Behavior\n\n| State | Display |\n| ---------------- | ---------------------------------------------------- |\n| No selection | Worst N channels by Cpk (ascending sort) |\n| Channel selected | Selected channel highlighted, others dimmed (0.4) |\n| Empty channels | Placeholder: \"No channel performance data available\" |\n\n### Sorting and Limiting\n\nChannels are automatically sorted by Cpk ascending (worst first) using `sortChannels(channels, 'cpk-asc')` from `@variscout/core`. The `maxDisplayed` prop limits display (default: 20).\n\n### Neutral Coloring\n\nAll bars use a uniform blue color (`chartColors.mean`) regardless of Cpk value. This neutral approach lets users focus on the ranking and set their own Cpk targets via PerformanceSetupPanel.\n\n### Reference Lines\n\n| Line | Value | Color | Meaning |\n| -------- | ----- | ----- | ------------------------ |\n| Critical | 1.0 | Red | Minimum acceptable Cpk |\n| Target | 1.33 | Green | Industry standard target |\n\n### Example\n\n```tsx\nimport PerformancePareto from '@variscout/charts/PerformancePareto';\n\n\u003CPerformancePareto\n channels={channelResults}\n selectedMeasure={selectedId}\n maxDisplayed={15}\n onChannelClick={handleChannelSelect}\n/>;\n```\n\n---\n\n## Visual Elements\n\n| Element | Standard ParetoChart | PerformancePareto |\n| ------------------- | ----------------------------------- | -------------------------- |\n| **Bars** | Count or Sum values (descending) | Cpk values (ascending) |\n| **Bar color** | Default or selected | Health-based |\n| **Cumulative line** | Orange with circle markers | Orange with circle markers |\n| **Left Y-axis** | Count or Sum (based on aggregation) | Cpk |\n| **Right Y-axis** | Cumulative % | Cumulative % |\n| **Reference line** | 80% threshold (orange) | Cpk 1.0 & 1.33 (red/green) |\n| **Grid** | Horizontal rows | Horizontal rows |\n| **X-axis labels** | Category names | Channel labels (truncated) |\n\n---\n\n## Data Flow\n\n### Standard ParetoChart (PWA)\n\n```\nDataContext\n | filteredData, rawData, paretoMode, separateParetoData, outcome\n |\nParetoChart (responsive wrapper)\n | aggregation prop determines value computation:\n | - 'count': counts occurrences per category\n | - 'value': sums outcome column per category\n | (or uses separateParetoData if paretoMode === 'separate')\n | Sorts by value (descending)\n | Computes cumulative percentages\n | Calculates full population comparison (if enabled)\n |\nSVG rendering with Visx primitives\n```\n\n### PerformancePareto\n\n```\nDataContext (PWA/Azure)\n | analyzePerformanceData()\nPerformanceDashboard.tsx\n | channels: ChannelResult[]\nPerformancePareto (responsive wrapper)\n | sortChannels(channels, 'cpk-asc')\n | slice(0, maxDisplayed)\nPerformanceParetoBase (renders SVG)\n```\n\n---\n\n## Interactions\n\n### Mobile Tap Interaction\n\nOn mobile (\u003C640px), tapping a Pareto bar opens a `MobileCategorySheet` bottom action sheet (from `@variscout/ui`) showing the category's contribution %. Count and cumulative % display are deferred to a future update. The sheet is triggered by the tap on the bar, with drill-down and highlight (red/amber/green) actions available.\n\n### Click Behavior\n\n```tsx\n// Standard ParetoChart - toggle category selection\nonBarClick={(key) => {\n if (selectedBars.includes(key)) {\n setSelectedBars(bars => bars.filter(b => b !== key));\n } else {\n setSelectedBars(bars => [...bars, key]);\n }\n}}\n\n// PerformancePareto - single channel selection (toggle)\nonChannelClick={(channelId) => {\n setSelectedMeasure(prev => prev === channelId ? null : channelId);\n}}\n```\n\n### Hover Tooltip\n\nStandard ParetoChart tooltip shows:\n\n- Category key\n- Count or Sum value (based on aggregation mode, labeled with column name)\n- Cumulative percentage\n- **When comparison mode active:**\n - Filtered % (current selection)\n - Overall % (full population)\n - Difference with directional arrow (↑/↓/→)\n\nPerformancePareto tooltip shows:\n\n- Channel label\n- Rank (e.g., #1, #2)\n- Cpk value\n- Sample size (n)\n- Health status (colored)\n\n---\n\n## Cross-App Usage\n\n### PWA\n\nThe PWA uses a custom ParetoChart component in `apps/pwa/src/components/charts/ParetoChart.tsx` that derives data from DataContext:\n\n```tsx\nimport ParetoChart from './components/charts/ParetoChart';\n\n// Data is derived from DataContext based on factor column\n\u003Cdiv className=\"h-[400px]\">\n \u003CParetoChart\n factor=\"Shift\"\n onDrillDown={handleDrillDown}\n showComparison={showComparison}\n onToggleComparison={() => setShowComparison(prev => !prev)}\n onHide={() => setParetoVisible(false)}\n />\n\u003C/div>;\n```\n\n### PerformancePareto (Shared)\n\nUse the responsive wrapper from `@variscout/charts` for Performance Mode:\n\n```tsx\nimport PerformancePareto from '@variscout/charts/PerformancePareto';\n\n\u003Cdiv className=\"h-[300px]\">\n \u003CPerformancePareto channels={channels} onChannelClick={handleClick} />\n\u003C/div>;\n```\n\n---\n\n## Colors and Theming\n\n### Bar Colors\n\n| Variant | Condition | Fill Color |\n| ------------------- | ------------ | ------------------------- |\n| Standard (default) | Unselected | `chromeColors.boxDefault` |\n| Standard (selected) | In selection | `chartColors.selected` |\n| Performance | By health | Health color (see above) |\n\n### Theme-Aware Colors\n\nPerformancePareto uses `useChartTheme()` for automatic light/dark adaptation:\n\n```typescript\nconst { chrome } = useChartTheme();\n\n// Chrome colors adapt to theme:\n// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\n```\n\nStandard ParetoChart also uses `useChartTheme()` for theme-aware chrome colors.\n\n### Cumulative Line & Reference Colors\n\n```typescript\n// Cumulative line\nstroke={chartColors.cumulative} // orange-500\n\n// 80% threshold (standard)\nstroke={chartColors.threshold80} // orange-500\n\n// Cpk thresholds (performance)\nstroke={chartColors.fail} // red-500 (1.0)\nstroke={chartColors.pass} // green-500 (1.33)\n```\n\n---\n\n## Responsive Behavior\n\nX-axis labels are rotated 45 degrees when there are more than 10 categories in PerformancePareto. Labels longer than 8 characters are truncated with ellipsis.\n\n---\n\n## Exports\n\n```typescript\n// PWA Standard Pareto (local component, derives data from DataContext)\nimport ParetoChart from './components/charts/ParetoChart';\n\n// Shared Performance Pareto (responsive wrapper)\nimport PerformancePareto from '@variscout/charts/PerformancePareto';\n\n// Base component for manual sizing\nimport { PerformanceParetoBase } from '@variscout/charts/PerformancePareto';\n\n// Types\nimport type { PerformanceParetoProps } from '@variscout/charts';\n```\n\n---\n\n## See Also\n\n- [Overview](./overview.md) - Chart design system overview and selection guide\n- [Colors](./colors.md) - Chart color constants\n- [Responsive](./responsive.md) - Breakpoints and scaling utilities\n- [Hooks](./hooks.md) - useChartLayout, useChartTooltip, useSelectionState\n- [Performance Mode](./performance-mode.md) - Full Performance Mode documentation\n- [Boxplot](./boxplot.md) - Distribution comparison charts", + "src/content/docs/06-design-system/charts/pareto.md", + "8767d2f7b99954c9", + { "html": 10348, "metadata": 10349 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"pareto-charts\">Pareto Charts\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#pareto-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pareto Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Frequency analysis and ranking charts with cumulative percentage lines.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout provides two Pareto chart variants for different analysis contexts:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Context\u003C/th>\u003Cth>Data Source\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>ParetoChart\u003C/strong>\u003C/td>\u003Ctd>Category frequency analysis\u003C/td>\u003Ctd>Standard Analysis\u003C/td>\u003Ctd>Derived from \u003Ccode dir=\"auto\">DataContext\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>PerformancePareto\u003C/strong>\u003C/td>\u003Ctd>Channel Cpk ranking\u003C/td>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ChannelResult[]\u003C/code> (props)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/ParetoChart.tsx\u003C/code> (shared), \u003Ccode dir=\"auto\">packages/charts/src/PerformancePareto.tsx\u003C/code> (shared)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"standard-paretochart\">Standard ParetoChart\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#standard-paretochart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard ParetoChart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shows frequency distribution with bars sorted by count (highest first) and a cumulative percentage line. Classic Pareto analysis for identifying the “vital few” causes.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-interface\">Props Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ParetoChartProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Factor column name for grouping */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Parent container width (from withParentSize) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Parent container height (from withParentSize) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback for drill-down on bar click */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onDrillDown\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">value\u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Show ghost bars comparing filtered to full population */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showComparison\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback to toggle comparison view */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onToggleComparison\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback to hide the Pareto panel */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onHide\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback to open factor selector (not currently used — both apps use visible FactorSelector buttons) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onSelectFactor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback to open Pareto file upload dialog */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onUploadPareto\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Available factors for selection (determines if \"Select Factor\" button shows) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">availableFactors\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Aggregation mode: 'count' (occurrences) or 'value' (sum of outcome) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">aggregation\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">count\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">value\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback to toggle aggregation mode */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onToggleAggregation\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ParetoChartProps { /** Factor column name for grouping */ factor: string; /** Parent container width (from withParentSize) */ parentWidth: number; /** Parent container height (from withParentSize) */ parentHeight: number; /** Callback for drill-down on bar click */ onDrillDown?: (factor: string, value: string) => void; /** Show ghost bars comparing filtered to full population */ showComparison?: boolean; /** Callback to toggle comparison view */ onToggleComparison?: () => void; /** Callback to hide the Pareto panel */ onHide?: () => void; /** Callback to open factor selector (not currently used — both apps use visible FactorSelector buttons) */ onSelectFactor?: () => void; /** Callback to open Pareto file upload dialog */ onUploadPareto?: () => void; /** Available factors for selection (determines if "Select Factor" button shows) */ availableFactors?: string[]; /** Aggregation mode: 'count' (occurrences) or 'value' (sum of outcome) */ aggregation?: 'count' | 'value'; /** Callback to toggle aggregation mode */ onToggleAggregation?: () => void;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"internal-data-structure\">Internal Data Structure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#internal-data-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Internal Data Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The component derives Pareto data internally from \u003Ccode dir=\"auto\">DataContext.filteredData\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ParetoDataPoint {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">key\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Category identifier\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Count or sum depending on aggregation mode\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cumulative\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Running total\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cumulativePercentage\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Cumulative % (0-100)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ParetoDataPoint { key: string; // Category identifier value: number; // Count or sum depending on aggregation mode cumulative: number; // Running total cumulativePercentage: number; // Cumulative % (0-100)}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Data is automatically sorted by value (descending) with cumulative percentages calculated. In count mode, \u003Ccode dir=\"auto\">value\u003C/code> represents the number of occurrences. In value mode, \u003Ccode dir=\"auto\">value\u003C/code> represents the sum of the outcome column for each category.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-features\">Display Features\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Bars:\u003C/strong> Count or sum per category based on aggregation mode (left Y-axis)\u003C/li>\n\u003Cli>\u003Cstrong>Cumulative line:\u003C/strong> Running percentage with circle markers\u003C/li>\n\u003Cli>\u003Cstrong>80% threshold:\u003C/strong> Dashed orange reference line\u003C/li>\n\u003Cli>\u003Cstrong>Dual Y-axes:\u003C/strong> Count/Sum (left) and Cumulative % (right)\u003C/li>\n\u003Cli>\u003Cstrong>Y-axis label:\u003C/strong> “Count” in count mode, outcome column name in value mode\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"panel-controls\">Panel Controls\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#panel-controls\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Panel Controls”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Pareto chart includes optional control buttons in the top-right corner:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Button\u003C/th>\u003Cth>Icon\u003C/th>\u003Cth>Condition\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Hide\u003C/strong>\u003C/td>\u003Ctd>EyeOff\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">onHide\u003C/code> provided\u003C/td>\u003Ctd>Hides the Pareto panel from view\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Aggregation\u003C/strong>\u003C/td>\u003Ctd>Hash/Sigma\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">onToggleAggregation\u003C/code> provided + \u003Ccode dir=\"auto\">outcome\u003C/code> exists + not using separate data\u003C/td>\u003Ctd>Toggles count/value mode\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Comparison\u003C/strong>\u003C/td>\u003Ctd>Eye/EyeOff\u003C/td>\u003Ctd>Filters active + \u003Ccode dir=\"auto\">onToggleComparison\u003C/code> provided + not using separate data\u003C/td>\u003Ctd>Toggles ghost bar comparison\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pre-aggregated hint\u003C/strong>\u003C/td>\u003Ctd>Info\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">allSingleRow\u003C/code> + count mode + \u003Ccode dir=\"auto\">outcome\u003C/code> exists + \u003Ccode dir=\"auto\">onToggleAggregation\u003C/code> provided\u003C/td>\u003Ctd>Clickable amber hint that switches to value mode\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>When both buttons are visible, the hide button appears to the left of the comparison toggle.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"comparison-mode\">Comparison Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#comparison-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Comparison Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When filters are active, the comparison toggle shows ghost bars representing the full population distribution:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Ghost bars:\u003C/strong> Dashed outline, 30% opacity, shows expected count based on overall distribution\u003C/li>\n\u003Cli>\u003Cstrong>Solid bars:\u003C/strong> Current filtered data\u003C/li>\n\u003Cli>\u003Cstrong>Tooltip (with comparison):\u003C/strong> Shows filtered %, overall %, and difference with directional arrow (↑/↓)\u003C/li>\n\u003C/ul>\n\u003Cp>This helps identify whether a category is over- or under-represented in the filtered subset.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"aggregation-mode\">Aggregation Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#aggregation-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Aggregation Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Pareto chart supports two aggregation modes for analyzing category importance:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Mode\u003C/th>\u003Cth>Icon\u003C/th>\u003Cth>Y-Axis Label\u003C/th>\u003Cth>Bar Values\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Count\u003C/strong>\u003C/td>\u003Ctd>Hash\u003C/td>\u003Ctd>”Count”\u003C/td>\u003Ctd>Number of occurrences per category\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Value\u003C/strong>\u003C/td>\u003Ctd>Sigma\u003C/td>\u003Ctd>Outcome column name\u003C/td>\u003Ctd>Sum of outcome column per category\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Default behavior:\u003C/strong> Count mode (shows frequency of each category).\u003C/p>\n\u003Cp>\u003Cstrong>Value mode:\u003C/strong> When enabled, bars represent the sum of the outcome column for each category. This is useful for analyzing total impact (e.g., total cost, total downtime) rather than just frequency.\u003C/p>\n\u003Cp>\u003Cstrong>Auto-detection:\u003C/strong> When every category has exactly 1 row in count mode (pre-aggregated data), \u003Ccode dir=\"auto\">useParetoChartData\u003C/code> sets \u003Ccode dir=\"auto\">allSingleRow: true\u003C/code>. The wrapper renders an amber hint (“1 row each — try Σ”) that acts as a clickable shortcut to switch to value mode. The hint disappears once value mode is active.\u003C/p>\n\u003Cp>\u003Cstrong>Toggle button:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Appears when \u003Ccode dir=\"auto\">onToggleAggregation\u003C/code> is provided AND an \u003Ccode dir=\"auto\">outcome\u003C/code> column exists\u003C/li>\n\u003Cli>Hidden when using separate Pareto data (no underlying data to aggregate)\u003C/li>\n\u003Cli>Hash icon (# ) in count mode, Sigma icon (Σ) in value mode\u003C/li>\n\u003Cli>Purple highlight when value mode is active\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Tooltip behavior:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Count mode: Shows “Count: N”\u003C/li>\n\u003Cli>Value mode: Shows “{outcome column name}: N.N” (one decimal place)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Y-axis label:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Dynamically updates to show “Count” or the outcome column name/alias\u003C/li>\n\u003Cli>Clickable to edit the column alias (same as other axis labels)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"empty-state\">Empty State\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#empty-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Empty State”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When no Pareto data is available (e.g. all categories filtered out), an actionable empty state is shown:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Upload\u003C/strong> button — visible if \u003Ccode dir=\"auto\">onUploadPareto\u003C/code> provided. Opens ColumnMapping re-edit (factor management).\u003C/li>\n\u003Cli>\u003Cstrong>Hide\u003C/strong> button — visible if \u003Ccode dir=\"auto\">onHide\u003C/code> provided. Hides the Pareto card from the dashboard grid.\u003C/li>\n\u003C/ul>\n\u003Cp>Both PWA and Azure wire these two actions. The shared component also accepts \u003Ccode dir=\"auto\">onSelectFactor\u003C/code> for a “Select Factor” button, but neither app passes it — factor selection uses the visible \u003Ccode dir=\"auto\">FactorSelector\u003C/code> pill buttons in the card header instead.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"separate-pareto-data-mode\">Separate Pareto Data Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#separate-pareto-data-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Separate Pareto Data Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When \u003Ccode dir=\"auto\">paretoMode === 'separate'\u003C/code> in DataContext, the chart uses pre-aggregated data from \u003Ccode dir=\"auto\">separateParetoData\u003C/code> instead of deriving counts from filtered data. An amber info banner indicates this mode: “Using separate Pareto file (not linked to filters)”. Comparison mode is disabled when using separate data.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ParetoChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./components/charts/ParetoChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Basic usage - data is derived from DataContext based on factor column\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[400px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ParetoChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">factor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onDrillDown\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">console\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">log\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Drill:\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// With panel controls and comparison\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[400px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ParetoChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">factor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onDrillDown\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleDrillDown\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">showComparison\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showComparison\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onToggleComparison\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setShowComparison\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">prev\u003C/span>\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">!\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">prev)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onHide\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setParetoVisible\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onUploadPareto\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setParetoUploadOpen\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// With aggregation mode control (count vs value)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[400px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ParetoChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">factor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Reason\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onDrillDown\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleDrillDown\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">aggregation\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">paretoAggregation\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onToggleAggregation\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setParetoAggregation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">paretoAggregation\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">===\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">count\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">value\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">count\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import ParetoChart from './components/charts/ParetoChart';// Basic usage - data is derived from DataContext based on factor column\u003Cdiv className="h-[400px]"> \u003CParetoChart factor="Shift" onDrillDown={(factor, value) => console.log('Drill:', factor, value)} />\u003C/div>// With panel controls and comparison\u003Cdiv className="h-[400px]"> \u003CParetoChart factor="Shift" onDrillDown={handleDrillDown} showComparison={showComparison} onToggleComparison={() => setShowComparison(prev => !prev)} onHide={() => setParetoVisible(false)} onUploadPareto={() => setParetoUploadOpen(true)} />\u003C/div>// With aggregation mode control (count vs value)\u003Cdiv className="h-[400px]"> \u003CParetoChart factor="Reason" onDrillDown={handleDrillDown} aggregation={paretoAggregation} onToggleAggregation={() => setParetoAggregation( paretoAggregation === 'count' ? 'value' : 'count' )} />\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"selection-behavior\">Selection Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#selection-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Selection Behavior”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Clicking a bar either:\u003C/p>\n\u003Col>\n\u003Cli>Calls \u003Ccode dir=\"auto\">onDrillDown(factor, value)\u003C/code> if provided, or\u003C/li>\n\u003Cli>Falls back to toggling the bar in \u003Ccode dir=\"auto\">filters[factor]\u003C/code> via DataContext\u003C/li>\n\u003C/ol>\n\u003Cp>Selected bars are highlighted using \u003Ccode dir=\"auto\">chartColors.selected\u003C/code>, unselected bars use \u003Ccode dir=\"auto\">chrome.boxDefault\u003C/code>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performancepareto\">PerformancePareto\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performancepareto\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformancePareto”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shows channels ranked by Cpk (worst first) in Pareto-style bar chart. Helps identify which channels need the most attention.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-interface-1\">Props Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-interface-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceParetoProps \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extends\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">BaseChartProps\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Channel results for ranking */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChannelResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Currently selected measure/channel */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Maximum number of channels to display (default: 20) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">maxDisplayed\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Callback when a bar is clicked */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">channelId\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface PerformanceParetoProps extends BaseChartProps { /** Channel results for ranking */ channels: ChannelResult[]; /** Currently selected measure/channel */ selectedMeasure?: string | null; /** Maximum number of channels to display (default: 20) */ maxDisplayed?: number; /** Callback when a bar is clicked */ onChannelClick?: (channelId: string) => void;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-behavior\">Display Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Behavior”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>State\u003C/th>\u003Cth>Display\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>No selection\u003C/td>\u003Ctd>Worst N channels by Cpk (ascending sort)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Channel selected\u003C/td>\u003Ctd>Selected channel highlighted, others dimmed (0.4)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Empty channels\u003C/td>\u003Ctd>Placeholder: “No channel performance data available”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"sorting-and-limiting\">Sorting and Limiting\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#sorting-and-limiting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sorting and Limiting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Channels are automatically sorted by Cpk ascending (worst first) using \u003Ccode dir=\"auto\">sortChannels(channels, 'cpk-asc')\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>. The \u003Ccode dir=\"auto\">maxDisplayed\u003C/code> prop limits display (default: 20).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"neutral-coloring\">Neutral Coloring\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#neutral-coloring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Neutral Coloring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All bars use a uniform blue color (\u003Ccode dir=\"auto\">chartColors.mean\u003C/code>) regardless of Cpk value. This neutral approach lets users focus on the ranking and set their own Cpk targets via PerformanceSetupPanel.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"reference-lines\">Reference Lines\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#reference-lines\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reference Lines”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Line\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Critical\u003C/td>\u003Ctd>1.0\u003C/td>\u003Ctd>Red\u003C/td>\u003Ctd>Minimum acceptable Cpk\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Target\u003C/td>\u003Ctd>1.33\u003C/td>\u003Ctd>Green\u003C/td>\u003Ctd>Industry standard target\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-1\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformancePareto \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformancePareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformancePareto\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channelResults\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedId\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">maxDisplayed\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">15\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleChannelSelect\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import PerformancePareto from '@variscout/charts/PerformancePareto';\u003CPerformancePareto channels={channelResults} selectedMeasure={selectedId} maxDisplayed={15} onChannelClick={handleChannelSelect}/>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visual-elements\">Visual Elements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visual-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Elements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Standard ParetoChart\u003C/th>\u003Cth>PerformancePareto\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Bars\u003C/strong>\u003C/td>\u003Ctd>Count or Sum values (descending)\u003C/td>\u003Ctd>Cpk values (ascending)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Bar color\u003C/strong>\u003C/td>\u003Ctd>Default or selected\u003C/td>\u003Ctd>Health-based\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Cumulative line\u003C/strong>\u003C/td>\u003Ctd>Orange with circle markers\u003C/td>\u003Ctd>Orange with circle markers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Left Y-axis\u003C/strong>\u003C/td>\u003Ctd>Count or Sum (based on aggregation)\u003C/td>\u003Ctd>Cpk\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Right Y-axis\u003C/strong>\u003C/td>\u003Ctd>Cumulative %\u003C/td>\u003Ctd>Cumulative %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Reference line\u003C/strong>\u003C/td>\u003Ctd>80% threshold (orange)\u003C/td>\u003Ctd>Cpk 1.0 & 1.33 (red/green)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Grid\u003C/strong>\u003C/td>\u003Ctd>Horizontal rows\u003C/td>\u003Ctd>Horizontal rows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>X-axis labels\u003C/strong>\u003C/td>\u003Ctd>Category names\u003C/td>\u003Ctd>Channel labels (truncated)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-flow\">Data Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-paretochart-pwa\">Standard ParetoChart (PWA)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-paretochart-pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard ParetoChart (PWA)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| filteredData, rawData, paretoMode, separateParetoData, outcome\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">ParetoChart (responsive wrapper)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| aggregation prop determines value computation:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| - 'count': counts occurrences per category\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| - 'value': sums outcome column per category\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| (or uses separateParetoData if paretoMode === 'separate')\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| Sorts by value (descending)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| Computes cumulative percentages\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| Calculates full population comparison (if enabled)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">SVG rendering with Visx primitives\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DataContext | filteredData, rawData, paretoMode, separateParetoData, outcome |ParetoChart (responsive wrapper) | aggregation prop determines value computation: | - 'count': counts occurrences per category | - 'value': sums outcome column per category | (or uses separateParetoData if paretoMode === 'separate') | Sorts by value (descending) | Computes cumulative percentages | Calculates full population comparison (if enabled) |SVG rendering with Visx primitives\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performancepareto-1\">PerformancePareto\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performancepareto-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformancePareto”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext (PWA/Azure)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| analyzePerformanceData()\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceDashboard.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| channels: ChannelResult[]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformancePareto (responsive wrapper)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| sortChannels(channels, 'cpk-asc')\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| slice(0, maxDisplayed)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceParetoBase (renders SVG)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DataContext (PWA/Azure) | analyzePerformanceData()PerformanceDashboard.tsx | channels: ChannelResult[]PerformancePareto (responsive wrapper) | sortChannels(channels, 'cpk-asc') | slice(0, maxDisplayed)PerformanceParetoBase (renders SVG)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interactions\">Interactions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interactions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interactions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mobile-tap-interaction\">Mobile Tap Interaction\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-tap-interaction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Tap Interaction”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>On mobile (<640px), tapping a Pareto bar opens a \u003Ccode dir=\"auto\">MobileCategorySheet\u003C/code> bottom action sheet (from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>) showing the category’s contribution %. Count and cumulative % display are deferred to a future update. The sheet is triggered by the tap on the bar, with drill-down and highlight (red/amber/green) actions available.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"click-behavior\">Click Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#click-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Click Behavior”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard ParetoChart - toggle category selection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onBarClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{(key) => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (selectedBars\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">includes\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(key)) {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedBars\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">bars\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> bars\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filter\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">b\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> b \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!==\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> key));\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">else\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedBars\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">bars\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">bars, key]);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PerformancePareto - single channel selection (toggle)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{(channelId) => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedMeasure\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">prev\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> prev \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> channelId \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> channelId);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Standard ParetoChart - toggle category selectiononBarClick={(key) => { if (selectedBars.includes(key)) { setSelectedBars(bars => bars.filter(b => b !== key)); } else { setSelectedBars(bars => [...bars, key]); }}}// PerformancePareto - single channel selection (toggle)onChannelClick={(channelId) => { setSelectedMeasure(prev => prev === channelId ? null : channelId);}}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"hover-tooltip\">Hover Tooltip\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#hover-tooltip\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hover Tooltip”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standard ParetoChart tooltip shows:\u003C/p>\n\u003Cul>\n\u003Cli>Category key\u003C/li>\n\u003Cli>Count or Sum value (based on aggregation mode, labeled with column name)\u003C/li>\n\u003Cli>Cumulative percentage\u003C/li>\n\u003Cli>\u003Cstrong>When comparison mode active:\u003C/strong>\n\u003Cul>\n\u003Cli>Filtered % (current selection)\u003C/li>\n\u003Cli>Overall % (full population)\u003C/li>\n\u003Cli>Difference with directional arrow (↑/↓/→)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ul>\n\u003Cp>PerformancePareto tooltip shows:\u003C/p>\n\u003Cul>\n\u003Cli>Channel label\u003C/li>\n\u003Cli>Rank (e.g., #1, #2)\u003C/li>\n\u003Cli>Cpk value\u003C/li>\n\u003Cli>Sample size (n)\u003C/li>\n\u003Cli>Health status (colored)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-app-usage\">Cross-App Usage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-app-usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-App Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa\">PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA uses a custom ParetoChart component in \u003Ccode dir=\"auto\">apps/pwa/src/components/charts/ParetoChart.tsx\u003C/code> that derives data from DataContext:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ParetoChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./components/charts/ParetoChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Data is derived from DataContext based on factor column\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[400px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ParetoChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">factor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Shift\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onDrillDown\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleDrillDown\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">showComparison\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showComparison\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onToggleComparison\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setShowComparison\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">prev\u003C/span>\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">!\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">prev)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onHide\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setParetoVisible\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import ParetoChart from './components/charts/ParetoChart';// Data is derived from DataContext based on factor column\u003Cdiv className="h-[400px]"> \u003CParetoChart factor="Shift" onDrillDown={handleDrillDown} showComparison={showComparison} onToggleComparison={() => setShowComparison(prev => !prev)} onHide={() => setParetoVisible(false)} />\u003C/div>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"performancepareto-shared\">PerformancePareto (Shared)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#performancepareto-shared\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformancePareto (Shared)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use the responsive wrapper from \u003Ccode dir=\"auto\">@variscout/charts\u003C/code> for Performance Mode:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformancePareto \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformancePareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[300px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformancePareto\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleClick\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import PerformancePareto from '@variscout/charts/PerformancePareto';\u003Cdiv className="h-[300px]"> \u003CPerformancePareto channels={channels} onChannelClick={handleClick} />\u003C/div>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"colors-and-theming\">Colors and Theming\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#colors-and-theming\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Colors and Theming”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"bar-colors\">Bar Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#bar-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Bar Colors”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variant\u003C/th>\u003Cth>Condition\u003C/th>\u003Cth>Fill Color\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Standard (default)\u003C/td>\u003Ctd>Unselected\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chromeColors.boxDefault\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Standard (selected)\u003C/td>\u003Ctd>In selection\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.selected\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance\u003C/td>\u003Ctd>By health\u003C/td>\u003Ctd>Health color (see above)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"theme-aware-colors\">Theme-Aware Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#theme-aware-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theme-Aware Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>PerformancePareto uses \u003Ccode dir=\"auto\">useChartTheme()\u003C/code> for automatic light/dark adaptation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chrome colors adapt to theme:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const { chrome } = useChartTheme();// Chrome colors adapt to theme:// chrome.gridLine, chrome.axisPrimary, chrome.labelPrimary, etc.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Standard ParetoChart also uses \u003Ccode dir=\"auto\">useChartTheme()\u003C/code> for theme-aware chrome colors.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cumulative-line--reference-colors\">Cumulative Line & Reference Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cumulative-line--reference-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cumulative Line & Reference Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Cumulative line\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.cumulative} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// orange-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 80% threshold (standard)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.threshold80} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// orange-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Cpk thresholds (performance)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.fail} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// red-500 (1.0)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.pass} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// green-500 (1.33)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Cumulative linestroke={chartColors.cumulative} // orange-500// 80% threshold (standard)stroke={chartColors.threshold80} // orange-500// Cpk thresholds (performance)stroke={chartColors.fail} // red-500 (1.0)stroke={chartColors.pass} // green-500 (1.33)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"responsive-behavior\">Responsive Behavior\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#responsive-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Responsive Behavior”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>X-axis labels are rotated 45 degrees when there are more than 10 categories in PerformancePareto. Labels longer than 8 characters are truncated with ellipsis.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"exports\">Exports\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#exports\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PWA Standard Pareto (local component, derives data from DataContext)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ParetoChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./components/charts/ParetoChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Shared Performance Pareto (responsive wrapper)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformancePareto \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformancePareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Base component for manual sizing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { PerformanceParetoBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformancePareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Types\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { PerformanceParetoProps } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// PWA Standard Pareto (local component, derives data from DataContext)import ParetoChart from './components/charts/ParetoChart';// Shared Performance Pareto (responsive wrapper)import PerformancePareto from '@variscout/charts/PerformancePareto';// Base component for manual sizingimport { PerformanceParetoBase } from '@variscout/charts/PerformancePareto';// Typesimport type { PerformanceParetoProps } from '@variscout/charts';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview and selection guide\u003C/li>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - Chart color constants\u003C/li>\n\u003Cli>\u003Ca href=\"./responsive.md\">Responsive\u003C/a> - Breakpoints and scaling utilities\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - useChartLayout, useChartTooltip, useSelectionState\u003C/li>\n\u003Cli>\u003Ca href=\"./performance-mode.md\">Performance Mode\u003C/a> - Full Performance Mode documentation\u003C/li>\n\u003Cli>\u003Ca href=\"./boxplot.md\">Boxplot\u003C/a> - Distribution comparison charts\u003C/li>\n\u003C/ul>", + { + "headings": 10350, + "localImagePaths": 10425, + "remoteImagePaths": 10426, + "frontmatter": 10427, + "imagePaths": 10428 + }, + [ + 10351, 10353, 10354, 10357, 10358, 10361, 10364, 10367, 10370, 10373, 10376, 10379, 10380, + 10383, 10386, 10387, 10388, 10391, 10394, 10397, 10398, 10399, 10400, 10403, 10405, 10406, + 10407, 10408, 10409, 10410, 10411, 10414, 10415, 10416, 10417, 10420, 10423, 10424 + ], + { "depth": 30, "slug": 10352, "text": 10340 }, + "pareto-charts", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 10355, "text": 10356 }, + "standard-paretochart", + "Standard ParetoChart", + { "depth": 79, "slug": 9737, "text": 9738 }, + { "depth": 79, "slug": 10359, "text": 10360 }, + "internal-data-structure", + "Internal Data Structure", + { "depth": 79, "slug": 10362, "text": 10363 }, + "display-features", + "Display Features", + { "depth": 79, "slug": 10365, "text": 10366 }, + "panel-controls", + "Panel Controls", + { "depth": 79, "slug": 10368, "text": 10369 }, + "comparison-mode", + "Comparison Mode", + { "depth": 79, "slug": 10371, "text": 10372 }, + "aggregation-mode", + "Aggregation Mode", + { "depth": 79, "slug": 10374, "text": 10375 }, + "empty-state", + "Empty State", + { "depth": 79, "slug": 10377, "text": 10378 }, + "separate-pareto-data-mode", + "Separate Pareto Data Mode", + { "depth": 79, "slug": 7536, "text": 7537 }, + { "depth": 79, "slug": 10381, "text": 10382 }, + "selection-behavior", + "Selection Behavior", + { "depth": 33, "slug": 10384, "text": 10385 }, + "performancepareto", + "PerformancePareto", + { "depth": 79, "slug": 9764, "text": 9738 }, + { "depth": 79, "slug": 9766, "text": 9767 }, + { "depth": 79, "slug": 10389, "text": 10390 }, + "sorting-and-limiting", + "Sorting and Limiting", + { "depth": 79, "slug": 10392, "text": 10393 }, + "neutral-coloring", + "Neutral Coloring", + { "depth": 79, "slug": 10395, "text": 10396 }, + "reference-lines", + "Reference Lines", + { "depth": 79, "slug": 9894, "text": 7537 }, + { "depth": 33, "slug": 9896, "text": 9897 }, + { "depth": 33, "slug": 9776, "text": 9777 }, + { "depth": 79, "slug": 10401, "text": 10402 }, + "standard-paretochart-pwa", + "Standard ParetoChart (PWA)", + { "depth": 79, "slug": 10404, "text": 10385 }, + "performancepareto-1", + { "depth": 33, "slug": 9783, "text": 9784 }, + { "depth": 79, "slug": 9789, "text": 9790 }, + { "depth": 79, "slug": 9792, "text": 9793 }, + { "depth": 79, "slug": 9795, "text": 9796 }, + { "depth": 33, "slug": 9801, "text": 9802 }, + { "depth": 79, "slug": 5545, "text": 5546 }, + { "depth": 79, "slug": 10412, "text": 10413 }, + "performancepareto-shared", + "PerformancePareto (Shared)", + { "depth": 33, "slug": 9807, "text": 9808 }, + { "depth": 79, "slug": 9907, "text": 9908 }, + { "depth": 79, "slug": 9813, "text": 9814 }, + { "depth": 79, "slug": 10418, "text": 10419 }, + "cumulative-line--reference-colors", + "Cumulative Line & Reference Colors", + { "depth": 33, "slug": 10421, "text": 10422 }, + "responsive-behavior", + "Responsive Behavior", + { "depth": 33, "slug": 1723, "text": 1724 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 10340 }, + [], + "06-design-system/charts/probability-plot", + { + "id": 10429, + "data": 10431, + "body": 10435, + "filePath": 10436, + "digest": 10437, + "rendered": 10438 + }, + { + "title": 581, + "editUrl": 16, + "head": 10432, + "template": 18, + "sidebar": 10433, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 10434 }, + {}, + "# Probability Plot\n\nNormality assessment chart with 95% confidence intervals following Minitab conventions.\n\n## Overview\n\nThe ProbabilityPlot component displays data against a theoretical normal distribution to assess normality. Points falling along the fitted line indicate normally distributed data.\n\n| Component | Purpose | Data Source |\n| ------------------- | -------------------- | ----------- |\n| **ProbabilityPlot** | Normality assessment | `number[]` |\n\n**Source:** `packages/charts/src/ProbabilityPlot.tsx`\n\n---\n\n## ProbabilityPlot\n\nShows data points plotted against expected percentiles with 95% confidence interval bands. Uses probability-transformed Y-axis (inverse normal CDF) following Minitab conventions.\n\n### Props Interface\n\n```typescript\ninterface ProbabilityPlotProps extends BaseChartProps {\n /** Raw numeric values */\n data: number[];\n /** Mean for theoretical line */\n mean: number;\n /** Standard deviation for theoretical line */\n stdDev: number;\n /** Optional custom margin override */\n marginOverride?: { top: number; right: number; bottom: number; left: number };\n /** Optional custom font sizes override */\n fontsOverride?: ChartFonts;\n /** Optional signature element to render */\n signatureElement?: React.ReactNode;\n}\n```\n\n### Example\n\n```tsx\nimport ProbabilityPlot from '@variscout/charts/ProbabilityPlot';\n\n\u003CProbabilityPlot data={measurementValues} mean={stats.mean} stdDev={stats.stdDev} />;\n```\n\n---\n\n## Visual Elements\n\n| Element | Description |\n| -------------------- | ---------------------------------------------------------------- |\n| **Data points** | Green circles with white stroke |\n| **Fitted line** | Blue straight line (theoretical normal) |\n| **CI bands** | Light blue shaded area with dashed boundaries |\n| **Grid** | Horizontal lines at standard percentile positions |\n| **Y-axis (Percent)** | Probability-transformed scale (1, 5, 10, 25, 50, 75, 90, 95, 99) |\n| **X-axis** | Data values |\n\n### Probability Percentile Scale\n\nThe Y-axis uses standard percentile tick values:\n\n- Full display: 1, 5, 10, 25, 50, 75, 90, 95, 99%\n- Compact display (\u003C 300px): 5, 25, 50, 75, 95%\n\nThese percentiles are transformed using the inverse normal CDF (z-scores) to create a probability-scaled axis.\n\n---\n\n## Confidence Interval Bands\n\nThe 95% CI bands widen at the extremes (low and high percentiles) following MLE variance propagation:\n\n```typescript\nfunction calculateCIWidth(\n p: number, // percentile as decimal (0-1)\n n: number, // sample size\n stdDev: number // sample standard deviation\n): number {\n const z = normalQuantile(p);\n\n // Variance includes:\n // 1. Uncertainty in mean estimation: σ²/n\n // 2. Uncertainty in std dev propagated through z: z² * σ²/(2n)\n const varPercentile = (stdDev² / n) * (1 + z² / 2);\n const sePercentile = Math.sqrt(varPercentile);\n\n // 95% CI half-width\n return 1.96 * sePercentile;\n}\n```\n\nThis creates smooth, symmetric CI bands that naturally widen at distribution tails.\n\n---\n\n## Interpretation\n\n| Pattern | Meaning |\n| -------------------------- | ---------------------------- |\n| Points on fitted line | Data is normally distributed |\n| Points curve away at ends | Heavy tails (leptokurtic) |\n| Points curve toward center | Light tails (platykurtic) |\n| S-shaped deviation | Skewed distribution |\n| Points outside CI bands | Significant non-normality |\n\n---\n\n## Data Flow\n\n```\nDataContext (PWA/Azure)\n |\nStatsPanel.tsx\n | data: number[], mean, stdDev from stats\nProbabilityPlot (responsive wrapper)\n | calculateProbabilityPlotData() from @variscout/core\n | normalQuantile() for z-scores\nProbabilityPlotBase (renders SVG)\n```\n\n### Plot Data Calculation\n\nUses `calculateProbabilityPlotData()` from `@variscout/core`:\n\n```typescript\n// For each data point:\n// 1. Sort data ascending\n// 2. Calculate expected percentile using Benard formula: (i - 0.3) / (n + 0.4)\n// 3. Return { value, expectedPercentile }\n```\n\n---\n\n## Cross-App Usage\n\n### PWA and Azure\n\nUse the responsive wrapper (auto-sizing with `withParentSize`):\n\n```tsx\nimport ProbabilityPlot from '@variscout/charts/ProbabilityPlot';\n\n\u003Cdiv className=\"h-[400px]\">\n \u003CProbabilityPlot data={values} mean={stats.mean} stdDev={stats.stdDev} />\n\u003C/div>;\n```\n\n### Custom Margins and Fonts\n\n```tsx\n\u003CProbabilityPlot\n data={values}\n mean={mean}\n stdDev={stdDev}\n marginOverride={{ top: 20, right: 30, bottom: 50, left: 60 }}\n fontsOverride={{ tickLabel: 10, axisLabel: 12, statLabel: 10, tooltipText: 11, brandingText: 9 }}\n/>\n```\n\n---\n\n## Colors and Theming\n\n### Point Colors\n\nAll data points use `chartColors.pass` (green) with white stroke.\n\n### Line Colors\n\n```typescript\n// Fitted distribution line\nstroke={chartColors.linear} // blue-500\n\n// CI boundary lines\nstroke={chromeColors.labelMuted} // gray, dashed\n```\n\n### CI Band Fill\n\n```typescript\nfill={chromeColors.ciband} // blue-500 with 15% opacity\n```\n\n### Theme Colors\n\nUses hardcoded dark theme colors from `chromeColors`:\n\n- Grid: `chromeColors.tooltipBorder`\n- Labels: `chromeColors.labelSecondary`\n- Axes: `chromeColors.labelMuted`\n\n---\n\n## Responsive Behavior\n\n| Width Range | Y-Axis Label | Tick Percentiles | X-Axis Ticks |\n| ----------- | ------------ | -------------------------------- | ------------ |\n| \u003C 300px | Hidden | 5, 25, 50, 75, 95 (compact) | 4 |\n| >= 300px | \"Percent\" | 1, 5, 10, 25, 50, 75, 90, 95, 99 | 6 |\n\n---\n\n## Mathematical Background\n\n### Probability Transformation\n\nThe Y-axis uses the inverse normal CDF (quantile function):\n\n```typescript\nconst z = normalQuantile(p); // Convert percentile to z-score\n```\n\nThis transformation makes normally distributed data appear as a straight line because:\n\n- For normal data: X_p = μ + z_p × σ\n- When plotted with z on Y-axis and X on X-axis, the relationship is linear\n\n### Fitted Line Points\n\nThe fitted line represents the theoretical normal distribution:\n\n```typescript\nconst fittedLineWithCI = percentiles.map(p => {\n const pDecimal = p / 100;\n const z = normalQuantile(pDecimal);\n const expectedX = mean + z * stdDev; // Theoretical value\n const ciWidth = calculateCIWidth(pDecimal, n, stdDev);\n\n return {\n z,\n x: expectedX,\n lowerCI: expectedX - ciWidth,\n upperCI: expectedX + ciWidth,\n };\n});\n```\n\n---\n\n## Signature Element\n\nAn optional `signatureElement` prop allows rendering custom content (like a logo or signature) within the chart:\n\n```tsx\n\u003CProbabilityPlot data={values} mean={mean} stdDev={stdDev} signatureElement={\u003CCustomSignature />} />\n```\n\n---\n\n## Exports\n\n```typescript\n// Responsive wrapper (auto-sizing)\nimport ProbabilityPlot from '@variscout/charts/ProbabilityPlot';\n\n// Base component (manual sizing)\nimport { ProbabilityPlotBase } from '@variscout/charts/ProbabilityPlot';\n\n// Types\nimport type { ProbabilityPlotProps } from '@variscout/charts';\n\n// Core functions\nimport { calculateProbabilityPlotData, normalQuantile } from '@variscout/core';\n```\n\n---\n\n## See Also\n\n- [Overview](./overview.md) - Chart design system overview and selection guide\n- [Colors](./colors.md) - Chart color constants\n- [Responsive](./responsive.md) - Breakpoints and scaling utilities\n- [Hooks](./hooks.md) - useChartLayout\n- [Capability](./capability.md) - Distribution histograms", + "src/content/docs/06-design-system/charts/probability-plot.md", + "179e2a9f4b4cbd66", + { "html": 10439, "metadata": 10440 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"probability-plot\">Probability Plot\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#probability-plot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Probability Plot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Normality assessment chart with 95% confidence intervals following Minitab conventions.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The ProbabilityPlot component displays data against a theoretical normal distribution to assess normality. Points falling along the fitted line indicate normally distributed data.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Data Source\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>ProbabilityPlot\u003C/strong>\u003C/td>\u003Ctd>Normality assessment\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number[]\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/ProbabilityPlot.tsx\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"probabilityplot\">ProbabilityPlot\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#probabilityplot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ProbabilityPlot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shows data points plotted against expected percentiles with 95% confidence interval bands. Uses probability-transformed Y-axis (inverse normal CDF) following Minitab conventions.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-interface\">Props Interface\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ProbabilityPlotProps \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">extends\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">BaseChartProps\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Raw numeric values */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Mean for theoretical line */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Standard deviation for theoretical line */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stdDev\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Optional custom margin override */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">marginOverride\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { top\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; right\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; bottom\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; left\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> };\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Optional custom font sizes override */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fontsOverride\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartFonts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Optional signature element to render */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">signatureElement\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ReactNode\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ProbabilityPlotProps extends BaseChartProps { /** Raw numeric values */ data: number[]; /** Mean for theoretical line */ mean: number; /** Standard deviation for theoretical line */ stdDev: number; /** Optional custom margin override */ marginOverride?: { top: number; right: number; bottom: number; left: number }; /** Optional custom font sizes override */ fontsOverride?: ChartFonts; /** Optional signature element to render */ signatureElement?: React.ReactNode;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ProbabilityPlot \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/ProbabilityPlot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ProbabilityPlot\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measurementValues\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">mean\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mean\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stdDev\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">stdDev\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import ProbabilityPlot from '@variscout/charts/ProbabilityPlot';\u003CProbabilityPlot data={measurementValues} mean={stats.mean} stdDev={stats.stdDev} />;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visual-elements\">Visual Elements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visual-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Elements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Data points\u003C/strong>\u003C/td>\u003Ctd>Green circles with white stroke\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Fitted line\u003C/strong>\u003C/td>\u003Ctd>Blue straight line (theoretical normal)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>CI bands\u003C/strong>\u003C/td>\u003Ctd>Light blue shaded area with dashed boundaries\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Grid\u003C/strong>\u003C/td>\u003Ctd>Horizontal lines at standard percentile positions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Y-axis (Percent)\u003C/strong>\u003C/td>\u003Ctd>Probability-transformed scale (1, 5, 10, 25, 50, 75, 90, 95, 99)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>X-axis\u003C/strong>\u003C/td>\u003Ctd>Data values\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"probability-percentile-scale\">Probability Percentile Scale\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#probability-percentile-scale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Probability Percentile Scale”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Y-axis uses standard percentile tick values:\u003C/p>\n\u003Cul>\n\u003Cli>Full display: 1, 5, 10, 25, 50, 75, 90, 95, 99%\u003C/li>\n\u003Cli>Compact display (< 300px): 5, 25, 50, 75, 95%\u003C/li>\n\u003C/ul>\n\u003Cp>These percentiles are transformed using the inverse normal CDF (z-scores) to create a probability-scaled axis.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"confidence-interval-bands\">Confidence Interval Bands\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#confidence-interval-bands\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Confidence Interval Bands”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The 95% CI bands widen at the extremes (low and high percentiles) following MLE variance propagation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateCIWidth\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// percentile as decimal (0-1)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">n\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// sample size\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">stdDev\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// sample standard deviation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">z\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">normalQuantile\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(p);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Variance includes:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Uncertainty in mean estimation: σ²/n\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Uncertainty in std dev propagated through z: z² * σ²/(2n)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">varPercentile\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(stdDev\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">² / \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">n)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> * \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> + \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">z\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">² / \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sePercentile\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Math\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">sqrt\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(varPercentile);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 95% CI half-width\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.96\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">*\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> sePercentile;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"function calculateCIWidth( p: number, // percentile as decimal (0-1) n: number, // sample size stdDev: number // sample standard deviation): number { const z = normalQuantile(p); // Variance includes: // 1. Uncertainty in mean estimation: σ²/n // 2. Uncertainty in std dev propagated through z: z² * σ²/(2n) const varPercentile = (stdDev² / n) * (1 + z² / 2); const sePercentile = Math.sqrt(varPercentile); // 95% CI half-width return 1.96 * sePercentile;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This creates smooth, symmetric CI bands that naturally widen at distribution tails.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"interpretation\">Interpretation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#interpretation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interpretation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pattern\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Points on fitted line\u003C/td>\u003Ctd>Data is normally distributed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Points curve away at ends\u003C/td>\u003Ctd>Heavy tails (leptokurtic)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Points curve toward center\u003C/td>\u003Ctd>Light tails (platykurtic)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>S-shaped deviation\u003C/td>\u003Ctd>Skewed distribution\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Points outside CI bands\u003C/td>\u003Ctd>Significant non-normality\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-flow\">Data Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">DataContext (PWA/Azure)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">StatsPanel.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| data: number[], mean, stdDev from stats\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">ProbabilityPlot (responsive wrapper)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| calculateProbabilityPlotData() from @variscout/core\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| normalQuantile() for z-scores\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">ProbabilityPlotBase (renders SVG)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"DataContext (PWA/Azure) |StatsPanel.tsx | data: number[], mean, stdDev from statsProbabilityPlot (responsive wrapper) | calculateProbabilityPlotData() from @variscout/core | normalQuantile() for z-scoresProbabilityPlotBase (renders SVG)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"plot-data-calculation\">Plot Data Calculation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#plot-data-calculation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Plot Data Calculation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Uses \u003Ccode dir=\"auto\">calculateProbabilityPlotData()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// For each data point:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Sort data ascending\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Calculate expected percentile using Benard formula: (i - 0.3) / (n + 0.4)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Return { value, expectedPercentile }\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// For each data point:// 1. Sort data ascending// 2. Calculate expected percentile using Benard formula: (i - 0.3) / (n + 0.4)// 3. Return { value, expectedPercentile }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-app-usage\">Cross-App Usage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-app-usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-App Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-and-azure\">PWA and Azure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-and-azure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA and Azure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use the responsive wrapper (auto-sizing with \u003Ccode dir=\"auto\">withParentSize\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ProbabilityPlot \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/ProbabilityPlot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[400px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ProbabilityPlot\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">mean\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">mean\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stdDev\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">stdDev\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import ProbabilityPlot from '@variscout/charts/ProbabilityPlot';\u003Cdiv className="h-[400px]"> \u003CProbabilityPlot data={values} mean={stats.mean} stdDev={stats.stdDev} />\u003C/div>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"custom-margins-and-fonts\">Custom Margins and Fonts\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#custom-margins-and-fonts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Custom Margins and Fonts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ProbabilityPlot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">mean\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stdDev\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stdDev\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">marginOverride\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ top: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, right: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">30\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, bottom: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">50\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, left: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">60\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fontsOverride\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ tickLabel: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">10\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, axisLabel: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">12\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, statLabel: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">10\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, tooltipText: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">11\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, brandingText: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">9\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CProbabilityPlot data={values} mean={mean} stdDev={stdDev} marginOverride={{ top: 20, right: 30, bottom: 50, left: 60 }} fontsOverride={{ tickLabel: 10, axisLabel: 12, statLabel: 10, tooltipText: 11, brandingText: 9 }}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"colors-and-theming\">Colors and Theming\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#colors-and-theming\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Colors and Theming”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"point-colors\">Point Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#point-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Point Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All data points use \u003Ccode dir=\"auto\">chartColors.pass\u003C/code> (green) with white stroke.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"line-colors\">Line Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#line-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Line Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Fitted distribution line\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chartColors.linear} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// blue-500\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// CI boundary lines\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chromeColors.labelMuted} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// gray, dashed\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Fitted distribution linestroke={chartColors.linear} // blue-500// CI boundary linesstroke={chromeColors.labelMuted} // gray, dashed\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ci-band-fill\">CI Band Fill\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ci-band-fill\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CI Band Fill”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{chromeColors.ciband} \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// blue-500 with 15% opacity\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"fill={chromeColors.ciband} // blue-500 with 15% opacity\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"theme-colors\">Theme Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#theme-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theme Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Uses hardcoded dark theme colors from \u003Ccode dir=\"auto\">chromeColors\u003C/code>:\u003C/p>\n\u003Cul>\n\u003Cli>Grid: \u003Ccode dir=\"auto\">chromeColors.tooltipBorder\u003C/code>\u003C/li>\n\u003Cli>Labels: \u003Ccode dir=\"auto\">chromeColors.labelSecondary\u003C/code>\u003C/li>\n\u003Cli>Axes: \u003Ccode dir=\"auto\">chromeColors.labelMuted\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"responsive-behavior\">Responsive Behavior\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#responsive-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Responsive Behavior”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Width Range\u003C/th>\u003Cth>Y-Axis Label\u003C/th>\u003Cth>Tick Percentiles\u003C/th>\u003Cth>X-Axis Ticks\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>< 300px\u003C/td>\u003Ctd>Hidden\u003C/td>\u003Ctd>5, 25, 50, 75, 95 (compact)\u003C/td>\u003Ctd>4\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>>= 300px\u003C/td>\u003Ctd>”Percent”\u003C/td>\u003Ctd>1, 5, 10, 25, 50, 75, 90, 95, 99\u003C/td>\u003Ctd>6\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"mathematical-background\">Mathematical Background\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#mathematical-background\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mathematical Background”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"probability-transformation\">Probability Transformation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#probability-transformation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Probability Transformation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Y-axis uses the inverse normal CDF (quantile function):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">z\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">normalQuantile\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(p); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Convert percentile to z-score\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const z = normalQuantile(p); // Convert percentile to z-score\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This transformation makes normally distributed data appear as a straight line because:\u003C/p>\n\u003Cul>\n\u003Cli>For normal data: X_p = μ + z_p × σ\u003C/li>\n\u003Cli>When plotted with z on Y-axis and X on X-axis, the relationship is linear\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"fitted-line-points\">Fitted Line Points\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#fitted-line-points\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Fitted Line Points”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The fitted line represents the theoretical normal distribution:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fittedLineWithCI\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">percentiles\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">p\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pDecimal\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">p\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> / \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">z\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">normalQuantile\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(pDecimal)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">expectedX\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> + \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">z\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> * \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stdDev\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Theoretical value\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">ciWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">calculateCIWidth\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(pDecimal\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">n\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stdDev)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">z\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">x: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">expectedX\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">lowerCI: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">expectedX\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> - \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ciWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">upperCI: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">expectedX\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> + \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ciWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const fittedLineWithCI = percentiles.map(p => { const pDecimal = p / 100; const z = normalQuantile(pDecimal); const expectedX = mean + z * stdDev; // Theoretical value const ciWidth = calculateCIWidth(pDecimal, n, stdDev); return { z, x: expectedX, lowerCI: expectedX - ciWidth, upperCI: expectedX + ciWidth, };});\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"signature-element\">Signature Element\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#signature-element\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Signature Element”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>An optional \u003Ccode dir=\"auto\">signatureElement\u003C/code> prop allows rendering custom content (like a logo or signature) within the chart:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ProbabilityPlot\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">mean\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stdDev\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stdDev\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">signatureElement\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">CustomSignature\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CProbabilityPlot data={values} mean={mean} stdDev={stdDev} signatureElement={\u003CCustomSignature />} />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"exports\">Exports\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#exports\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Responsive wrapper (auto-sizing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ProbabilityPlot \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/ProbabilityPlot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Base component (manual sizing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { ProbabilityPlotBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/ProbabilityPlot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Types\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">type\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { ProbabilityPlotProps } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Core functions\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { calculateProbabilityPlotData, normalQuantile } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Responsive wrapper (auto-sizing)import ProbabilityPlot from '@variscout/charts/ProbabilityPlot';// Base component (manual sizing)import { ProbabilityPlotBase } from '@variscout/charts/ProbabilityPlot';// Typesimport type { ProbabilityPlotProps } from '@variscout/charts';// Core functionsimport { calculateProbabilityPlotData, normalQuantile } from '@variscout/core';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview and selection guide\u003C/li>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - Chart color constants\u003C/li>\n\u003Cli>\u003Ca href=\"./responsive.md\">Responsive\u003C/a> - Breakpoints and scaling utilities\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - useChartLayout\u003C/li>\n\u003Cli>\u003Ca href=\"./capability.md\">Capability\u003C/a> - Distribution histograms\u003C/li>\n\u003C/ul>", + { + "headings": 10441, + "localImagePaths": 10490, + "remoteImagePaths": 10491, + "frontmatter": 10492, + "imagePaths": 10493 + }, + [ + 10442, 10443, 10444, 10447, 10448, 10449, 10450, 10453, 10456, 10457, 10458, 10461, 10462, + 10463, 10466, 10467, 10468, 10469, 10472, 10475, 10476, 10479, 10482, 10485, 10488, 10489 + ], + { "depth": 30, "slug": 580, "text": 581 }, + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 10445, "text": 10446 }, + "probabilityplot", + "ProbabilityPlot", + { "depth": 79, "slug": 9737, "text": 9738 }, + { "depth": 79, "slug": 7536, "text": 7537 }, + { "depth": 33, "slug": 9896, "text": 9897 }, + { "depth": 79, "slug": 10451, "text": 10452 }, + "probability-percentile-scale", + "Probability Percentile Scale", + { "depth": 33, "slug": 10454, "text": 10455 }, + "confidence-interval-bands", + "Confidence Interval Bands", + { "depth": 33, "slug": 6346, "text": 6347 }, + { "depth": 33, "slug": 9776, "text": 9777 }, + { "depth": 79, "slug": 10459, "text": 10460 }, + "plot-data-calculation", + "Plot Data Calculation", + { "depth": 33, "slug": 9801, "text": 9802 }, + { "depth": 79, "slug": 9804, "text": 9805 }, + { "depth": 79, "slug": 10464, "text": 10465 }, + "custom-margins-and-fonts", + "Custom Margins and Fonts", + { "depth": 33, "slug": 9807, "text": 9808 }, + { "depth": 79, "slug": 10249, "text": 10250 }, + { "depth": 79, "slug": 9952, "text": 9953 }, + { "depth": 79, "slug": 10470, "text": 10471 }, + "ci-band-fill", + "CI Band Fill", + { "depth": 79, "slug": 10473, "text": 10474 }, + "theme-colors", + "Theme Colors", + { "depth": 33, "slug": 10421, "text": 10422 }, + { "depth": 33, "slug": 10477, "text": 10478 }, + "mathematical-background", + "Mathematical Background", + { "depth": 79, "slug": 10480, "text": 10481 }, + "probability-transformation", + "Probability Transformation", + { "depth": 79, "slug": 10483, "text": 10484 }, + "fitted-line-points", + "Fitted Line Points", + { "depth": 33, "slug": 10486, "text": 10487 }, + "signature-element", + "Signature Element", + { "depth": 33, "slug": 1723, "text": 1724 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 581 }, + [], + "06-design-system/charts/performance-mode", + { + "id": 10494, + "data": 10496, + "body": 10501, + "filePath": 10502, + "digest": 10503, + "rendered": 10504 + }, + { + "title": 10497, + "editUrl": 16, + "head": 10498, + "template": 18, + "sidebar": 10499, + "pagefind": 16, + "draft": 20 + }, + "Performance Mode Charts", + [], + { "hidden": 20, "attrs": 10500 }, + {}, + "# Performance Mode Charts\n\nMulti-measure analysis charts for comparing performance across multiple measurement channels.\n\n## Overview\n\nPerformance Mode enables analysis of wide-format data with multiple measurement columns (fill heads, cavities, nozzles, etc.). These charts help identify which channels need attention and how they compare.\n\n| Component | Purpose | Normal | Maximized |\n| ----------------------- | --------------------------- | ------ | --------- |\n| `PerformanceIChart` | Cpk scatter plot by channel | All | All |\n| `PerformanceBoxplot` | Distribution comparison | 5 | All |\n| `PerformancePareto` | Cpk ranking (worst first) | 20 | 50 |\n| `PerformanceCapability` | Single channel histogram | 1 | 1 |\n\n**Source:** `packages/charts/src/Performance*.tsx`\n\n---\n\n## ChannelResult Interface\n\nAll Performance charts accept `channels: ChannelResult[]` from `@variscout/core`:\n\n```typescript\ninterface ChannelResult {\n id: string; // Unique channel identifier\n label: string; // Display label\n values: number[]; // Raw measurement values\n n: number; // Sample size\n mean: number; // Mean value\n stdDev: number; // Standard deviation\n cp?: number; // Process Capability\n cpk?: number; // Process Capability Index\n health: 'excellent' | 'capable' | 'warning' | 'critical'; // Legacy, not used for display\n}\n```\n\n### Per-Measure Specs (Optional)\n\nPerformance Mode supports different specification limits for each measure column. This is useful when channels have different tolerance requirements (e.g., different fill heads with different nominal values).\n\n```typescript\n// In DataState (from useDataState hook)\nmeasureSpecs?: Record\u003Cstring, SpecLimits>;\n\n// Usage\nconst specsForChannel = state.getSpecsForMeasure(channelId);\n// Returns per-measure override if defined, otherwise global specs\n```\n\nThe `measureSpecs` map is keyed by measure column name and persisted in project state.\n\n### Characteristic Type\n\nEach spec (global or per-measure) can have a `characteristicType` that affects interpretation:\n\n| Type | Specs Defined | Meaning |\n| ----------- | ------------- | ------------------------------------------------------ |\n| `'nominal'` | USL + LSL | Target is ideal, deviation in either direction is loss |\n| `'smaller'` | USL only | Smaller-is-better (e.g., defects, cycle time) |\n| `'larger'` | LSL only | Larger-is-better (e.g., yield, strength) |\n\nThe type is automatically inferred from which specs are defined, but can be overridden:\n\n```typescript\nimport { inferCharacteristicType } from '@variscout/core';\n\nconst type = inferCharacteristicType({ usl: 100, lsl: 90 }); // 'nominal'\nconst type = inferCharacteristicType({ usl: 5 }); // 'smaller'\nconst type = inferCharacteristicType({ lsl: 80 }); // 'larger'\n```\n\n### Color Approach\n\nPerformance Mode uses a simplified color scheme that lets users set their own Cpk targets:\n\n| Chart | Coloring Approach | Description |\n| ----------------------- | ----------------- | ------------------------------------------- |\n| `PerformanceIChart` | Control-based | Blue (in-control) / Red (out-of-control) |\n| `PerformanceBoxplot` | Spec-based | Colored by position relative to spec limits |\n| `PerformancePareto` | Neutral | All bars use blue (`chartColors.mean`) |\n| `PerformanceCapability` | Spec-based | Histogram bars colored by spec position |\n\n> **Note:** Users set their own Cpk target (default 1.33) via PerformanceSetupPanel (setup phase).\n\n---\n\n## PerformanceIChart\n\nI-Chart for capability metrics (Cpk or Cp) across channels. Uses statistical control limits rather than health-based coloring.\n\n**Source:** `packages/charts/src/PerformanceIChart.tsx`\n\n### Props\n\n```typescript\ninterface PerformanceIChartProps {\n parentWidth: number;\n parentHeight: number;\n channels: ChannelResult[];\n selectedMeasure?: string; // Highlighted channel\n onChannelClick?: (id: string) => void;\n showBranding?: boolean;\n capabilityMetric?: 'cp' | 'cpk'; // Toggle between Cp/Cpk (default: 'cpk')\n cpkTarget?: number; // Target line value (default: 1.33)\n}\n```\n\n### Features\n\n- **X-axis:** Channel index/name\n- **Y-axis:** Capability metric value (Cpk or Cp)\n- **Control limits:** UCL/LCL calculated from capability distribution (mean ± 3σ)\n- **Mean line:** Average capability across all channels (solid blue)\n- **Target line:** User-defined reference (default: 1.33, dashed green)\n- **Point coloring:** Control-based (blue = in-control, red = out-of-control)\n- **Nelson Rule 2:** 9+ consecutive points on same side of mean flagged as violations\n- Selected point highlighted with larger radius and white stroke\n- Unselected points dimmed when selection exists\n\n### Control-Based Coloring\n\nPerformanceIChart uses control limits calculated from the Cpk/Cp distribution:\n\n- **Blue points:** Within control limits (in-control)\n- **Red points:** Outside control limits (out-of-control)\n- **Target line:** User-defined Cpk target (default 1.33)\n\n### Cpk Target Setting\n\nUsers can configure a custom Cpk target in PerformanceSetupPanel:\n\n| Property | Default | Range | Description |\n| --------- | ------- | --------- | ---------------------------- |\n| cpkTarget | 1.33 | 0.5 - 3.0 | Target line shown on I-Chart |\n\nCommon target values:\n\n| Target | PPM Defects | Use Case |\n| ------ | ----------- | ------------------ |\n| 1.00 | ~2,700 | Minimum capability |\n| 1.33 | ~63 | Standard target |\n| 1.67 | ~1 | High capability |\n| 2.00 | \u003C1 | Six Sigma |\n\n### Example\n\n```tsx\nimport PerformanceIChart from '@variscout/charts/PerformanceIChart';\n\n\u003CPerformanceIChart\n channels={channelResults}\n selectedMeasure={selectedId}\n onChannelClick={handleChannelSelect}\n capabilityMetric=\"cpk\"\n cpkTarget={1.33}\n/>;\n```\n\n---\n\n## PerformanceBoxplot\n\nShows boxplots for selected channel or worst-performing channels.\n\n**Source:** `packages/charts/src/PerformanceBoxplot.tsx`\n\n### Props\n\n```typescript\ninterface PerformanceBoxplotProps {\n parentWidth: number;\n parentHeight: number;\n channels: ChannelResult[];\n specs: SpecLimits; // USL, LSL, Target\n selectedMeasure?: string;\n maxDisplayed?: number; // Default: 5\n onChannelClick?: (id: string) => void;\n showBranding?: boolean;\n}\n```\n\n### Behavior\n\n- **When channel selected:** Shows single detailed boxplot\n- **When no selection:** Shows worst N channels by Cpk (uses `getWorstChannels()`)\n\n### Boxplot Elements\n\n| Element | Description |\n| ---------- | ---------------- |\n| Whiskers | Min to Max range |\n| Box | Q1 to Q3 (IQR) |\n| Thick line | Median |\n| Diamond | Mean |\n\n### Example\n\n```tsx\nimport PerformanceBoxplot from '@variscout/charts/PerformanceBoxplot';\n\n\u003CPerformanceBoxplot\n channels={channelResults}\n specs={{ usl: 105, lsl: 95, target: 100 }}\n selectedMeasure={selectedId}\n maxDisplayed={5}\n onChannelClick={handleChannelSelect}\n/>;\n```\n\n---\n\n## PerformancePareto\n\nRanks channels by Cpk (worst first) with cumulative percentage line.\n\n**Source:** `packages/charts/src/PerformancePareto.tsx`\n\n### Props\n\n```typescript\ninterface PerformanceParetoProps {\n parentWidth: number;\n parentHeight: number;\n channels: ChannelResult[];\n selectedMeasure?: string;\n maxDisplayed?: number; // Default: 20\n onChannelClick?: (id: string) => void;\n showBranding?: boolean;\n}\n```\n\n### Features\n\n- Bars sorted by Cpk ascending (worst first)\n- All bars use neutral blue color (`chartColors.mean`)\n- Cumulative percentage line (right Y-axis)\n- Reference lines at Cpk = 1.0 and 1.33 thresholds\n- Tooltip shows rank, Cpk, and n\n\n### Example\n\n```tsx\nimport PerformancePareto from '@variscout/charts/PerformancePareto';\n\n\u003CPerformancePareto\n channels={channelResults}\n selectedMeasure={selectedId}\n maxDisplayed={20}\n onChannelClick={handleChannelSelect}\n/>;\n```\n\n---\n\n## PerformanceCapability\n\nDetailed capability histogram for a single selected channel.\n\n**Source:** `packages/charts/src/PerformanceCapability.tsx`\n\n### Props\n\n```typescript\ninterface PerformanceCapabilityProps {\n parentWidth: number;\n parentHeight: number;\n channel: ChannelResult | null;\n specs: SpecLimits;\n showBranding?: boolean;\n}\n```\n\n### Features\n\n- 15-bin histogram of measurement values\n- Vertical spec limit lines (LSL, USL)\n- Mean line with value label\n- Stats overlay panel showing:\n - Channel label\n - n, σ, Cpk values\n- Bars colored by position relative to specs (green in-spec, red/amber out-of-spec)\n\n### Example\n\n```tsx\nimport PerformanceCapability from '@variscout/charts/PerformanceCapability';\n\n\u003CPerformanceCapability channel={selectedChannel} specs={{ usl: 105, lsl: 95 }} />;\n```\n\n---\n\n## Cross-App Usage\n\n### PWA and Azure\n\nUse the responsive wrapper (auto-sizing with `withParentSize`):\n\n```tsx\nimport PerformanceIChart from '@variscout/charts/PerformanceIChart';\n\n\u003Cdiv className=\"h-[300px]\">\n \u003CPerformanceIChart channels={channels} onChannelClick={handleClick} />\n\u003C/div>;\n```\n\n## Drill-Down Flow\n\nTypical user journey through Performance Mode:\n\n```\nPerformancePareto (overview)\n |\n | Click worst channel\n v\nPerformanceBoxplot (distribution)\n |\n | Click channel\n v\nPerformanceCapability (detail)\n |\n | Back button\n v\nStandard Dashboard (I-Chart, etc.)\n```\n\n### Implementation\n\n```tsx\nconst [selectedMeasure, setSelectedMeasure] = useState\u003Cstring | null>(null);\n\n// Pareto and IChart show all channels, highlight selected\n\u003CPerformancePareto\n channels={channels}\n selectedMeasure={selectedMeasure}\n onChannelClick={setSelectedMeasure}\n/>\n\n// Boxplot shows selected or worst N\n\u003CPerformanceBoxplot\n channels={channels}\n selectedMeasure={selectedMeasure}\n onChannelClick={setSelectedMeasure}\n/>\n\n// Capability shows only selected\n{selectedMeasure && (\n \u003CPerformanceCapability\n channel={channels.find(c => c.id === selectedMeasure)}\n specs={specs}\n />\n)}\n```\n\n---\n\n## Focus Mode\n\nPerformance charts support maximize/fullscreen mode for detailed analysis of all channels.\n\n### Activation\n\n- Click the maximize button (⤢) in each chart panel header\n- Chart expands to full viewport with navigation arrows\n\n### Keyboard Navigation\n\n| Key | Action |\n| --------- | -------------------- |\n| `←` / `→` | Cycle between charts |\n| `Escape` | Exit focus mode |\n\nNavigation arrows appear on hover at screen edges.\n\n### Display Limits\n\nWhen maximized, display limits increase to show more data:\n\n| Chart | Normal | Maximized |\n| ----------------------- | ------ | --------- |\n| `PerformanceBoxplot` | 5 | All |\n| `PerformancePareto` | 20 | 50 |\n| `PerformanceIChart` | All | All |\n| `PerformanceCapability` | 1 | 1 |\n\n### Implementation\n\nFocus Mode is implemented in the Performance Dashboard components:\n\n- **PWA:** `apps/pwa/src/components/PerformanceDashboard.tsx`\n- **Azure:** `apps/azure/src/components/PerformanceDashboard.tsx`\n\nState management uses `focusedChart` to track the currently maximized panel (or `null` for normal view).\n\n---\n\n## Exports\n\n```typescript\n// Responsive wrappers (auto-sizing)\nimport PerformanceIChart from '@variscout/charts/PerformanceIChart';\nimport PerformanceBoxplot from '@variscout/charts/PerformanceBoxplot';\nimport PerformancePareto from '@variscout/charts/PerformancePareto';\nimport PerformanceCapability from '@variscout/charts/PerformanceCapability';\n\n// Base components (manual sizing)\nimport { PerformanceIChartBase } from '@variscout/charts/PerformanceIChart';\nimport { PerformanceBoxplotBase } from '@variscout/charts/PerformanceBoxplot';\nimport { PerformanceParetoBase } from '@variscout/charts/PerformancePareto';\nimport { PerformanceCapabilityBase } from '@variscout/charts/PerformanceCapability';\n```\n\n---\n\n## See Also\n\n- [Overview](./overview.md) - Chart design system overview and selection guide\n- [Colors](./colors.md) - Chart color constants\n- [Responsive](./responsive.md) - Breakpoints and scaling utilities\n- [Hooks](./hooks.md) - useChartLayout, useChartTooltip\n- [IChart](./ichart.md) - PerformanceIChart component\n- [Boxplot](./boxplot.md) - PerformanceBoxplot component\n- [Pareto](./pareto.md) - PerformancePareto component\n- [Capability](./capability.md) - PerformanceCapability component", + "src/content/docs/06-design-system/charts/performance-mode.md", + "bc68bd0068ec297e", + { "html": 10505, "metadata": 10506 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"performance-mode-charts\">Performance Mode Charts\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#performance-mode-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance Mode Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Multi-measure analysis charts for comparing performance across multiple measurement channels.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Performance Mode enables analysis of wide-format data with multiple measurement columns (fill heads, cavities, nozzles, etc.). These charts help identify which channels need attention and how they compare.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Normal\u003C/th>\u003Cth>Maximized\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceIChart\u003C/code>\u003C/td>\u003Ctd>Cpk scatter plot by channel\u003C/td>\u003Ctd>All\u003C/td>\u003Ctd>All\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceBoxplot\u003C/code>\u003C/td>\u003Ctd>Distribution comparison\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>All\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformancePareto\u003C/code>\u003C/td>\u003Ctd>Cpk ranking (worst first)\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>50\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceCapability\u003C/code>\u003C/td>\u003Ctd>Single channel histogram\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/Performance*.tsx\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"channelresult-interface\">ChannelResult Interface\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#channelresult-interface\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ChannelResult Interface”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All Performance charts accept \u003Ccode dir=\"auto\">channels: ChannelResult[]\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChannelResult {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Unique channel identifier\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Display label\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">values\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Raw measurement values\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">n\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Sample size\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mean value\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stdDev\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard deviation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cp\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Process Capability\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cpk\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Process Capability Index\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">health\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">excellent\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">capable\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">warning\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">critical\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Legacy, not used for display\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ChannelResult { id: string; // Unique channel identifier label: string; // Display label values: number[]; // Raw measurement values n: number; // Sample size mean: number; // Mean value stdDev: number; // Standard deviation cp?: number; // Process Capability cpk?: number; // Process Capability Index health: 'excellent' | 'capable' | 'warning' | 'critical'; // Legacy, not used for display}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"per-measure-specs-optional\">Per-Measure Specs (Optional)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#per-measure-specs-optional\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Per-Measure Specs (Optional)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Performance Mode supports different specification limits for each measure column. This is useful when channels have different tolerance requirements (e.g., different fill heads with different nominal values).\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// In DataState (from useDataState hook)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measureSpecs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Record\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">string, SpecLimits\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Usage\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">specsForChannel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">state\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getSpecsForMeasure\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(channelId);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns per-measure override if defined, otherwise global specs\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// In DataState (from useDataState hook)measureSpecs?: Record\u003Cstring, SpecLimits>;// Usageconst specsForChannel = state.getSpecsForMeasure(channelId);// Returns per-measure override if defined, otherwise global specs\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">measureSpecs\u003C/code> map is keyed by measure column name and persisted in project state.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"characteristic-type\">Characteristic Type\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#characteristic-type\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Characteristic Type”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each spec (global or per-measure) can have a \u003Ccode dir=\"auto\">characteristicType\u003C/code> that affects interpretation:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Specs Defined\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'nominal'\u003C/code>\u003C/td>\u003Ctd>USL + LSL\u003C/td>\u003Ctd>Target is ideal, deviation in either direction is loss\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'smaller'\u003C/code>\u003C/td>\u003Ctd>USL only\u003C/td>\u003Ctd>Smaller-is-better (e.g., defects, cycle time)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">'larger'\u003C/code>\u003C/td>\u003Ctd>LSL only\u003C/td>\u003Ctd>Larger-is-better (e.g., yield, strength)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The type is automatically inferred from which specs are defined, but can be overridden:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { inferCharacteristicType } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">inferCharacteristicType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">90\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 'nominal'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">inferCharacteristicType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">5\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 'smaller'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">inferCharacteristicType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">80\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 'larger'\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { inferCharacteristicType } from '@variscout/core';const type = inferCharacteristicType({ usl: 100, lsl: 90 }); // 'nominal'const type = inferCharacteristicType({ usl: 5 }); // 'smaller'const type = inferCharacteristicType({ lsl: 80 }); // 'larger'\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"color-approach\">Color Approach\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#color-approach\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color Approach”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Performance Mode uses a simplified color scheme that lets users set their own Cpk targets:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Coloring Approach\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceIChart\u003C/code>\u003C/td>\u003Ctd>Control-based\u003C/td>\u003Ctd>Blue (in-control) / Red (out-of-control)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceBoxplot\u003C/code>\u003C/td>\u003Ctd>Spec-based\u003C/td>\u003Ctd>Colored by position relative to spec limits\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformancePareto\u003C/code>\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>All bars use blue (\u003Ccode dir=\"auto\">chartColors.mean\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceCapability\u003C/code>\u003C/td>\u003Ctd>Spec-based\u003C/td>\u003Ctd>Histogram bars colored by spec position\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note:\u003C/strong> Users set their own Cpk target (default 1.33) via PerformanceSetupPanel (setup phase).\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performanceichart\">PerformanceIChart\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performanceichart\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformanceIChart”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>I-Chart for capability metrics (Cpk or Cp) across channels. Uses statistical control limits rather than health-based coloring.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/PerformanceIChart.tsx\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceIChartProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChannelResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Highlighted channel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showBranding\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">capabilityMetric\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cp\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Toggle between Cp/Cpk (default: 'cpk')\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cpkTarget\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Target line value (default: 1.33)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface PerformanceIChartProps { parentWidth: number; parentHeight: number; channels: ChannelResult[]; selectedMeasure?: string; // Highlighted channel onChannelClick?: (id: string) => void; showBranding?: boolean; capabilityMetric?: 'cp' | 'cpk'; // Toggle between Cp/Cpk (default: 'cpk') cpkTarget?: number; // Target line value (default: 1.33)}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"features\">Features\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>X-axis:\u003C/strong> Channel index/name\u003C/li>\n\u003Cli>\u003Cstrong>Y-axis:\u003C/strong> Capability metric value (Cpk or Cp)\u003C/li>\n\u003Cli>\u003Cstrong>Control limits:\u003C/strong> UCL/LCL calculated from capability distribution (mean ± 3σ)\u003C/li>\n\u003Cli>\u003Cstrong>Mean line:\u003C/strong> Average capability across all channels (solid blue)\u003C/li>\n\u003Cli>\u003Cstrong>Target line:\u003C/strong> User-defined reference (default: 1.33, dashed green)\u003C/li>\n\u003Cli>\u003Cstrong>Point coloring:\u003C/strong> Control-based (blue = in-control, red = out-of-control)\u003C/li>\n\u003Cli>\u003Cstrong>Nelson Rule 2:\u003C/strong> 9+ consecutive points on same side of mean flagged as violations\u003C/li>\n\u003Cli>Selected point highlighted with larger radius and white stroke\u003C/li>\n\u003Cli>Unselected points dimmed when selection exists\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"control-based-coloring\">Control-Based Coloring\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#control-based-coloring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Control-Based Coloring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>PerformanceIChart uses control limits calculated from the Cpk/Cp distribution:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Blue points:\u003C/strong> Within control limits (in-control)\u003C/li>\n\u003Cli>\u003Cstrong>Red points:\u003C/strong> Outside control limits (out-of-control)\u003C/li>\n\u003Cli>\u003Cstrong>Target line:\u003C/strong> User-defined Cpk target (default 1.33)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cpk-target-setting\">Cpk Target Setting\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cpk-target-setting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cpk Target Setting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Users can configure a custom Cpk target in PerformanceSetupPanel:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Property\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Range\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>cpkTarget\u003C/td>\u003Ctd>1.33\u003C/td>\u003Ctd>0.5 - 3.0\u003C/td>\u003Ctd>Target line shown on I-Chart\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Common target values:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Target\u003C/th>\u003Cth>PPM Defects\u003C/th>\u003Cth>Use Case\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1.00\u003C/td>\u003Ctd>~2,700\u003C/td>\u003Ctd>Minimum capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.33\u003C/td>\u003Ctd>~63\u003C/td>\u003Ctd>Standard target\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>1.67\u003C/td>\u003Ctd>~1\u003C/td>\u003Ctd>High capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2.00\u003C/td>\u003Ctd><1\u003C/td>\u003Ctd>Six Sigma\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceIChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceIChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceIChart\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channelResults\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedId\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleChannelSelect\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">capabilityMetric\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">cpk\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">cpkTarget\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">1.33\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import PerformanceIChart from '@variscout/charts/PerformanceIChart';\u003CPerformanceIChart channels={channelResults} selectedMeasure={selectedId} onChannelClick={handleChannelSelect} capabilityMetric="cpk" cpkTarget={1.33}/>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performanceboxplot\">PerformanceBoxplot\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performanceboxplot\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformanceBoxplot”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Shows boxplots for selected channel or worst-performing channels.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/PerformanceBoxplot.tsx\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-1\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceBoxplotProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChannelResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// USL, LSL, Target\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">maxDisplayed\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Default: 5\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showBranding\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface PerformanceBoxplotProps { parentWidth: number; parentHeight: number; channels: ChannelResult[]; specs: SpecLimits; // USL, LSL, Target selectedMeasure?: string; maxDisplayed?: number; // Default: 5 onChannelClick?: (id: string) => void; showBranding?: boolean;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"behavior\">Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Behavior”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>When channel selected:\u003C/strong> Shows single detailed boxplot\u003C/li>\n\u003Cli>\u003Cstrong>When no selection:\u003C/strong> Shows worst N channels by Cpk (uses \u003Ccode dir=\"auto\">getWorstChannels()\u003C/code>)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"boxplot-elements\">Boxplot Elements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#boxplot-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Boxplot Elements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Whiskers\u003C/td>\u003Ctd>Min to Max range\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Box\u003C/td>\u003Ctd>Q1 to Q3 (IQR)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Thick line\u003C/td>\u003Ctd>Median\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Diamond\u003C/td>\u003Ctd>Mean\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-1\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceBoxplot \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceBoxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceBoxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channelResults\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">105\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">95\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, target: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedId\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">maxDisplayed\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">5\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleChannelSelect\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import PerformanceBoxplot from '@variscout/charts/PerformanceBoxplot';\u003CPerformanceBoxplot channels={channelResults} specs={{ usl: 105, lsl: 95, target: 100 }} selectedMeasure={selectedId} maxDisplayed={5} onChannelClick={handleChannelSelect}/>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performancepareto\">PerformancePareto\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performancepareto\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformancePareto”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Ranks channels by Cpk (worst first) with cumulative percentage line.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/PerformancePareto.tsx\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-2\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceParetoProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChannelResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">maxDisplayed\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Default: 20\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showBranding\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface PerformanceParetoProps { parentWidth: number; parentHeight: number; channels: ChannelResult[]; selectedMeasure?: string; maxDisplayed?: number; // Default: 20 onChannelClick?: (id: string) => void; showBranding?: boolean;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"features-1\">Features\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#features-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Bars sorted by Cpk ascending (worst first)\u003C/li>\n\u003Cli>All bars use neutral blue color (\u003Ccode dir=\"auto\">chartColors.mean\u003C/code>)\u003C/li>\n\u003Cli>Cumulative percentage line (right Y-axis)\u003C/li>\n\u003Cli>Reference lines at Cpk = 1.0 and 1.33 thresholds\u003C/li>\n\u003Cli>Tooltip shows rank, Cpk, and n\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-2\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformancePareto \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformancePareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformancePareto\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channelResults\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedId\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">maxDisplayed\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleChannelSelect\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import PerformancePareto from '@variscout/charts/PerformancePareto';\u003CPerformancePareto channels={channelResults} selectedMeasure={selectedId} maxDisplayed={20} onChannelClick={handleChannelSelect}/>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performancecapability\">PerformanceCapability\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performancecapability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PerformanceCapability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Detailed capability histogram for a single selected channel.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/PerformanceCapability.tsx\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-3\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceCapabilityProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChannelResult\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showBranding\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface PerformanceCapabilityProps { parentWidth: number; parentHeight: number; channel: ChannelResult | null; specs: SpecLimits; showBranding?: boolean;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"features-2\">Features\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#features-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>15-bin histogram of measurement values\u003C/li>\n\u003Cli>Vertical spec limit lines (LSL, USL)\u003C/li>\n\u003Cli>Mean line with value label\u003C/li>\n\u003Cli>Stats overlay panel showing:\n\u003Cul>\n\u003Cli>Channel label\u003C/li>\n\u003Cli>n, σ, Cpk values\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>Bars colored by position relative to specs (green in-spec, red/amber out-of-spec)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-3\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceCapability \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceCapability\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceCapability\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedChannel\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ usl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">105\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, lsl: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">95\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import PerformanceCapability from '@variscout/charts/PerformanceCapability';\u003CPerformanceCapability channel={selectedChannel} specs={{ usl: 105, lsl: 95 }} />;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-app-usage\">Cross-App Usage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-app-usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-App Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-and-azure\">PWA and Azure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-and-azure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA and Azure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Use the responsive wrapper (auto-sizing with \u003Ccode dir=\"auto\">withParentSize\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceIChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceIChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[300px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceIChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">handleClick\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import PerformanceIChart from '@variscout/charts/PerformanceIChart';\u003Cdiv className="h-[300px]"> \u003CPerformanceIChart channels={channels} onChannelClick={handleClick} />\u003C/div>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"drill-down-flow\">Drill-Down Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#drill-down-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drill-Down Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Typical user journey through Performance Mode:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformancePareto (overview)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| Click worst channel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">v\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceBoxplot (distribution)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| Click channel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">v\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">PerformanceCapability (detail)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">|\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| Back button\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">v\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Standard Dashboard (I-Chart, etc.)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"PerformancePareto (overview) | | Click worst channel vPerformanceBoxplot (distribution) | | Click channel vPerformanceCapability (detail) | | Back button vStandard Dashboard (I-Chart, etc.)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"implementation\">Implementation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const [\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelectedMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">] = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useState\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Pareto and IChart show all channels, highlight selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformancePareto\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setSelectedMeasure\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Boxplot shows selected or worst N\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceBoxplot\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChannelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setSelectedMeasure\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Capability shows only selected\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{selectedMeasure \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PerformanceCapability\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">channel\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">channels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">find\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">c\u003C/span>\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">c\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">id\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">===\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const [selectedMeasure, setSelectedMeasure] = useState\u003Cstring | null>(null);// Pareto and IChart show all channels, highlight selected\u003CPerformancePareto channels={channels} selectedMeasure={selectedMeasure} onChannelClick={setSelectedMeasure}/>// Boxplot shows selected or worst N\u003CPerformanceBoxplot channels={channels} selectedMeasure={selectedMeasure} onChannelClick={setSelectedMeasure}/>// Capability shows only selected{selectedMeasure && ( \u003CPerformanceCapability channel={channels.find(c => c.id === selectedMeasure)} specs={specs} />)}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"focus-mode\">Focus Mode\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#focus-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Focus Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Performance charts support maximize/fullscreen mode for detailed analysis of all channels.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"activation\">Activation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#activation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Activation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Click the maximize button (⤢) in each chart panel header\u003C/li>\n\u003Cli>Chart expands to full viewport with navigation arrows\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"keyboard-navigation\">Keyboard Navigation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#keyboard-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyboard Navigation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Key\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">←\u003C/code> / \u003Ccode dir=\"auto\">→\u003C/code>\u003C/td>\u003Ctd>Cycle between charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Escape\u003C/code>\u003C/td>\u003Ctd>Exit focus mode\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Navigation arrows appear on hover at screen edges.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"display-limits\">Display Limits\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#display-limits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Display Limits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When maximized, display limits increase to show more data:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Normal\u003C/th>\u003Cth>Maximized\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceBoxplot\u003C/code>\u003C/td>\u003Ctd>5\u003C/td>\u003Ctd>All\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformancePareto\u003C/code>\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>50\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceIChart\u003C/code>\u003C/td>\u003Ctd>All\u003C/td>\u003Ctd>All\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceCapability\u003C/code>\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>1\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"implementation-1\">Implementation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Focus Mode is implemented in the Performance Dashboard components:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>PWA:\u003C/strong> \u003Ccode dir=\"auto\">apps/pwa/src/components/PerformanceDashboard.tsx\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Azure:\u003C/strong> \u003Ccode dir=\"auto\">apps/azure/src/components/PerformanceDashboard.tsx\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>State management uses \u003Ccode dir=\"auto\">focusedChart\u003C/code> to track the currently maximized panel (or \u003Ccode dir=\"auto\">null\u003C/code> for normal view).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"exports\">Exports\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#exports\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Exports”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Responsive wrappers (auto-sizing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceIChart \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceIChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceBoxplot \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceBoxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformancePareto \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformancePareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> PerformanceCapability \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceCapability\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Base components (manual sizing)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { PerformanceIChartBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceIChart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { PerformanceBoxplotBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceBoxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { PerformanceParetoBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformancePareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { PerformanceCapabilityBase } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts/PerformanceCapability\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Responsive wrappers (auto-sizing)import PerformanceIChart from '@variscout/charts/PerformanceIChart';import PerformanceBoxplot from '@variscout/charts/PerformanceBoxplot';import PerformancePareto from '@variscout/charts/PerformancePareto';import PerformanceCapability from '@variscout/charts/PerformanceCapability';// Base components (manual sizing)import { PerformanceIChartBase } from '@variscout/charts/PerformanceIChart';import { PerformanceBoxplotBase } from '@variscout/charts/PerformanceBoxplot';import { PerformanceParetoBase } from '@variscout/charts/PerformancePareto';import { PerformanceCapabilityBase } from '@variscout/charts/PerformanceCapability';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview and selection guide\u003C/li>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - Chart color constants\u003C/li>\n\u003Cli>\u003Ca href=\"./responsive.md\">Responsive\u003C/a> - Breakpoints and scaling utilities\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - useChartLayout, useChartTooltip\u003C/li>\n\u003Cli>\u003Ca href=\"./ichart.md\">IChart\u003C/a> - PerformanceIChart component\u003C/li>\n\u003Cli>\u003Ca href=\"./boxplot.md\">Boxplot\u003C/a> - PerformanceBoxplot component\u003C/li>\n\u003Cli>\u003Ca href=\"./pareto.md\">Pareto\u003C/a> - PerformancePareto component\u003C/li>\n\u003Cli>\u003Ca href=\"./capability.md\">Capability\u003C/a> - PerformanceCapability component\u003C/li>\n\u003C/ul>", + { + "headings": 10507, + "localImagePaths": 10573, + "remoteImagePaths": 10574, + "frontmatter": 10575, + "imagePaths": 10576 + }, + [ + 10508, 10510, 10511, 10514, 10517, 10518, 10521, 10522, 10525, 10526, 10527, 10530, 10531, + 10532, 10534, 10535, 10538, 10539, 10540, 10542, 10544, 10546, 10547, 10549, 10551, 10553, + 10554, 10555, 10558, 10559, 10562, 10565, 10566, 10569, 10571, 10572 + ], + { "depth": 30, "slug": 10509, "text": 10497 }, + "performance-mode-charts", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 10512, "text": 10513 }, + "channelresult-interface", + "ChannelResult Interface", + { "depth": 79, "slug": 10515, "text": 10516 }, + "per-measure-specs-optional", + "Per-Measure Specs (Optional)", + { "depth": 79, "slug": 577, "text": 578 }, + { "depth": 79, "slug": 10519, "text": 10520 }, + "color-approach", + "Color Approach", + { "depth": 33, "slug": 10205, "text": 10206 }, + { "depth": 79, "slug": 10523, "text": 10524 }, + "props", + "Props", + { "depth": 79, "slug": 1082, "text": 1070 }, + { "depth": 79, "slug": 10214, "text": 10215 }, + { "depth": 79, "slug": 10528, "text": 10529 }, + "cpk-target-setting", + "Cpk Target Setting", + { "depth": 79, "slug": 7536, "text": 7537 }, + { "depth": 33, "slug": 9761, "text": 9762 }, + { "depth": 79, "slug": 10533, "text": 10524 }, + "props-1", + { "depth": 79, "slug": 10113, "text": 10114 }, + { "depth": 79, "slug": 10536, "text": 10537 }, + "boxplot-elements", + "Boxplot Elements", + { "depth": 79, "slug": 9894, "text": 7537 }, + { "depth": 33, "slug": 10384, "text": 10385 }, + { "depth": 79, "slug": 10541, "text": 10524 }, + "props-2", + { "depth": 79, "slug": 10543, "text": 1070 }, + "features-1", + { "depth": 79, "slug": 10545, "text": 7537 }, + "example-2", + { "depth": 33, "slug": 9881, "text": 9882 }, + { "depth": 79, "slug": 10548, "text": 10524 }, + "props-3", + { "depth": 79, "slug": 10550, "text": 1070 }, + "features-2", + { "depth": 79, "slug": 10552, "text": 7537 }, + "example-3", + { "depth": 33, "slug": 9801, "text": 9802 }, + { "depth": 79, "slug": 9804, "text": 9805 }, + { "depth": 33, "slug": 10556, "text": 10557 }, + "drill-down-flow", + "Drill-Down Flow", + { "depth": 79, "slug": 1885, "text": 1886 }, + { "depth": 33, "slug": 10560, "text": 10561 }, + "focus-mode", + "Focus Mode", + { "depth": 79, "slug": 10563, "text": 10564 }, + "activation", + "Activation", + { "depth": 79, "slug": 1194, "text": 1195 }, + { "depth": 79, "slug": 10567, "text": 10568 }, + "display-limits", + "Display Limits", + { "depth": 79, "slug": 10570, "text": 1886 }, + "implementation-1", + { "depth": 33, "slug": 1723, "text": 1724 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 10497 }, + [], + "06-design-system/charts/responsive", + { + "id": 10577, + "data": 10579, + "body": 10584, + "filePath": 10585, + "digest": 10586, + "rendered": 10587 + }, + { + "title": 10580, + "editUrl": 16, + "head": 10581, + "template": 18, + "sidebar": 10582, + "pagefind": 16, + "draft": 20 + }, + "Responsive Charts", + [], + { "hidden": 20, "attrs": 10583 }, + {}, + "# Responsive Charts\n\nCharts adapt to container size using responsive utilities.\n\n## Breakpoints\n\n| Name | Width | Typical Usage |\n| ------- | --------- | ---------------------- |\n| Mobile | \u003C 400px | Phone portrait |\n| Tablet | 400-768px | Tablet/phone landscape |\n| Desktop | > 768px | Desktop/laptop |\n\n## Responsive Utilities\n\nImport from `@variscout/charts`:\n\n```tsx\nimport {\n getResponsiveMargins,\n getResponsiveFonts,\n getResponsiveTickCount,\n} from '@variscout/charts';\n```\n\n### Margins\n\n```tsx\nconst margin = getResponsiveMargins(parentWidth, chartType, extraBottom);\n```\n\n**Chart type margins (desktop):**\n\n| Chart | Top | Right | Bottom | Left |\n| ----------- | --- | ----- | ------ | ---- |\n| ichart | 40 | 85 | 60 | 70 |\n| boxplot | 20 | 20 | 60 | 70 |\n| pareto | 20 | 20 | 60 | 70 |\n| histogram | 20 | 20 | 40 | 40 |\n| probability | 20 | 20 | 40 | 50 |\n| scatter | 20 | 20 | 50 | 50 |\n\n**Scaling:**\n\n- Mobile (\u003C 400px): 50-75% of base\n- Tablet (400-768px): 70-85% of base\n- Desktop: 100% of base\n\n### Fonts\n\n```tsx\nconst fonts = getResponsiveFonts(parentWidth);\n// Returns: { tickLabel, axisLabel, statLabel }\n```\n\n| Breakpoint | tickLabel | axisLabel | statLabel |\n| ---------- | --------- | --------- | --------- |\n| \u003C 400px | 8px | 9px | 10px |\n| 400-768px | 9px | 10px | 11px |\n| > 768px | 11px | 13px | 12px |\n\n### Tick Count\n\n```tsx\nconst xTicks = getResponsiveTickCount(parentWidth, 'x');\nconst yTicks = getResponsiveTickCount(parentHeight, 'y');\n```\n\n**X-axis ticks:**\n| Width | Ticks |\n|-------|-------|\n| \u003C 200px | 3 |\n| 200-400px | 5 |\n| 400-600px | 7 |\n| > 600px | 10 |\n\n**Y-axis ticks:**\n| Height | Ticks |\n|--------|-------|\n| \u003C 150px | 3 |\n| 150-250px | 5 |\n| > 250px | 7 |\n\n## Using withParentSize\n\nThe `withParentSize` HOC from Visx handles responsive sizing:\n\n```tsx\nimport { withParentSize } from '@visx/responsive';\n\nconst ChartBase: React.FC\u003CChartProps> = ({ parentWidth, parentHeight, ...props }) => {\n const margin = getResponsiveMargins(parentWidth, 'ichart');\n const fonts = getResponsiveFonts(parentWidth);\n\n const width = parentWidth - margin.left - margin.right;\n const height = parentHeight - margin.top - margin.bottom;\n\n // Render chart...\n};\n\nexport default withParentSize(ChartBase);\n```\n\n## Container Requirements\n\nFor responsive charts to work, the parent container must have defined dimensions:\n\n```tsx\n// PWA - flex container\n\u003Cdiv className=\"flex-1 min-h-0\">\n \u003CIChart data={data} />\n\u003C/div>\n\n// Fixed height\n\u003Cdiv style={{ height: 400 }}>\n \u003CIChart data={data} />\n\u003C/div>\n```\n\n## Mobile Optimizations\n\nAt small sizes, charts automatically:\n\n1. Reduce axis tick count\n2. Shrink margins\n3. Hide axis labels if too crowded\n4. Simplify tooltips\n\n### Example: Hide label on small width\n\n```tsx\n\u003CAxisBottom label={parentWidth > 250 ? 'X Value' : ''} labelOffset={parentWidth \u003C 400 ? 24 : 32} />\n```\n\n## PWA Breakpoints\n\nThe PWA uses Tailwind breakpoints for layout:\n\n| Breakpoint | Width | Usage |\n| ---------- | ------ | --------------------- |\n| sm | 640px | Mobile/desktop toggle |\n| md | 768px | Grid column changes |\n| lg | 1024px | Full desktop layout |\n\n```tsx\n// Mobile detection in Dashboard\nconst MOBILE_BREAKPOINT = 640;\nconst isMobile = window.innerWidth \u003C MOBILE_BREAKPOINT;\n```\n\n## Panel Sizing\n\nDashboard panels use `react-resizable-panels` with:\n\n- Default split: 40% I-Chart / 60% bottom\n- Min size: 20% per panel\n- Persisted to localStorage\n\n```tsx\n\u003CPanelGroup orientation=\"vertical\">\n \u003CPanel defaultSize={40} minSize={20}>\n {/* I-Chart */}\n \u003C/Panel>\n \u003CPanelResizeHandle />\n \u003CPanel defaultSize={60} minSize={20}>\n {/* Bottom charts */}\n \u003C/Panel>\n\u003C/PanelGroup>\n```\n\n---\n\n## See Also\n\n- [Overview](./overview.md) - Chart design system overview and selection guide\n- [Colors](./colors.md) - Data visualization color palette\n- [Hooks](./hooks.md) - useChartLayout for responsive layout", + "src/content/docs/06-design-system/charts/responsive.md", + "6c6103e2df431191", + { "html": 10588, "metadata": 10589 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"responsive-charts\">Responsive Charts\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#responsive-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Responsive Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Charts adapt to container size using responsive utilities.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"breakpoints\">Breakpoints\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#breakpoints\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Breakpoints”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Name\u003C/th>\u003Cth>Width\u003C/th>\u003Cth>Typical Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Mobile\u003C/td>\u003Ctd>< 400px\u003C/td>\u003Ctd>Phone portrait\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tablet\u003C/td>\u003Ctd>400-768px\u003C/td>\u003Ctd>Tablet/phone landscape\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Desktop\u003C/td>\u003Ctd>> 768px\u003C/td>\u003Ctd>Desktop/laptop\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"responsive-utilities\">Responsive Utilities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#responsive-utilities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Responsive Utilities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Import from \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">getResponsiveMargins,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">getResponsiveFonts,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">getResponsiveTickCount,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">} \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { getResponsiveMargins, getResponsiveFonts, getResponsiveTickCount,} from '@variscout/charts';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"margins\">Margins\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#margins\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Margins”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getResponsiveMargins\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartType\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">extraBottom);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const margin = getResponsiveMargins(parentWidth, chartType, extraBottom);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Chart type margins (desktop):\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Chart\u003C/th>\u003Cth>Top\u003C/th>\u003Cth>Right\u003C/th>\u003Cth>Bottom\u003C/th>\u003Cth>Left\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>ichart\u003C/td>\u003Ctd>40\u003C/td>\u003Ctd>85\u003C/td>\u003Ctd>60\u003C/td>\u003Ctd>70\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>boxplot\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>60\u003C/td>\u003Ctd>70\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>pareto\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>60\u003C/td>\u003Ctd>70\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>histogram\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>40\u003C/td>\u003Ctd>40\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>probability\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>40\u003C/td>\u003Ctd>50\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>scatter\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>20\u003C/td>\u003Ctd>50\u003C/td>\u003Ctd>50\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Scaling:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Mobile (< 400px): 50-75% of base\u003C/li>\n\u003Cli>Tablet (400-768px): 70-85% of base\u003C/li>\n\u003Cli>Desktop: 100% of base\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"fonts\">Fonts\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#fonts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Fonts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getResponsiveFonts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(parentWidth);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Returns: { tickLabel, axisLabel, statLabel }\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const fonts = getResponsiveFonts(parentWidth);// Returns: { tickLabel, axisLabel, statLabel }\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Breakpoint\u003C/th>\u003Cth>tickLabel\u003C/th>\u003Cth>axisLabel\u003C/th>\u003Cth>statLabel\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>< 400px\u003C/td>\u003Ctd>8px\u003C/td>\u003Ctd>9px\u003C/td>\u003Ctd>10px\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>400-768px\u003C/td>\u003Ctd>9px\u003C/td>\u003Ctd>10px\u003C/td>\u003Ctd>11px\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>> 768px\u003C/td>\u003Ctd>11px\u003C/td>\u003Ctd>13px\u003C/td>\u003Ctd>12px\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tick-count\">Tick Count\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tick-count\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tick Count”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">xTicks\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getResponsiveTickCount\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">x\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">yTicks\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getResponsiveTickCount\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">y\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const xTicks = getResponsiveTickCount(parentWidth, 'x');const yTicks = getResponsiveTickCount(parentHeight, 'y');\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>X-axis ticks:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Width\u003C/th>\u003Cth>Ticks\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>< 200px\u003C/td>\u003Ctd>3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>200-400px\u003C/td>\u003Ctd>5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>400-600px\u003C/td>\u003Ctd>7\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>> 600px\u003C/td>\u003Ctd>10\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Y-axis ticks:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Height\u003C/th>\u003Cth>Ticks\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>< 150px\u003C/td>\u003Ctd>3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>150-250px\u003C/td>\u003Ctd>5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>> 250px\u003C/td>\u003Ctd>7\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"using-withparentsize\">Using withParentSize\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#using-withparentsize\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Using withParentSize”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">withParentSize\u003C/code> HOC from Visx handles responsive sizing:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { withParentSize } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@visx/responsive\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">ChartBase\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FC\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartProps\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">props\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getResponsiveMargins\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">ichart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getResponsiveFonts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(parentWidth)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> - \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">left\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> - \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">right\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentHeight\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> - \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">top\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> - \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">bottom\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Render chart...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">default\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">withParentSize\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(ChartBase);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { withParentSize } from '@visx/responsive';const ChartBase: React.FC\u003CChartProps> = ({ parentWidth, parentHeight, ...props }) => { const margin = getResponsiveMargins(parentWidth, 'ichart'); const fonts = getResponsiveFonts(parentWidth); const width = parentWidth - margin.left - margin.right; const height = parentHeight - margin.top - margin.bottom; // Render chart...};export default withParentSize(ChartBase);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"container-requirements\">Container Requirements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#container-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Container Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For responsive charts to work, the parent container must have defined dimensions:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PWA - flex container\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-1 min-h-0\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Fixed height\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">style\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ height: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">400\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// PWA - flex container\u003Cdiv className="flex-1 min-h-0"> \u003CIChart data={data} />\u003C/div>// Fixed height\u003Cdiv style={{ height: 400 }}> \u003CIChart data={data} />\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"mobile-optimizations\">Mobile Optimizations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-optimizations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Optimizations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>At small sizes, charts automatically:\u003C/p>\n\u003Col>\n\u003Cli>Reduce axis tick count\u003C/li>\n\u003Cli>Shrink margins\u003C/li>\n\u003Cli>Hide axis labels if too crowded\u003C/li>\n\u003Cli>Simplify tooltips\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-hide-label-on-small-width\">Example: Hide label on small width\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-hide-label-on-small-width\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example: Hide label on small width”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">AxisBottom\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">label\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">250\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">X Value\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">''\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">labelOffset\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">parentWidth\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\"><\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">400\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">24\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">32\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CAxisBottom label={parentWidth > 250 ? 'X Value' : ''} labelOffset={parentWidth \u003C 400 ? 24 : 32} />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pwa-breakpoints\">PWA Breakpoints\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-breakpoints\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA Breakpoints”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA uses Tailwind breakpoints for layout:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Breakpoint\u003C/th>\u003Cth>Width\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>sm\u003C/td>\u003Ctd>640px\u003C/td>\u003Ctd>Mobile/desktop toggle\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>md\u003C/td>\u003Ctd>768px\u003C/td>\u003Ctd>Grid column changes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>lg\u003C/td>\u003Ctd>1024px\u003C/td>\u003Ctd>Full desktop layout\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Mobile detection in Dashboard\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">MOBILE_BREAKPOINT\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">640\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isMobile\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">window\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">innerWidth\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> < \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">MOBILE_BREAKPOINT\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Mobile detection in Dashboardconst MOBILE_BREAKPOINT = 640;const isMobile = window.innerWidth \u003C MOBILE_BREAKPOINT;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"panel-sizing\">Panel Sizing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#panel-sizing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Panel Sizing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Dashboard panels use \u003Ccode dir=\"auto\">react-resizable-panels\u003C/code> with:\u003C/p>\n\u003Cul>\n\u003Cli>Default split: 40% I-Chart / 60% bottom\u003C/li>\n\u003Cli>Min size: 20% per panel\u003C/li>\n\u003Cli>Persisted to localStorage\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PanelGroup\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">orientation\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">vertical\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Panel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">defaultSize\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">40\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">minSize\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* I-Chart */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Panel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PanelResizeHandle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Panel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">defaultSize\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">60\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">minSize\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Bottom charts */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Panel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PanelGroup\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CPanelGroup orientation="vertical"> \u003CPanel defaultSize={40} minSize={20}> {/* I-Chart */} \u003C/Panel> \u003CPanelResizeHandle /> \u003CPanel defaultSize={60} minSize={20}> {/* Bottom charts */} \u003C/Panel>\u003C/PanelGroup>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview and selection guide\u003C/li>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - Data visualization color palette\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - useChartLayout for responsive layout\u003C/li>\n\u003C/ul>", + { + "headings": 10590, + "localImagePaths": 10625, + "remoteImagePaths": 10626, + "frontmatter": 10627, + "imagePaths": 10628 + }, + [10591, 10593, 10594, 10597, 10600, 10603, 10606, 10609, 10612, 10615, 10618, 10621, 10624], + { "depth": 30, "slug": 10592, "text": 10580 }, + "responsive-charts", + { "depth": 33, "slug": 4253, "text": 4254 }, + { "depth": 33, "slug": 10595, "text": 10596 }, + "responsive-utilities", + "Responsive Utilities", + { "depth": 79, "slug": 10598, "text": 10599 }, + "margins", + "Margins", + { "depth": 79, "slug": 10601, "text": 10602 }, + "fonts", + "Fonts", + { "depth": 79, "slug": 10604, "text": 10605 }, + "tick-count", + "Tick Count", + { "depth": 33, "slug": 10607, "text": 10608 }, + "using-withparentsize", + "Using withParentSize", + { "depth": 33, "slug": 10610, "text": 10611 }, + "container-requirements", + "Container Requirements", + { "depth": 33, "slug": 10613, "text": 10614 }, + "mobile-optimizations", + "Mobile Optimizations", + { "depth": 79, "slug": 10616, "text": 10617 }, + "example-hide-label-on-small-width", + "Example: Hide label on small width", + { "depth": 33, "slug": 10619, "text": 10620 }, + "pwa-breakpoints", + "PWA Breakpoints", + { "depth": 33, "slug": 10622, "text": 10623 }, + "panel-sizing", + "Panel Sizing", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 10580 }, + [], + "06-design-system/charts/shared-components", + { + "id": 10629, + "data": 10631, + "body": 10636, + "filePath": 10637, + "digest": 10638, + "rendered": 10639 + }, + { + "title": 10632, + "editUrl": 16, + "head": 10633, + "template": 18, + "sidebar": 10634, + "pagefind": 16, + "draft": 20 + }, + "Shared Chart Components", + [], + { "hidden": 20, "attrs": 10635 }, + {}, + "# Shared Chart Components\n\nReusable components for building consistent charts in `@variscout/charts`.\n\n## Overview\n\nThe charts package provides shared components that enforce visual consistency:\n\n| Component | Purpose |\n| ----------------------- | -------------------------------------- |\n| `SpecLimitLine` | Horizontal spec/control limit lines |\n| `VerticalSpecLimitLine` | Vertical spec limit lines (histograms) |\n| `ChartTooltip` | Standardized tooltip wrapper |\n| `EditableChartTitle` | Click-to-edit title component |\n| `ChartCard` | Card wrapper with header layout |\n| `ChartSignature` | Painter-style branding signature |\n| `ChartSourceBar` | Footer branding bar with sample count |\n\n**Source:** `packages/charts/src/components/`\n\n---\n\n## SpecLimitLine\n\nRenders horizontal specification and control limit lines with consistent styling.\n\n**Source:** `packages/charts/src/components/SpecLimitLine.tsx`\n\n### Props\n\n```typescript\ninterface SpecLimitLineProps {\n value: number; // The limit value\n type: LimitType; // 'usl' | 'lsl' | 'target' | 'ucl' | 'lcl' | 'mean'\n yScale: NumericScale; // Y-scale for positioning\n width: number; // Chart inner width\n fonts: ChartFonts; // Font sizes for label\n showLabel?: boolean; // Show label (default: true)\n labelText?: string; // Custom label text\n labelOffset?: number; // Label position from right (default: 4)\n onLabelClick?: () => void; // Click handler for label\n decimalPlaces?: number; // Value display precision (default: 1)\n}\n```\n\n### Limit Type Styling\n\nEach limit type has predefined color and line style:\n\n| Type | Color | Line Style | Default Label |\n| -------- | ------------------------------ | ---------- | --------------- |\n| `usl` | `chartColors.spec` (red) | Dashed 6,3 | \"USL: {value}\" |\n| `lsl` | `chartColors.spec` (red) | Dashed 6,3 | \"LSL: {value}\" |\n| `target` | `chartColors.target` (green) | Dotted 2,2 | \"Tgt: {value}\" |\n| `ucl` | `chartColors.control` (orange) | Dashed 4,4 | \"UCL: {value}\" |\n| `lcl` | `chartColors.control` (orange) | Dashed 4,4 | \"LCL: {value}\" |\n| `mean` | `chartColors.mean` (blue) | Solid | \"Mean: {value}\" |\n\n### Example\n\n```tsx\nimport { SpecLimitLine } from '@variscout/charts';\n\n\u003CSpecLimitLine\n value={specs.usl}\n type=\"usl\"\n yScale={yScale}\n width={width}\n fonts={fonts}\n onLabelClick={() => onSpecClick?.('usl')}\n/>;\n```\n\n---\n\n## VerticalSpecLimitLine\n\nRenders vertical specification lines for histogram X-axis positioning.\n\n### Props\n\n```typescript\ninterface VerticalSpecLimitLineProps {\n value: number;\n type: LimitType;\n xScale: NumericScale; // X-scale for positioning\n height: number; // Chart inner height\n fonts: ChartFonts;\n showLabel?: boolean;\n labelText?: string;\n}\n```\n\n### Example\n\n```tsx\n\u003CVerticalSpecLimitLine value={specs.lsl} type=\"lsl\" xScale={xScale} height={height} fonts={fonts} />\n```\n\n---\n\n## ChartTooltip\n\nStandardized tooltip wrapper with consistent styling across all charts.\n\n**Source:** `packages/charts/src/components/ChartTooltip.tsx`\n\n### Props\n\n```typescript\ninterface ChartTooltipProps\u003CT> {\n data: T | undefined; // Tooltip data (hidden when undefined)\n isOpen: boolean; // Whether tooltip is visible\n left?: number; // X position from tooltip hook\n top?: number; // Y position from tooltip hook\n margin?: ChartMargins; // Chart margins for offset\n fonts: ChartFonts; // Font sizes\n children: (data: T) => React.ReactNode; // Render function\n applyMarginOffset?: boolean; // Apply margin offset (default: true)\n}\n```\n\n### Styling\n\nUses `chromeColors` for consistent appearance:\n\n- Background: `chromeColors.tooltipBg`\n- Text: `chromeColors.tooltipText`\n- Border: `chromeColors.tooltipBorder`\n- Border radius: 6px\n- Padding: 8px 12px\n\n### Example\n\n```tsx\nimport { ChartTooltip } from '@variscout/charts';\n\n\u003CChartTooltip\n data={tooltipData}\n isOpen={tooltipOpen}\n left={tooltipLeft}\n top={tooltipTop}\n margin={margin}\n fonts={fonts}\n>\n {data => (\n \u003C>\n \u003Cdiv>\n \u003Cstrong>{data.label}\u003C/strong>\n \u003C/div>\n \u003Cdiv>Value: {data.value}\u003C/div>\n \u003C/>\n )}\n\u003C/ChartTooltip>;\n```\n\n### `getTooltipStyle(fonts)`\n\nFor charts that need custom positioning, get the style object directly:\n\n```tsx\nimport { getTooltipStyle } from '@variscout/charts';\n\n\u003CTooltipWithBounds style={getTooltipStyle(fonts)}>{/* Custom content */}\u003C/TooltipWithBounds>;\n```\n\n---\n\n## EditableChartTitle\n\nClick-to-edit chart title with subtle hover indicator.\n\n**Source:** `packages/charts/src/components/EditableChartTitle.tsx`\n\n### Props\n\n```typescript\ninterface EditableChartTitleProps {\n defaultTitle: string; // Auto-generated title (shown when custom is empty)\n value?: string; // Current custom title\n onChange: (newTitle: string) => void;\n className?: string;\n}\n```\n\n### UX Pattern\n\n1. **Display mode:**\n - Shows subtle dashed underline on hover\n - Cursor: text (indicates editable)\n\n2. **Edit mode:**\n - Text input with blue border\n - Text pre-selected for easy replacement\n - Helper text: \"Enter to save - Esc to cancel\"\n\n3. **Saving:**\n - Enter key saves\n - Escape cancels\n - Blur (click outside) saves\n - Empty input reverts to default\n\n### Example\n\n```tsx\nimport { EditableChartTitle } from '@variscout/charts';\n\n\u003Ch2 className=\"text-xl font-bold\">\n \u003CEditableChartTitle\n defaultTitle={`${measureColumn} Control Chart`}\n value={customTitle}\n onChange={setCustomTitle}\n />\n\u003C/h2>;\n```\n\n---\n\n## ChartCard\n\nReusable card wrapper with consistent header layout for chart panels.\n\n**Source:** `packages/charts/src/components/ChartCard.tsx`\n\n### Props\n\n```typescript\ninterface ChartCardProps {\n title: string; // Chart title (auto-generated default)\n icon?: React.ReactNode; // Optional icon component\n\n // Editable title support\n editableTitle?: boolean;\n customTitle?: string;\n onTitleChange?: (title: string) => void;\n\n // Header controls\n controls?: React.ReactNode; // Right-side controls\n actions?: React.ReactNode; // Action buttons (copy, maximize)\n\n children: React.ReactNode; // Chart content\n className?: string;\n id?: string;\n onClick?: () => void;\n}\n```\n\n### Layout\n\n```\n[Icon] [Title (editable?)] .......... [Controls] [Actions]\n[Chart Content]\n```\n\n### Example\n\n```tsx\nimport { ChartCard } from '@variscout/charts';\n\n\u003CChartCard\n title=\"I-Chart\"\n icon={\u003CTrendingUp />}\n editableTitle={true}\n customTitle={chartTitle}\n onTitleChange={setChartTitle}\n controls={\n \u003Cselect value={view} onChange={e => setView(e.target.value)}>\n \u003Coption value=\"all\">All Points\u003C/option>\n \u003Coption value=\"last30\">Last 30\u003C/option>\n \u003C/select>\n }\n actions={\u003Cbutton onClick={onCopy}>Copy\u003C/button>}\n>\n \u003CIChart data={data} specs={specs} />\n\u003C/ChartCard>;\n```\n\n### Styling\n\n- Background: `bg-surface-secondary`\n- Border: `border-edge`\n- Padding: `p-6`\n- Border radius: `rounded-2xl`\n- Shadow: `shadow-xl shadow-black/20`\n\n---\n\n## ChartSignature\n\nPainter-style \"VariScout\" signature mark rendered as SVG text. Only visible for free tier (branding required); hidden for paid tiers via `shouldShowBranding()` from `@variscout/core`.\n\n**Source:** `packages/charts/src/ChartSignature.tsx`\n\n### Props\n\n```typescript\ninterface ChartSignatureProps {\n x: number; // Right edge position\n y: number; // Bottom position (above source bar)\n}\n```\n\n### Mode-Aware Styling\n\n| Mode | Font | Size | Opacity | Text |\n| --------- | ------------------ | ---- | ------- | ----------- |\n| Technical | Caveat (cursive) | 16px | 0.4 | \"VariScout\" |\n| Executive | Inter (sans-serif) | 12px | 0.3 | \"VARISCOUT\" |\n\n---\n\n## ChartSourceBar\n\nFooter bar displaying sample count and branding text. Positioned at the bottom of the chart SVG.\n\n**Source:** `packages/charts/src/ChartSourceBar.tsx`\n\n### Props\n\n```typescript\ninterface ChartSourceBarProps {\n width: number; // Chart inner width\n top: number; // Y position\n n: number; // Sample count\n brandingText?: string;\n}\n```\n\nHeight: 18px (included in bottom margin calculations via `getSourceBarHeight(showBranding)`).\n\nThe branding dot uses `var(--accent-hex)` for its fill color, picking up the company accent when set in Azure App. Falls back to the `accentColor` prop (blue-500) when the variable is absent.\n\n---\n\n## Import Patterns\n\n### Direct Import\n\n```typescript\nimport { SpecLimitLine, ChartTooltip, ChartCard } from '@variscout/charts';\n```\n\n### Components Index\n\nAll shared components are exported from the components barrel:\n\n```typescript\n// packages/charts/src/components/index.ts\nexport { SpecLimitLine, VerticalSpecLimitLine } from './SpecLimitLine';\nexport { ChartTooltip, getTooltipStyle } from './ChartTooltip';\nexport { default as EditableChartTitle } from './EditableChartTitle';\nexport { default as ChartCard } from './ChartCard';\n```\n\n---\n\n## See Also\n\n- [Overview](./overview.md) - Chart design system overview and selection guide\n- [Hooks](./hooks.md) - useChartTooltip hook\n- [Colors](./colors.md) - Chart color constants\n- [Responsive](./responsive.md) - Breakpoints and scaling utilities", + "src/content/docs/06-design-system/charts/shared-components.md", + "7d4f6d07f1012337", + { "html": 10640, "metadata": 10641 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"shared-chart-components\">Shared Chart Components\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#shared-chart-components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Shared Chart Components”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Reusable components for building consistent charts in \u003Ccode dir=\"auto\">@variscout/charts\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The charts package provides shared components that enforce visual consistency:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">SpecLimitLine\u003C/code>\u003C/td>\u003Ctd>Horizontal spec/control limit lines\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">VerticalSpecLimitLine\u003C/code>\u003C/td>\u003Ctd>Vertical spec limit lines (histograms)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChartTooltip\u003C/code>\u003C/td>\u003Ctd>Standardized tooltip wrapper\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">EditableChartTitle\u003C/code>\u003C/td>\u003Ctd>Click-to-edit title component\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChartCard\u003C/code>\u003C/td>\u003Ctd>Card wrapper with header layout\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChartSignature\u003C/code>\u003C/td>\u003Ctd>Painter-style branding signature\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChartSourceBar\u003C/code>\u003C/td>\u003Ctd>Footer branding bar with sample count\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/components/\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"speclimitline\">SpecLimitLine\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#speclimitline\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SpecLimitLine”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Renders horizontal specification and control limit lines with consistent styling.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/components/SpecLimitLine.tsx\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> SpecLimitLineProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// The limit value\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">type\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">LimitType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 'usl' | 'lsl' | 'target' | 'ucl' | 'lcl' | 'mean'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yScale\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">NumericScale\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Y-scale for positioning\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart inner width\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fonts\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartFonts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Font sizes for label\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showLabel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Show label (default: true)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">labelText\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Custom label text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">labelOffset\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Label position from right (default: 4)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onLabelClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Click handler for label\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">decimalPlaces\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Value display precision (default: 1)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface SpecLimitLineProps { value: number; // The limit value type: LimitType; // 'usl' | 'lsl' | 'target' | 'ucl' | 'lcl' | 'mean' yScale: NumericScale; // Y-scale for positioning width: number; // Chart inner width fonts: ChartFonts; // Font sizes for label showLabel?: boolean; // Show label (default: true) labelText?: string; // Custom label text labelOffset?: number; // Label position from right (default: 4) onLabelClick?: () => void; // Click handler for label decimalPlaces?: number; // Value display precision (default: 1)}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"limit-type-styling\">Limit Type Styling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#limit-type-styling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Limit Type Styling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each limit type has predefined color and line style:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Line Style\u003C/th>\u003Cth>Default Label\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">usl\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.spec\u003C/code> (red)\u003C/td>\u003Ctd>Dashed 6,3\u003C/td>\u003Ctd>”USL: {value}“\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">lsl\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.spec\u003C/code> (red)\u003C/td>\u003Ctd>Dashed 6,3\u003C/td>\u003Ctd>”LSL: {value}“\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">target\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.target\u003C/code> (green)\u003C/td>\u003Ctd>Dotted 2,2\u003C/td>\u003Ctd>”Tgt: {value}“\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ucl\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.control\u003C/code> (orange)\u003C/td>\u003Ctd>Dashed 4,4\u003C/td>\u003Ctd>”UCL: {value}“\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">lcl\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.control\u003C/code> (orange)\u003C/td>\u003Ctd>Dashed 4,4\u003C/td>\u003Ctd>”LCL: {value}“\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">mean\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">chartColors.mean\u003C/code> (blue)\u003C/td>\u003Ctd>Solid\u003C/td>\u003Ctd>”Mean: {value}“\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { SpecLimitLine } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">SpecLimitLine\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">usl\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">usl\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">yScale\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">yScale\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fonts\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onLabelClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onSpecClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?.\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">usl\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { SpecLimitLine } from '@variscout/charts';\u003CSpecLimitLine value={specs.usl} type="usl" yScale={yScale} width={width} fonts={fonts} onLabelClick={() => onSpecClick?.('usl')}/>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"verticalspeclimitline\">VerticalSpecLimitLine\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#verticalspeclimitline\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VerticalSpecLimitLine”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Renders vertical specification lines for histogram X-axis positioning.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-1\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> VerticalSpecLimitLineProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">type\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">LimitType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">xScale\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">NumericScale\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// X-scale for positioning\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart inner height\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fonts\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartFonts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">showLabel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">labelText\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface VerticalSpecLimitLineProps { value: number; type: LimitType; xScale: NumericScale; // X-scale for positioning height: number; // Chart inner height fonts: ChartFonts; showLabel?: boolean; labelText?: string;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-1\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">VerticalSpecLimitLine\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">lsl\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">lsl\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">xScale\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">xScale\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">height\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">height\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fonts\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CVerticalSpecLimitLine value={specs.lsl} type="lsl" xScale={xScale} height={height} fonts={fonts} />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"charttooltip\">ChartTooltip\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#charttooltip\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ChartTooltip”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standardized tooltip wrapper with consistent styling across all charts.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/components/ChartTooltip.tsx\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-2\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChartTooltipProps<\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">T\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">T\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Tooltip data (hidden when undefined)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isOpen\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Whether tooltip is visible\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">left\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// X position from tooltip hook\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">top\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Y position from tooltip hook\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartMargins\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart margins for offset\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fonts\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ChartFonts\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Font sizes\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">children\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#FFCB8B\">T\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ReactNode\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Render function\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">applyMarginOffset\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Apply margin offset (default: true)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ChartTooltipProps\u003CT> { data: T | undefined; // Tooltip data (hidden when undefined) isOpen: boolean; // Whether tooltip is visible left?: number; // X position from tooltip hook top?: number; // Y position from tooltip hook margin?: ChartMargins; // Chart margins for offset fonts: ChartFonts; // Font sizes children: (data: T) => React.ReactNode; // Render function applyMarginOffset?: boolean; // Apply margin offset (default: true)}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"styling\">Styling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#styling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Styling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Uses \u003Ccode dir=\"auto\">chromeColors\u003C/code> for consistent appearance:\u003C/p>\n\u003Cul>\n\u003Cli>Background: \u003Ccode dir=\"auto\">chromeColors.tooltipBg\u003C/code>\u003C/li>\n\u003Cli>Text: \u003Ccode dir=\"auto\">chromeColors.tooltipText\u003C/code>\u003C/li>\n\u003Cli>Border: \u003Ccode dir=\"auto\">chromeColors.tooltipBorder\u003C/code>\u003C/li>\n\u003Cli>Border radius: 6px\u003C/li>\n\u003Cli>Padding: 8px 12px\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-2\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { ChartTooltip } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ChartTooltip\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipData\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">isOpen\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipOpen\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">left\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipLeft\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">top\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tooltipTop\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">margin\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">margin\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fonts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">fonts\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">data\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">strong\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">label\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">strong\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Value: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">value\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ChartTooltip\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { ChartTooltip } from '@variscout/charts';\u003CChartTooltip data={tooltipData} isOpen={tooltipOpen} left={tooltipLeft} top={tooltipTop} margin={margin} fonts={fonts}> {data => ( \u003C> \u003Cdiv> \u003Cstrong>{data.label}\u003C/strong> \u003C/div> \u003Cdiv>Value: {data.value}\u003C/div> \u003C/> )}\u003C/ChartTooltip>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"gettooltipstylefonts\">\u003Ccode dir=\"auto\">getTooltipStyle(fonts)\u003C/code>\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#gettooltipstylefonts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “getTooltipStyle(fonts)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For charts that need custom positioning, get the style object directly:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { getTooltipStyle } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">TooltipWithBounds\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">style\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getTooltipStyle\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(fonts)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Custom content */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">TooltipWithBounds\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { getTooltipStyle } from '@variscout/charts';\u003CTooltipWithBounds style={getTooltipStyle(fonts)}>{/* Custom content */}\u003C/TooltipWithBounds>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"editablecharttitle\">EditableChartTitle\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#editablecharttitle\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “EditableChartTitle”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Click-to-edit chart title with subtle hover indicator.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/components/EditableChartTitle.tsx\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-3\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> EditableChartTitleProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">defaultTitle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Auto-generated title (shown when custom is empty)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Current custom title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onChange\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">newTitle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">className\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface EditableChartTitleProps { defaultTitle: string; // Auto-generated title (shown when custom is empty) value?: string; // Current custom title onChange: (newTitle: string) => void; className?: string;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ux-pattern\">UX Pattern\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ux-pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “UX Pattern”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Display mode:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Shows subtle dashed underline on hover\u003C/li>\n\u003Cli>Cursor: text (indicates editable)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Edit mode:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Text input with blue border\u003C/li>\n\u003Cli>Text pre-selected for easy replacement\u003C/li>\n\u003Cli>Helper text: “Enter to save - Esc to cancel”\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Saving:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Enter key saves\u003C/li>\n\u003Cli>Escape cancels\u003C/li>\n\u003Cli>Blur (click outside) saves\u003C/li>\n\u003Cli>Empty input reverts to default\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-3\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-3\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { EditableChartTitle } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xl font-bold\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">EditableChartTitle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">defaultTitle\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measureColumn\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\"> Control Chart\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">customTitle\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setCustomTitle\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { EditableChartTitle } from '@variscout/charts';\u003Ch2 className="text-xl font-bold"> \u003CEditableChartTitle defaultTitle={`${measureColumn} Control Chart`} value={customTitle} onChange={setCustomTitle} />\u003C/h2>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chartcard\">ChartCard\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chartcard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ChartCard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Reusable card wrapper with consistent header layout for chart panels.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/components/ChartCard.tsx\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-4\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChartCardProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">title\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart title (auto-generated default)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">icon\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ReactNode\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Optional icon component\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Editable title support\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">editableTitle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">customTitle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onTitleChange\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">title\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Header controls\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">controls\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ReactNode\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Right-side controls\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">actions\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ReactNode\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Action buttons (copy, maximize)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">children\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> React\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ReactNode\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart content\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">className\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">id\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ChartCardProps { title: string; // Chart title (auto-generated default) icon?: React.ReactNode; // Optional icon component // Editable title support editableTitle?: boolean; customTitle?: string; onTitleChange?: (title: string) => void; // Header controls controls?: React.ReactNode; // Right-side controls actions?: React.ReactNode; // Action buttons (copy, maximize) children: React.ReactNode; // Chart content className?: string; id?: string; onClick?: () => void;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layout\">Layout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Icon] [Title (editable?)] .......... [Controls] [Actions]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Chart Content]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Icon] [Title (editable?)] .......... [Controls] [Actions][Chart Content]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"example-4\">Example\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#example-4\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Example”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { ChartCard } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ChartCard\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">title\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">I-Chart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">icon\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">TrendingUp\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">editableTitle\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">customTitle\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartTitle\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onTitleChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setChartTitle\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">controls\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6;--1:#8844AE\">select\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">view\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setView\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(e\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">target\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">value\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">option\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">all\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">All Points\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">option\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">option\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">last30\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Last 30\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">option\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">select\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">actions\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onCopy\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Copy\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ChartCard\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { ChartCard } from '@variscout/charts';\u003CChartCard title="I-Chart" icon={\u003CTrendingUp />} editableTitle={true} customTitle={chartTitle} onTitleChange={setChartTitle} controls={ \u003Cselect value={view} onChange={e => setView(e.target.value)}> \u003Coption value="all">All Points\u003C/option> \u003Coption value="last30">Last 30\u003C/option> \u003C/select> } actions={\u003Cbutton onClick={onCopy}>Copy\u003C/button>}> \u003CIChart data={data} specs={specs} />\u003C/ChartCard>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"styling-1\">Styling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#styling-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Styling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Background: \u003Ccode dir=\"auto\">bg-surface-secondary\u003C/code>\u003C/li>\n\u003Cli>Border: \u003Ccode dir=\"auto\">border-edge\u003C/code>\u003C/li>\n\u003Cli>Padding: \u003Ccode dir=\"auto\">p-6\u003C/code>\u003C/li>\n\u003Cli>Border radius: \u003Ccode dir=\"auto\">rounded-2xl\u003C/code>\u003C/li>\n\u003Cli>Shadow: \u003Ccode dir=\"auto\">shadow-xl shadow-black/20\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chartsignature\">ChartSignature\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chartsignature\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ChartSignature”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Painter-style “VariScout” signature mark rendered as SVG text. Only visible for free tier (branding required); hidden for paid tiers via \u003Ccode dir=\"auto\">shouldShowBranding()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/ChartSignature.tsx\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-5\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-5\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChartSignatureProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">x\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Right edge position\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">y\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Bottom position (above source bar)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ChartSignatureProps { x: number; // Right edge position y: number; // Bottom position (above source bar)}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"mode-aware-styling\">Mode-Aware Styling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#mode-aware-styling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mode-Aware Styling”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Mode\u003C/th>\u003Cth>Font\u003C/th>\u003Cth>Size\u003C/th>\u003Cth>Opacity\u003C/th>\u003Cth>Text\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Technical\u003C/td>\u003Ctd>Caveat (cursive)\u003C/td>\u003Ctd>16px\u003C/td>\u003Ctd>0.4\u003C/td>\u003Ctd>”VariScout”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Executive\u003C/td>\u003Ctd>Inter (sans-serif)\u003C/td>\u003Ctd>12px\u003C/td>\u003Ctd>0.3\u003C/td>\u003Ctd>”VARISCOUT”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chartsourcebar\">ChartSourceBar\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chartsourcebar\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ChartSourceBar”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Footer bar displaying sample count and branding text. Positioned at the bottom of the chart SVG.\u003C/p>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/charts/src/ChartSourceBar.tsx\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-6\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-6\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChartSourceBarProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">width\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart inner width\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">top\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Y position\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">n\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Sample count\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">brandingText\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface ChartSourceBarProps { width: number; // Chart inner width top: number; // Y position n: number; // Sample count brandingText?: string;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Height: 18px (included in bottom margin calculations via \u003Ccode dir=\"auto\">getSourceBarHeight(showBranding)\u003C/code>).\u003C/p>\n\u003Cp>The branding dot uses \u003Ccode dir=\"auto\">var(--accent-hex)\u003C/code> for its fill color, picking up the company accent when set in Azure App. Falls back to the \u003Ccode dir=\"auto\">accentColor\u003C/code> prop (blue-500) when the variable is absent.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"import-patterns\">Import Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#import-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Import Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"direct-import\">Direct Import\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#direct-import\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Direct Import”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { SpecLimitLine, ChartTooltip, ChartCard } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { SpecLimitLine, ChartTooltip, ChartCard } from '@variscout/charts';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"components-index\">Components Index\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#components-index\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Components Index”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All shared components are exported from the components barrel:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/charts/src/components/index.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { SpecLimitLine, VerticalSpecLimitLine } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./SpecLimitLine\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { ChartTooltip, getTooltipStyle } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./ChartTooltip\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">default\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">as\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> EditableChartTitle } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./EditableChartTitle\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">default\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">as\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ChartCard } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./ChartCard\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export { SpecLimitLine, VerticalSpecLimitLine } from './SpecLimitLine';export { ChartTooltip, getTooltipStyle } from './ChartTooltip';export { default as EditableChartTitle } from './EditableChartTitle';export { default as ChartCard } from './ChartCard';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"./overview.md\">Overview\u003C/a> - Chart design system overview and selection guide\u003C/li>\n\u003Cli>\u003Ca href=\"./hooks.md\">Hooks\u003C/a> - useChartTooltip hook\u003C/li>\n\u003Cli>\u003Ca href=\"./colors.md\">Colors\u003C/a> - Chart color constants\u003C/li>\n\u003Cli>\u003Ca href=\"./responsive.md\">Responsive\u003C/a> - Breakpoints and scaling utilities\u003C/li>\n\u003C/ul>", + { + "headings": 10642, + "localImagePaths": 10713, + "remoteImagePaths": 10714, + "frontmatter": 10715, + "imagePaths": 10716 + }, + [ + 10643, 10645, 10646, 10649, 10650, 10653, 10654, 10657, 10658, 10659, 10662, 10663, 10666, + 10667, 10670, 10673, 10674, 10677, 10678, 10681, 10683, 10686, 10688, 10690, 10693, 10695, + 10698, 10701, 10703, 10706, 10709, 10712 + ], + { "depth": 30, "slug": 10644, "text": 10632 }, + "shared-chart-components", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 10647, "text": 10648 }, + "speclimitline", + "SpecLimitLine", + { "depth": 79, "slug": 10523, "text": 10524 }, + { "depth": 79, "slug": 10651, "text": 10652 }, + "limit-type-styling", + "Limit Type Styling", + { "depth": 79, "slug": 7536, "text": 7537 }, + { "depth": 33, "slug": 10655, "text": 10656 }, + "verticalspeclimitline", + "VerticalSpecLimitLine", + { "depth": 79, "slug": 10533, "text": 10524 }, + { "depth": 79, "slug": 9894, "text": 7537 }, + { "depth": 33, "slug": 10660, "text": 10661 }, + "charttooltip", + "ChartTooltip", + { "depth": 79, "slug": 10541, "text": 10524 }, + { "depth": 79, "slug": 10664, "text": 10665 }, + "styling", + "Styling", + { "depth": 79, "slug": 10545, "text": 7537 }, + { "depth": 79, "slug": 10668, "text": 10669 }, + "gettooltipstylefonts", + "getTooltipStyle(fonts)", + { "depth": 33, "slug": 10671, "text": 10672 }, + "editablecharttitle", + "EditableChartTitle", + { "depth": 79, "slug": 10548, "text": 10524 }, + { "depth": 79, "slug": 10675, "text": 10676 }, + "ux-pattern", + "UX Pattern", + { "depth": 79, "slug": 10552, "text": 7537 }, + { "depth": 33, "slug": 10679, "text": 10680 }, + "chartcard", + "ChartCard", + { "depth": 79, "slug": 10682, "text": 10524 }, + "props-4", + { "depth": 79, "slug": 10684, "text": 10685 }, + "layout", + "Layout", + { "depth": 79, "slug": 10687, "text": 7537 }, + "example-4", + { "depth": 79, "slug": 10689, "text": 10665 }, + "styling-1", + { "depth": 33, "slug": 10691, "text": 10692 }, + "chartsignature", + "ChartSignature", + { "depth": 79, "slug": 10694, "text": 10524 }, + "props-5", + { "depth": 79, "slug": 10696, "text": 10697 }, + "mode-aware-styling", + "Mode-Aware Styling", + { "depth": 33, "slug": 10699, "text": 10700 }, + "chartsourcebar", + "ChartSourceBar", + { "depth": 79, "slug": 10702, "text": 10524 }, + "props-6", + { "depth": 33, "slug": 10704, "text": 10705 }, + "import-patterns", + "Import Patterns", + { "depth": 79, "slug": 10707, "text": 10708 }, + "direct-import", + "Direct Import", + { "depth": 79, "slug": 10710, "text": 10711 }, + "components-index", + "Components Index", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 10632 }, + [], + "06-design-system/components/buttons", + { + "id": 10717, + "data": 10719, + "body": 10724, + "filePath": 10725, + "digest": 10726, + "rendered": 10727 + }, + { + "title": 10720, + "editUrl": 16, + "head": 10721, + "template": 18, + "sidebar": 10722, + "pagefind": 16, + "draft": 20 + }, + "Buttons", + [], + { "hidden": 20, "attrs": 10723 }, + {}, + "# Buttons\n\nButton variants for PWA and Website.\n\n## PWA Buttons (Tailwind)\n\n### Primary Button\n\n```jsx\n\u003Cbutton className=\"bg-blue-600 hover:bg-blue-700 disabled:bg-slate-600 disabled:cursor-not-allowed text-white font-medium px-4 py-2 rounded-lg transition-colors\">\n Save Project\n\u003C/button>\n```\n\n### Secondary Button\n\n```jsx\n\u003Cbutton className=\"bg-slate-700 hover:bg-slate-600 text-slate-300 font-medium px-4 py-2 rounded-lg transition-colors\">\n Cancel\n\u003C/button>\n```\n\n### Danger Button\n\n```jsx\n\u003Cbutton className=\"bg-red-600 hover:bg-red-500 text-white font-medium px-4 py-2 rounded-lg transition-colors\">\n Delete\n\u003C/button>\n```\n\n### Ghost Button\n\n```jsx\n\u003Cbutton className=\"text-slate-400 hover:text-white hover:bg-slate-700 px-3 py-1.5 rounded-lg transition-colors\">\n Reset\n\u003C/button>\n```\n\n### Icon Button\n\n```jsx\n\u003Cbutton className=\"p-2 text-slate-400 hover:text-white hover:bg-slate-800 rounded-lg transition-colors\">\n \u003CSettings size={18} />\n\u003C/button>\n```\n\n### Small Button\n\n```jsx\n\u003Cbutton className=\"px-3 py-1.5 text-xs font-medium bg-blue-600 hover:bg-blue-500 text-white rounded-lg transition-colors\">\n Apply\n\u003C/button>\n```\n\n## Button States\n\n### Disabled\n\n```jsx\n\u003Cbutton disabled className=\"... disabled:opacity-50 disabled:cursor-not-allowed\">\n Saving...\n\u003C/button>\n```\n\n### Loading\n\n```jsx\n\u003Cbutton disabled className=\"... flex items-center gap-2\">\n \u003CLoader2 className=\"animate-spin\" size={16} />\n Saving...\n\u003C/button>\n```\n\n### Active/Selected\n\n```jsx\n\u003Cbutton\n className={`... ${\n isActive ? 'bg-blue-600 text-white' : 'bg-slate-800 text-slate-400 hover:text-white'\n }`}\n>\n Option\n\u003C/button>\n```\n\n## Tab Buttons\n\n```jsx\n\u003Cdiv className=\"flex bg-slate-900/50 p-1 rounded-lg border border-slate-700/50\">\n \u003Cbutton\n className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${\n activeTab === 'summary'\n ? 'bg-slate-700 text-white shadow-sm'\n : 'text-slate-400 hover:text-slate-300'\n }`}\n >\n Summary\n \u003C/button>\n\u003C/div>\n```\n\n## Touch Targets\n\nFor mobile, ensure minimum 44px touch targets:\n\n```jsx\n\u003Cbutton className=\"p-2 ...\" style={{ minWidth: 44, minHeight: 44 }}>\n \u003CIcon size={18} />\n\u003C/button>\n```\n\n## Website Buttons (CSS Classes)\n\nThe website uses CSS component classes (defined in `apps/website/src/styles/global.css`) instead of inline Tailwind classes (PWA).\n\n### Variants\n\n```html\n\u003C!-- Primary — main CTAs -->\n\u003Ca class=\"btn btn-primary\" href=\"/pricing\">Get Started\u003C/a>\n\n\u003C!-- Secondary — alternative actions on light backgrounds -->\n\u003Ca class=\"btn btn-secondary\" href=\"/tools\">Explore Tools\u003C/a>\n\n\u003C!-- Outline — subtle actions on light backgrounds -->\n\u003Ca class=\"btn btn-outline\" href=\"/learn\">Learn More\u003C/a>\n\n\u003C!-- Outline Light — actions on dark backgrounds (hero, footer) -->\n\u003Ca class=\"btn btn-outline-light\" href=\"/cases\">Case Studies\u003C/a>\n```\n\n### Touch Targets\n\nThe base `.btn` class uses `py-2.5` (~40px height). For primary CTAs on landing pages, override to `py-3` to meet the 44px minimum touch target:\n\n```html\n\u003Ca class=\"btn btn-primary py-3\">Start Free\u003C/a>\n```\n\n## Copy Feedback Button\n\nPattern for copy-to-clipboard with visual feedback:\n\n```jsx\nconst [copied, setCopied] = useState(false);\n\n\u003Cbutton\n onClick={handleCopy}\n className={`p-1.5 rounded transition-all ${\n copied ? 'bg-green-500/20 text-green-400' : 'text-slate-500 hover:text-white hover:bg-slate-700'\n }`}\n>\n {copied ? \u003CCheck size={16} /> : \u003CCopy size={16} />}\n\u003C/button>;\n```", + "src/content/docs/06-design-system/components/buttons.md", + "b3affbd9b5c27972", + { "html": 10728, "metadata": 10729 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"buttons\">Buttons\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#buttons\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Buttons”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Button variants for PWA and Website.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pwa-buttons-tailwind\">PWA Buttons (Tailwind)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-buttons-tailwind\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA Buttons (Tailwind)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"primary-button\">Primary Button\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#primary-button\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Primary Button”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-blue-600 hover:bg-blue-700 disabled:bg-slate-600 disabled:cursor-not-allowed text-white font-medium px-4 py-2 rounded-lg transition-colors\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Save Project\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton className="bg-blue-600 hover:bg-blue-700 disabled:bg-slate-600 disabled:cursor-not-allowed text-white font-medium px-4 py-2 rounded-lg transition-colors"> Save Project\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"secondary-button\">Secondary Button\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#secondary-button\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Secondary Button”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-slate-700 hover:bg-slate-600 text-slate-300 font-medium px-4 py-2 rounded-lg transition-colors\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Cancel\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton className="bg-slate-700 hover:bg-slate-600 text-slate-300 font-medium px-4 py-2 rounded-lg transition-colors"> Cancel\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"danger-button\">Danger Button\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#danger-button\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Danger Button”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-red-600 hover:bg-red-500 text-white font-medium px-4 py-2 rounded-lg transition-colors\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Delete\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton className="bg-red-600 hover:bg-red-500 text-white font-medium px-4 py-2 rounded-lg transition-colors"> Delete\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ghost-button\">Ghost Button\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ghost-button\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Ghost Button”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-slate-400 hover:text-white hover:bg-slate-700 px-3 py-1.5 rounded-lg transition-colors\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Reset\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton className="text-slate-400 hover:text-white hover:bg-slate-700 px-3 py-1.5 rounded-lg transition-colors"> Reset\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"icon-button\">Icon Button\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#icon-button\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Icon Button”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-2 text-slate-400 hover:text-white hover:bg-slate-800 rounded-lg transition-colors\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Settings\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">18\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton className="p-2 text-slate-400 hover:text-white hover:bg-slate-800 rounded-lg transition-colors"> \u003CSettings size={18} />\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"small-button\">Small Button\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#small-button\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Small Button”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-3 py-1.5 text-xs font-medium bg-blue-600 hover:bg-blue-500 text-white rounded-lg transition-colors\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Apply\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton className="px-3 py-1.5 text-xs font-medium bg-blue-600 hover:bg-blue-500 text-white rounded-lg transition-colors"> Apply\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"button-states\">Button States\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#button-states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Button States”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"disabled\">Disabled\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#disabled\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Disabled”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">disabled\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">... disabled:opacity-50 disabled:cursor-not-allowed\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Saving...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton disabled className="... disabled:opacity-50 disabled:cursor-not-allowed"> Saving...\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"loading\">Loading\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#loading\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Loading”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">disabled\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">... flex items-center gap-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Loader2\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">animate-spin\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">16\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Saving...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton disabled className="... flex items-center gap-2"> \u003CLoader2 className="animate-spin" size={16} /> Saving...\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"activeselected\">Active/Selected\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#activeselected\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Active/Selected”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">... \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">isActive\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-blue-600 text-white\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-slate-800 text-slate-400 hover:text-white\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Option\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton className={`... ${ isActive ? 'bg-blue-600 text-white' : 'bg-slate-800 text-slate-400 hover:text-white' }`}> Option\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tab-buttons\">Tab Buttons\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tab-buttons\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tab Buttons”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex bg-slate-900/50 p-1 rounded-lg border border-slate-700/50\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">px-4 py-2 rounded-lg text-sm font-medium transition-colors \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">activeTab\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">summary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-slate-700 text-white shadow-sm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-slate-400 hover:text-slate-300\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Summary\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex bg-slate-900/50 p-1 rounded-lg border border-slate-700/50"> \u003Cbutton className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${ activeTab === 'summary' ? 'bg-slate-700 text-white shadow-sm' : 'text-slate-400 hover:text-slate-300' }`} > Summary \u003C/button>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"touch-targets\">Touch Targets\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#touch-targets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Touch Targets”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For mobile, ensure minimum 44px touch targets:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-2 ...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">style\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ minWidth: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">44\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, minHeight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">44\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Icon\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">18\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton className="p-2 ..." style={{ minWidth: 44, minHeight: 44 }}> \u003CIcon size={18} />\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"website-buttons-css-classes\">Website Buttons (CSS Classes)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#website-buttons-css-classes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Buttons (CSS Classes)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The website uses CSS component classes (defined in \u003Ccode dir=\"auto\">apps/website/src/styles/global.css\u003C/code>) instead of inline Tailwind classes (PWA).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variants\">Variants\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variants\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Variants”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"><!-- Primary — main CTAs -->\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">class\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">btn btn-primary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">href\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">/pricing\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Get Started\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"><!-- Secondary — alternative actions on light backgrounds -->\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">class\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">btn btn-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">href\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">/tools\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Explore Tools\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"><!-- Outline — subtle actions on light backgrounds -->\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">class\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">btn btn-outline\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">href\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">/learn\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Learn More\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"><!-- Outline Light — actions on dark backgrounds (hero, footer) -->\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">class\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">btn btn-outline-light\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">href\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">/cases\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Case Studies\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003C!-- Primary — main CTAs -->\u003Ca class="btn btn-primary" href="/pricing">Get Started\u003C/a>\u003C!-- Secondary — alternative actions on light backgrounds -->\u003Ca class="btn btn-secondary" href="/tools">Explore Tools\u003C/a>\u003C!-- Outline — subtle actions on light backgrounds -->\u003Ca class="btn btn-outline" href="/learn">Learn More\u003C/a>\u003C!-- Outline Light — actions on dark backgrounds (hero, footer) -->\u003Ca class="btn btn-outline-light" href="/cases">Case Studies\u003C/a>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"touch-targets-1\">Touch Targets\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#touch-targets-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Touch Targets”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The base \u003Ccode dir=\"auto\">.btn\u003C/code> class uses \u003Ccode dir=\"auto\">py-2.5\u003C/code> (~40px height). For primary CTAs on landing pages, override to \u003Ccode dir=\"auto\">py-3\u003C/code> to meet the 44px minimum touch target:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">class\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">btn btn-primary py-3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Start Free\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ca class="btn btn-primary py-3">Start Free\u003C/a>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"copy-feedback-button\">Copy Feedback Button\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#copy-feedback-button\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Copy Feedback Button”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pattern for copy-to-clipboard with visual feedback:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const [\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">copied\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setCopied\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">] = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useState\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">handleCopy\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">p-1.5 rounded transition-all \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">copied\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-green-500/20 text-green-400\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-slate-500 hover:text-white hover:bg-slate-700\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">copied\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Check\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">16\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Copy\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">16\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const [copied, setCopied] = useState(false);\u003Cbutton onClick={handleCopy} className={`p-1.5 rounded transition-all ${ copied ? 'bg-green-500/20 text-green-400' : 'text-slate-500 hover:text-white hover:bg-slate-700' }`}> {copied ? \u003CCheck size={16} /> : \u003CCopy size={16} />}\u003C/button>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>", + { + "headings": 10730, + "localImagePaths": 10783, + "remoteImagePaths": 10784, + "frontmatter": 10785, + "imagePaths": 10786 + }, + [ + 10731, 10733, 10736, 10739, 10742, 10745, 10748, 10751, 10754, 10757, 10760, 10763, 10766, + 10769, 10772, 10775, 10778, 10780 + ], + { "depth": 30, "slug": 10732, "text": 10720 }, + "buttons", + { "depth": 33, "slug": 10734, "text": 10735 }, + "pwa-buttons-tailwind", + "PWA Buttons (Tailwind)", + { "depth": 79, "slug": 10737, "text": 10738 }, + "primary-button", + "Primary Button", + { "depth": 79, "slug": 10740, "text": 10741 }, + "secondary-button", + "Secondary Button", + { "depth": 79, "slug": 10743, "text": 10744 }, + "danger-button", + "Danger Button", + { "depth": 79, "slug": 10746, "text": 10747 }, + "ghost-button", + "Ghost Button", + { "depth": 79, "slug": 10749, "text": 10750 }, + "icon-button", + "Icon Button", + { "depth": 79, "slug": 10752, "text": 10753 }, + "small-button", + "Small Button", + { "depth": 33, "slug": 10755, "text": 10756 }, + "button-states", + "Button States", + { "depth": 79, "slug": 10758, "text": 10759 }, + "disabled", + "Disabled", + { "depth": 79, "slug": 10761, "text": 10762 }, + "loading", + "Loading", + { "depth": 79, "slug": 10764, "text": 10765 }, + "activeselected", + "Active/Selected", + { "depth": 33, "slug": 10767, "text": 10768 }, + "tab-buttons", + "Tab Buttons", + { "depth": 33, "slug": 10770, "text": 10771 }, + "touch-targets", + "Touch Targets", + { "depth": 33, "slug": 10773, "text": 10774 }, + "website-buttons-css-classes", + "Website Buttons (CSS Classes)", + { "depth": 79, "slug": 10776, "text": 10777 }, + "variants", + "Variants", + { "depth": 79, "slug": 10779, "text": 10771 }, + "touch-targets-1", + { "depth": 33, "slug": 10781, "text": 10782 }, + "copy-feedback-button", + "Copy Feedback Button", + [], + [], + { "title": 10720 }, + [], + "06-design-system/components/cards", + { + "id": 10787, + "data": 10789, + "body": 10794, + "filePath": 10795, + "digest": 10796, + "rendered": 10797 + }, + { + "title": 10790, + "editUrl": 16, + "head": 10791, + "template": 18, + "sidebar": 10792, + "pagefind": 16, + "draft": 20 + }, + "Cards", + [], + { "hidden": 20, "attrs": 10793 }, + {}, + "# Cards\n\nCard components for grouping related content.\n\n---\n\n## Panel Card\n\nUsed for dashboard panels and chart containers.\n\n### PWA (Tailwind)\n\n```tsx\n\u003Cdiv className=\"bg-surface border border-edge rounded-lg p-4\">\n \u003Ch3 className=\"text-content font-semibold mb-2\">Panel Title\u003C/h3>\n \u003Cdiv className=\"text-content-secondary\">Panel content here\u003C/div>\n\u003C/div>\n```\n\n### Variants\n\n| Variant | Use Case | Border |\n| ----------- | --------------- | ----------------------- |\n| Default | Standard panels | `border-edge` |\n| Interactive | Clickable cards | `hover:border-blue-500` |\n| Selected | Active state | `border-blue-500` |\n\n---\n\n## Stats Card\n\nCompact card for displaying statistics.\n\n```tsx\n\u003Cdiv className=\"bg-surface-secondary rounded p-3\">\n \u003Cdiv className=\"text-content-secondary text-xs\">Label\u003C/div>\n \u003Cdiv className=\"text-content text-lg font-mono\">1.45\u003C/div>\n\u003C/div>\n```\n\n### Always-Visible Stats\n\nThe following metrics are always shown in the Stats Panel regardless of whether specification limits are configured:\n\n- **Mean** — arithmetic average\n- **Median** — midpoint value (always shown alongside Mean)\n- **Std Dev** — standard deviation\n- **Samples** — row count (n)\n\n### Spec-Dependent Metrics and Pencil Link (`onEditSpecs`)\n\nSpec-dependent metrics (Pass Rate, Cp, Cpk) require USL or LSL to be set. When no specs are configured, these cards are omitted from the grid.\n\n`StatsPanelBase` shows a pencil link below the metric cards when `onEditSpecs` is provided:\n\n- **No specs:** Shows `✏ Set spec limits`\n- **Specs exist:** Shows `✏ Edit spec limits`\n\nClicking the link calls `onEditSpecs()` — the app wrapper is responsible for opening its SpecEditor popover.\n\n```tsx\n\u003CStatsPanelBase\n stats={stats}\n specs={specs}\n onEditSpecs={() => setIsEditingSpecs(true)}\n // ...other props\n/>\n```\n\nWhen `onEditSpecs` is omitted, no pencil link is shown.\n\n### ColumnCard\n\nIndividual card for each column in the ColumnMapping screen. Displays rich metadata to help users understand their data at a glance.\n\n**Props:**\n\n| Prop | Type | Description |\n| ---------------- | ------------------------------------------------ | ------------------------------------------------- |\n| `column` | `ColumnAnalysis` | Rich column metadata from detectColumns |\n| `role` | `'outcome' \\| 'factor'` | Whether card is in Y or X section |\n| `selected` | `boolean` | Current selection state |\n| `disabled` | `boolean?` | Greyed out (e.g., already used) |\n| `disabledReason` | `string?` | Tooltip explaining why disabled |\n| `alias` | `string?` | Current rename alias |\n| `onSelect` | `() => void` | Selection callback |\n| `onRename` | `(originalName: string, alias: string) => void?` | Rename callback (pencil icon shown when provided) |\n\n**Type badges:**\n\n| Type | Color | Tailwind classes |\n| ----------- | ----- | ------------------------------------ |\n| Numeric | Blue | `bg-blue-500/20 text-blue-400` |\n| Categorical | Green | `bg-emerald-500/20 text-emerald-400` |\n| Date | Amber | `bg-amber-500/20 text-amber-400` |\n| Text | Slate | `bg-slate-500/20 text-slate-400` |\n\n**Card content:**\n\n- **Sample values**: Shows 3–4 values from `column.sampleValues` (all values shown for categorical columns with ≤6 unique values)\n- **Summary line**: Categorical with ≤10 unique → \"N categories\"; otherwise \"N unique\". Appends \"N missing\" when `missingCount > 0`\n- **Missing warning**: Amber `AlertTriangle` icon shown when `missingCount > 0`\n- **Inline rename**: Pencil icon triggers an inline text input. Enter/blur saves, Escape cancels. When aliased, original name shown as subtitle in parentheses\n\n### DataPreviewTable\n\nCollapsible mini table showing the first few rows of data with color-coded column headers.\n\n**Props:**\n\n| Prop | Type | Description |\n| ---------------- | ------------------ | ----------------------------------- |\n| `rows` | `DataRow[]` | Preview rows (first 5 displayed) |\n| `columnAnalysis` | `ColumnAnalysis[]` | Column metadata for header coloring |\n| `totalRows` | `number?` | Total row count for summary display |\n\n**Behavior:**\n\n- **Collapsed by default** — toggle via Table icon button\n- **Color-coded headers**: blue (numeric), emerald (categorical), amber (date), slate (text)\n- **Shows first 5 rows** with monospace values and row numbers\n- **Summary line**: \"N rows · N columns\" shown next to the toggle\n\n### ColumnMapping Spec Section\n\n`ColumnMapping` exposes an optional collapsible spec entry section (`SpecsSection`), collapsed by default. The component accepts rich column metadata via `columnAnalysis` (preferred) or falls back to plain column names via `availableColumns` for backwards compatibility.\n\n**Key props:**\n\n| Prop | Type | Description |\n| ------------------ | ------------------------------------------------ | --------------------------------------- |\n| `columnAnalysis` | `ColumnAnalysis[]?` | Rich metadata (preferred) |\n| `availableColumns` | `string[]?` | Fallback: plain column names |\n| `previewRows` | `DataRow[]?` | Rows for collapsible data preview table |\n| `totalRows` | `number?` | Total row count for summary |\n| `columnAliases` | `Record\u003Cstring, string>?` | Current column rename aliases |\n| `onColumnRename` | `(originalName: string, alias: string) => void?` | Callback when user renames a column |\n| `maxFactors` | `number?` | Max selectable factors (default: 3) |\n\nThis allows users to preview data, rename columns, and enter Target, LSL, and USL before reaching the dashboard.\n\n---\n\n## ChartCard (Accent-Aware Hover)\n\n`ChartCard` from `@variscout/charts` uses CSS for its hover border:\n\n```css\n.chart-card:hover {\n border-color: var(--accent-hex, var(--color-edge-hover, #475569));\n}\n```\n\nWhen a company accent is configured (Azure App), the hover border picks up that color. PWA falls back to `--color-edge-hover`.\n\nSee [Shared Chart Components > ChartCard](../charts/shared-components.md#chartcard) for full props and layout.\n\n---\n\n## See Also\n\n- [Layout Patterns](../patterns/layout.md)\n- [Specification Management](../../03-features/specifications.md)", + "src/content/docs/06-design-system/components/cards.md", + "930d3fd9ac62ed6b", + { "html": 10798, "metadata": 10799 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"cards\">Cards\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#cards\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cards”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Card components for grouping related content.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"panel-card\">Panel Card\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#panel-card\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Panel Card”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Used for dashboard panels and chart containers.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-tailwind\">PWA (Tailwind)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-tailwind\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA (Tailwind)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-surface border border-edge rounded-lg p-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h3\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content font-semibold mb-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Panel Title\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h3\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Panel content here\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="bg-surface border border-edge rounded-lg p-4"> \u003Ch3 className="text-content font-semibold mb-2">Panel Title\u003C/h3> \u003Cdiv className="text-content-secondary">Panel content here\u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variants\">Variants\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variants\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Variants”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variant\u003C/th>\u003Cth>Use Case\u003C/th>\u003Cth>Border\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Default\u003C/td>\u003Ctd>Standard panels\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">border-edge\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Interactive\u003C/td>\u003Ctd>Clickable cards\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">hover:border-blue-500\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Selected\u003C/td>\u003Ctd>Active state\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">border-blue-500\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"stats-card\">Stats Card\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#stats-card\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Stats Card”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Compact card for displaying statistics.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-surface-secondary rounded p-3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content-secondary text-xs\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Label\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content text-lg font-mono\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">1.45\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="bg-surface-secondary rounded p-3"> \u003Cdiv className="text-content-secondary text-xs">Label\u003C/div> \u003Cdiv className="text-content text-lg font-mono">1.45\u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"always-visible-stats\">Always-Visible Stats\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#always-visible-stats\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Always-Visible Stats”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The following metrics are always shown in the Stats Panel regardless of whether specification limits are configured:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Mean\u003C/strong> — arithmetic average\u003C/li>\n\u003Cli>\u003Cstrong>Median\u003C/strong> — midpoint value (always shown alongside Mean)\u003C/li>\n\u003Cli>\u003Cstrong>Std Dev\u003C/strong> — standard deviation\u003C/li>\n\u003Cli>\u003Cstrong>Samples\u003C/strong> — row count (n)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"spec-dependent-metrics-and-pencil-link-oneditspecs\">Spec-Dependent Metrics and Pencil Link (\u003Ccode dir=\"auto\">onEditSpecs\u003C/code>)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#spec-dependent-metrics-and-pencil-link-oneditspecs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Spec-Dependent Metrics and Pencil Link (onEditSpecs)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Spec-dependent metrics (Pass Rate, Cp, Cpk) require USL or LSL to be set. When no specs are configured, these cards are omitted from the grid.\u003C/p>\n\u003Cp>\u003Ccode dir=\"auto\">StatsPanelBase\u003C/code> shows a pencil link below the metric cards when \u003Ccode dir=\"auto\">onEditSpecs\u003C/code> is provided:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>No specs:\u003C/strong> Shows \u003Ccode dir=\"auto\">✏ Set spec limits\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Specs exist:\u003C/strong> Shows \u003Ccode dir=\"auto\">✏ Edit spec limits\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cp>Clicking the link calls \u003Ccode dir=\"auto\">onEditSpecs()\u003C/code> — the app wrapper is responsible for opening its SpecEditor popover.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">StatsPanelBase\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stats\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onEditSpecs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setIsEditingSpecs\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ...other props\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CStatsPanelBase stats={stats} specs={specs} onEditSpecs={() => setIsEditingSpecs(true)} // ...other props/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>When \u003Ccode dir=\"auto\">onEditSpecs\u003C/code> is omitted, no pencil link is shown.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"columncard\">ColumnCard\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#columncard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ColumnCard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Individual card for each column in the ColumnMapping screen. Displays rich metadata to help users understand their data at a glance.\u003C/p>\n\u003Cp>\u003Cstrong>Props:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Prop\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">column\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ColumnAnalysis\u003C/code>\u003C/td>\u003Ctd>Rich column metadata from detectColumns\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">role\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">'outcome' | 'factor'\u003C/code>\u003C/td>\u003Ctd>Whether card is in Y or X section\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">selected\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">boolean\u003C/code>\u003C/td>\u003Ctd>Current selection state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">disabled\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">boolean?\u003C/code>\u003C/td>\u003Ctd>Greyed out (e.g., already used)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">disabledReason\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string?\u003C/code>\u003C/td>\u003Ctd>Tooltip explaining why disabled\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">alias\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string?\u003C/code>\u003C/td>\u003Ctd>Current rename alias\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">onSelect\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">() => void\u003C/code>\u003C/td>\u003Ctd>Selection callback\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">onRename\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(originalName: string, alias: string) => void?\u003C/code>\u003C/td>\u003Ctd>Rename callback (pencil icon shown when provided)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Type badges:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Tailwind classes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Numeric\u003C/td>\u003Ctd>Blue\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-blue-500/20 text-blue-400\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Categorical\u003C/td>\u003Ctd>Green\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-emerald-500/20 text-emerald-400\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Date\u003C/td>\u003Ctd>Amber\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-amber-500/20 text-amber-400\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Text\u003C/td>\u003Ctd>Slate\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-slate-500/20 text-slate-400\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Card content:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Sample values\u003C/strong>: Shows 3–4 values from \u003Ccode dir=\"auto\">column.sampleValues\u003C/code> (all values shown for categorical columns with ≤6 unique values)\u003C/li>\n\u003Cli>\u003Cstrong>Summary line\u003C/strong>: Categorical with ≤10 unique → “N categories”; otherwise “N unique”. Appends “N missing” when \u003Ccode dir=\"auto\">missingCount > 0\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Missing warning\u003C/strong>: Amber \u003Ccode dir=\"auto\">AlertTriangle\u003C/code> icon shown when \u003Ccode dir=\"auto\">missingCount > 0\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Inline rename\u003C/strong>: Pencil icon triggers an inline text input. Enter/blur saves, Escape cancels. When aliased, original name shown as subtitle in parentheses\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"datapreviewtable\">DataPreviewTable\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#datapreviewtable\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “DataPreviewTable”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Collapsible mini table showing the first few rows of data with color-coded column headers.\u003C/p>\n\u003Cp>\u003Cstrong>Props:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Prop\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">rows\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]\u003C/code>\u003C/td>\u003Ctd>Preview rows (first 5 displayed)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">columnAnalysis\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ColumnAnalysis[]\u003C/code>\u003C/td>\u003Ctd>Column metadata for header coloring\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">totalRows\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number?\u003C/code>\u003C/td>\u003Ctd>Total row count for summary display\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Behavior:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Collapsed by default\u003C/strong> — toggle via Table icon button\u003C/li>\n\u003Cli>\u003Cstrong>Color-coded headers\u003C/strong>: blue (numeric), emerald (categorical), amber (date), slate (text)\u003C/li>\n\u003Cli>\u003Cstrong>Shows first 5 rows\u003C/strong> with monospace values and row numbers\u003C/li>\n\u003Cli>\u003Cstrong>Summary line\u003C/strong>: “N rows · N columns” shown next to the toggle\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"columnmapping-spec-section\">ColumnMapping Spec Section\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#columnmapping-spec-section\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ColumnMapping Spec Section”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">ColumnMapping\u003C/code> exposes an optional collapsible spec entry section (\u003Ccode dir=\"auto\">SpecsSection\u003C/code>), collapsed by default. The component accepts rich column metadata via \u003Ccode dir=\"auto\">columnAnalysis\u003C/code> (preferred) or falls back to plain column names via \u003Ccode dir=\"auto\">availableColumns\u003C/code> for backwards compatibility.\u003C/p>\n\u003Cp>\u003Cstrong>Key props:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Prop\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">columnAnalysis\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ColumnAnalysis[]?\u003C/code>\u003C/td>\u003Ctd>Rich metadata (preferred)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">availableColumns\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">string[]?\u003C/code>\u003C/td>\u003Ctd>Fallback: plain column names\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">previewRows\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataRow[]?\u003C/code>\u003C/td>\u003Ctd>Rows for collapsible data preview table\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">totalRows\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number?\u003C/code>\u003C/td>\u003Ctd>Total row count for summary\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">columnAliases\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Record<string, string>?\u003C/code>\u003C/td>\u003Ctd>Current column rename aliases\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">onColumnRename\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">(originalName: string, alias: string) => void?\u003C/code>\u003C/td>\u003Ctd>Callback when user renames a column\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">maxFactors\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">number?\u003C/code>\u003C/td>\u003Ctd>Max selectable factors (default: 3)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>This allows users to preview data, rename columns, and enter Target, LSL, and USL before reaching the dashboard.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chartcard-accent-aware-hover\">ChartCard (Accent-Aware Hover)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chartcard-accent-aware-hover\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ChartCard (Accent-Aware Hover)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">ChartCard\u003C/code> from \u003Ccode dir=\"auto\">@variscout/charts\u003C/code> uses CSS for its hover border:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">.chart-card:hover\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#80CBC4;--1:#096E72\">border-color\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">var\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--accent-hex\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">var\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--color-edge-hover\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--1:#AA0982\">\u003Cspan style=\"--0:#F78C6C\">#\u003C/span>\u003Cspan style=\"--0:#FFEB95\">475569\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\".chart-card:hover { border-color: var(--accent-hex, var(--color-edge-hover, #475569));}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>When a company accent is configured (Azure App), the hover border picks up that color. PWA falls back to \u003Ccode dir=\"auto\">--color-edge-hover\u003C/code>.\u003C/p>\n\u003Cp>See \u003Ca href=\"../charts/shared-components.md#chartcard\">Shared Chart Components > ChartCard\u003C/a> for full props and layout.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../patterns/layout.md\">Layout Patterns\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../03-features/specifications.md\">Specification Management\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 10800, + "localImagePaths": 10832, + "remoteImagePaths": 10833, + "frontmatter": 10834, + "imagePaths": 10835 + }, + [10801, 10803, 10806, 10809, 10810, 10813, 10816, 10819, 10822, 10825, 10828, 10831], + { "depth": 30, "slug": 10802, "text": 10790 }, + "cards", + { "depth": 33, "slug": 10804, "text": 10805 }, + "panel-card", + "Panel Card", + { "depth": 79, "slug": 10807, "text": 10808 }, + "pwa-tailwind", + "PWA (Tailwind)", + { "depth": 79, "slug": 10776, "text": 10777 }, + { "depth": 33, "slug": 10811, "text": 10812 }, + "stats-card", + "Stats Card", + { "depth": 79, "slug": 10814, "text": 10815 }, + "always-visible-stats", + "Always-Visible Stats", + { "depth": 79, "slug": 10817, "text": 10818 }, + "spec-dependent-metrics-and-pencil-link-oneditspecs", + "Spec-Dependent Metrics and Pencil Link (onEditSpecs)", + { "depth": 79, "slug": 10820, "text": 10821 }, + "columncard", + "ColumnCard", + { "depth": 79, "slug": 10823, "text": 10824 }, + "datapreviewtable", + "DataPreviewTable", + { "depth": 79, "slug": 10826, "text": 10827 }, + "columnmapping-spec-section", + "ColumnMapping Spec Section", + { "depth": 33, "slug": 10829, "text": 10830 }, + "chartcard-accent-aware-hover", + "ChartCard (Accent-Aware Hover)", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 10790 }, + [], + "06-design-system/components/forms", + { + "id": 10836, + "data": 10838, + "body": 10843, + "filePath": 10844, + "digest": 10845, + "rendered": 10846 + }, + { + "title": 10839, + "editUrl": 16, + "head": 10840, + "template": 18, + "sidebar": 10841, + "pagefind": 16, + "draft": 20 + }, + "Form Elements", + [], + { "hidden": 20, "attrs": 10842 }, + {}, + "# Form Elements\n\nForm input patterns using semantic Tailwind tokens for theme-aware styling.\n\n## Text Input\n\n```jsx\n\u003Cinput\n type=\"text\"\n placeholder=\"Enter value\"\n className=\"w-full px-3 py-2 bg-surface border border-edge rounded-lg text-content text-sm placeholder-content-muted outline-none focus:border-blue-500 transition-colors\"\n/>\n```\n\n## Number Input\n\n```jsx\n\u003Cinput\n type=\"number\"\n step=\"0.01\"\n className=\"w-full px-3 py-2 bg-surface border border-edge rounded-lg text-content text-sm font-mono text-right outline-none focus:border-blue-500\"\n/>\n```\n\n## Select Dropdown\n\n```jsx\n\u003Cselect className=\"bg-surface border border-edge text-content rounded-lg px-3 py-2 text-sm outline-none focus:border-blue-500 cursor-pointer\">\n \u003Coption value=\"\">Select...\u003C/option>\n \u003Coption value=\"a\">Option A\u003C/option>\n \u003Coption value=\"b\">Option B\u003C/option>\n\u003C/select>\n```\n\n### Small Select\n\n```jsx\n\u003Cselect className=\"bg-surface border border-edge text-xs text-content rounded px-2 py-1 outline-none focus:border-blue-500\">\n ...\n\u003C/select>\n```\n\n## Checkbox\n\n```jsx\n\u003Clabel className=\"flex items-center gap-2 cursor-pointer\">\n \u003Cinput\n type=\"checkbox\"\n checked={checked}\n onChange={e => setChecked(e.target.checked)}\n className=\"w-4 h-4 rounded border-edge bg-surface text-blue-600 focus:ring-blue-500 focus:ring-offset-surface\"\n />\n \u003Cspan className=\"text-sm text-content-secondary\">Show Cpk\u003C/span>\n\u003C/label>\n```\n\n## Radio Group\n\n```jsx\n\u003Cdiv className=\"flex flex-col gap-2\">\n {options.map(option => (\n \u003Clabel key={option.value} className=\"flex items-center gap-2 cursor-pointer\">\n \u003Cinput\n type=\"radio\"\n name=\"group\"\n value={option.value}\n checked={selected === option.value}\n onChange={() => setSelected(option.value)}\n className=\"w-4 h-4 border-edge bg-surface text-blue-600\"\n />\n \u003Cspan className=\"text-sm text-content-secondary\">{option.label}\u003C/span>\n \u003C/label>\n ))}\n\u003C/div>\n```\n\n## Toggle Switch (Custom)\n\n```jsx\n\u003Cbutton\n onClick={() => setEnabled(!enabled)}\n className={`relative w-10 h-6 rounded-full transition-colors ${\n enabled ? 'bg-blue-600' : 'bg-slate-600'\n }`}\n>\n \u003Cspan\n className={`absolute top-1 w-4 h-4 bg-white rounded-full transition-transform ${\n enabled ? 'left-5' : 'left-1'\n }`}\n />\n\u003C/button>\n```\n\n## Form Field with Label\n\n```jsx\n\u003Cdiv className=\"flex flex-col gap-1.5\">\n \u003Clabel className=\"text-xs text-content-secondary font-medium\">Upper Spec Limit (USL)\u003C/label>\n \u003Cinput\n type=\"number\"\n className=\"px-3 py-2 bg-surface border border-edge rounded-lg text-content\"\n />\n\u003C/div>\n```\n\n## Inline Form\n\n```jsx\n\u003Cdiv className=\"flex items-center gap-2\">\n \u003Clabel className=\"text-sm text-content-secondary whitespace-nowrap\">Factor:\u003C/label>\n \u003Cselect className=\"flex-1 bg-surface border border-edge ...\">...\u003C/select>\n\u003C/div>\n```\n\n## Input with Button\n\n```jsx\n\u003Cdiv className=\"flex\">\n \u003Cinput className=\"flex-1 px-3 py-2 bg-surface border border-edge rounded-l-lg text-content\" />\n \u003Cbutton className=\"px-4 py-2 bg-blue-600 text-white rounded-r-lg\">Apply\u003C/button>\n\u003C/div>\n```\n\n## File Input\n\n```jsx\n\u003Clabel className=\"flex items-center justify-center gap-2 px-4 py-3 border-2 border-dashed border-edge rounded-xl cursor-pointer hover:border-blue-500 hover:bg-surface-secondary/50 transition-colors\">\n \u003CUpload className=\"text-content-secondary\" />\n \u003Cspan className=\"text-sm text-content-secondary\">Drop file or click to browse\u003C/span>\n \u003Cinput type=\"file\" className=\"hidden\" onChange={handleFile} />\n\u003C/label>\n```\n\n## Validation States\n\n### Error\n\n```jsx\n\u003Cinput className=\"... border-red-500 focus:border-red-500\" />\n\u003Cspan className=\"text-xs text-red-400 mt-1\">Invalid value\u003C/span>\n```\n\n### Success\n\n```jsx\n\u003Cinput className=\"... border-green-500\" />\n```\n\n## Disabled State\n\n```jsx\n\u003Cinput disabled className=\"... opacity-50 cursor-not-allowed bg-surface-secondary\" />\n```\n\n## Segmented Control (Factor Selector)\n\nModern pill-button control for selecting from limited options.\n\nLocation: `packages/ui/src/components/FactorSelector/`\n\n```jsx\n\u003Cdiv className=\"inline-flex bg-surface rounded-lg p-0.5 border border-edge\">\n {options.map(option => (\n \u003Cbutton\n key={option}\n onClick={() => onChange(option)}\n className={`\n px-2.5 py-1 text-xs font-medium rounded-md transition-all relative\n ${\n selected === option\n ? 'bg-blue-600 text-white shadow-sm'\n : 'text-content-secondary hover:text-content hover:bg-surface-secondary'\n }\n `}\n >\n {option}\n {hasIndicator && selected === option && (\n \u003Cspan className=\"absolute -top-1 -right-1 w-2 h-2 bg-amber-500 rounded-full border border-surface\" />\n )}\n \u003C/button>\n ))}\n\u003C/div>\n```\n\n### Use Cases\n\n- Factor selection in Boxplot/Pareto charts\n- Tab-like selection with visual indicator\n- When options are 2-5 items (use dropdown for more)\n\n### States\n\n- **Default**: Secondary text on transparent\n- **Selected**: White text on blue background\n- **Indicator**: Amber dot when filter active on selection", + "src/content/docs/06-design-system/components/forms.md", + "e8e741bad652d174", + { "html": 10847, "metadata": 10848 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"form-elements\">Form Elements\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#form-elements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Form Elements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Form input patterns using semantic Tailwind tokens for theme-aware styling.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"text-input\">Text Input\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#text-input\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Text Input”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">placeholder\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Enter value\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">w-full px-3 py-2 bg-surface border border-edge rounded-lg text-content text-sm placeholder-content-muted outline-none focus:border-blue-500 transition-colors\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cinput type="text" placeholder="Enter value" className="w-full px-3 py-2 bg-surface border border-edge rounded-lg text-content text-sm placeholder-content-muted outline-none focus:border-blue-500 transition-colors"/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"number-input\">Number Input\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#number-input\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Number Input”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">step\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">0.01\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">w-full px-3 py-2 bg-surface border border-edge rounded-lg text-content text-sm font-mono text-right outline-none focus:border-blue-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cinput type="number" step="0.01" className="w-full px-3 py-2 bg-surface border border-edge rounded-lg text-content text-sm font-mono text-right outline-none focus:border-blue-500"/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"select-dropdown\">Select Dropdown\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#select-dropdown\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Select Dropdown”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">select\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-surface border border-edge text-content rounded-lg px-3 py-2 text-sm outline-none focus:border-blue-500 cursor-pointer\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">option\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Select...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">option\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">option\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">a\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Option A\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">option\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">option\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">b\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Option B\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">option\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">select\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cselect className="bg-surface border border-edge text-content rounded-lg px-3 py-2 text-sm outline-none focus:border-blue-500 cursor-pointer"> \u003Coption value="">Select...\u003C/option> \u003Coption value="a">Option A\u003C/option> \u003Coption value="b">Option B\u003C/option>\u003C/select>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"small-select\">Small Select\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#small-select\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Small Select”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">select\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-surface border border-edge text-xs text-content rounded px-2 py-1 outline-none focus:border-blue-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">select\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cselect className="bg-surface border border-edge text-xs text-content rounded px-2 py-1 outline-none focus:border-blue-500"> ...\u003C/select>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"checkbox\">Checkbox\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#checkbox\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Checkbox”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center gap-2 cursor-pointer\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">checkbox\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">checked\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">checked\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setChecked\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">e\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">target\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">checked\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">w-4 h-4 rounded border-edge bg-surface text-blue-600 focus:ring-blue-500 focus:ring-offset-surface\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm text-content-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Show Cpk\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Clabel className="flex items-center gap-2 cursor-pointer"> \u003Cinput type="checkbox" checked={checked} onChange={e => setChecked(e.target.checked)} className="w-4 h-4 rounded border-edge bg-surface text-blue-600 focus:ring-blue-500 focus:ring-offset-surface" /> \u003Cspan className="text-sm text-content-secondary">Show Cpk\u003C/span>\u003C/label>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"radio-group\">Radio Group\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#radio-group\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Radio Group”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col gap-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">options\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">option\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">option\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">value\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center gap-2 cursor-pointer\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">radio\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">name\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">group\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">option\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">value\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">checked\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">selected\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">===\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">option\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">value\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setSelected\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">option\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">value\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">w-4 h-4 border-edge bg-surface text-blue-600\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm text-content-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">option\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">label\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex flex-col gap-2"> {options.map(option => ( \u003Clabel key={option.value} className="flex items-center gap-2 cursor-pointer"> \u003Cinput type="radio" name="group" value={option.value} checked={selected === option.value} onChange={() => setSelected(option.value)} className="w-4 h-4 border-edge bg-surface text-blue-600" /> \u003Cspan className="text-sm text-content-secondary">{option.label}\u003C/span> \u003C/label> ))}\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"toggle-switch-custom\">Toggle Switch (Custom)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#toggle-switch-custom\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Toggle Switch (Custom)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setEnabled\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">enabled\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">relative w-10 h-6 rounded-full transition-colors \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">enabled\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-blue-600\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-slate-600\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">absolute top-1 w-4 h-4 bg-white rounded-full transition-transform \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">enabled\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">left-5\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">left-1\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton onClick={() => setEnabled(!enabled)} className={`relative w-10 h-6 rounded-full transition-colors ${ enabled ? 'bg-blue-600' : 'bg-slate-600' }`}> \u003Cspan className={`absolute top-1 w-4 h-4 bg-white rounded-full transition-transform ${ enabled ? 'left-5' : 'left-1' }`} />\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"form-field-with-label\">Form Field with Label\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#form-field-with-label\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Form Field with Label”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col gap-1.5\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs text-content-secondary font-medium\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Upper Spec Limit (USL)\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-3 py-2 bg-surface border border-edge rounded-lg text-content\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex flex-col gap-1.5"> \u003Clabel className="text-xs text-content-secondary font-medium">Upper Spec Limit (USL)\u003C/label> \u003Cinput type="number" className="px-3 py-2 bg-surface border border-edge rounded-lg text-content" />\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"inline-form\">Inline Form\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#inline-form\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Inline Form”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center gap-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm text-content-secondary whitespace-nowrap\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Factor:\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">select\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-1 bg-surface border border-edge ...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">select\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex items-center gap-2"> \u003Clabel className="text-sm text-content-secondary whitespace-nowrap">Factor:\u003C/label> \u003Cselect className="flex-1 bg-surface border border-edge ...">...\u003C/select>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"input-with-button\">Input with Button\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#input-with-button\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input with Button”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-1 px-3 py-2 bg-surface border border-edge rounded-l-lg text-content\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-4 py-2 bg-blue-600 text-white rounded-r-lg\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Apply\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex"> \u003Cinput className="flex-1 px-3 py-2 bg-surface border border-edge rounded-l-lg text-content" /> \u003Cbutton className="px-4 py-2 bg-blue-600 text-white rounded-r-lg">Apply\u003C/button>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"file-input\">File Input\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#file-input\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “File Input”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center justify-center gap-2 px-4 py-3 border-2 border-dashed border-edge rounded-xl cursor-pointer hover:border-blue-500 hover:bg-surface-secondary/50 transition-colors\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Upload\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm text-content-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Drop file or click to browse\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">file\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">hidden\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">handleFile\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Clabel className="flex items-center justify-center gap-2 px-4 py-3 border-2 border-dashed border-edge rounded-xl cursor-pointer hover:border-blue-500 hover:bg-surface-secondary/50 transition-colors"> \u003CUpload className="text-content-secondary" /> \u003Cspan className="text-sm text-content-secondary">Drop file or click to browse\u003C/span> \u003Cinput type="file" className="hidden" onChange={handleFile} />\u003C/label>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"validation-states\">Validation States\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#validation-states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Validation States”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"error\">Error\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#error\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Error”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">... border-red-500 focus:border-red-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs text-red-400 mt-1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Invalid value\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cinput className="... border-red-500 focus:border-red-500" />\u003Cspan className="text-xs text-red-400 mt-1">Invalid value\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"success\">Success\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#success\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">... border-green-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cinput className="... border-green-500" />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"disabled-state\">Disabled State\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#disabled-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Disabled State”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">disabled\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">... opacity-50 cursor-not-allowed bg-surface-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cinput disabled className="... opacity-50 cursor-not-allowed bg-surface-secondary" />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"segmented-control-factor-selector\">Segmented Control (Factor Selector)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#segmented-control-factor-selector\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Segmented Control (Factor Selector)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Modern pill-button control for selecting from limited options.\u003C/p>\n\u003Cp>Location: \u003Ccode dir=\"auto\">packages/ui/src/components/FactorSelector/\u003C/code>\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">inline-flex bg-surface rounded-lg p-0.5 border border-edge\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">options\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">option\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">option\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onChange\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">option\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">px-2.5 py-1 text-xs font-medium rounded-md transition-all relative\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">selected\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">option\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-blue-600 text-white shadow-sm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content-secondary hover:text-content hover:bg-surface-secondary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">option\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">hasIndicator\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">selected\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">===\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">option\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">absolute -top-1 -right-1 w-2 h-2 bg-amber-500 rounded-full border border-surface\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="inline-flex bg-surface rounded-lg p-0.5 border border-edge"> {options.map(option => ( \u003Cbutton key={option} onClick={() => onChange(option)} className={` px-2.5 py-1 text-xs font-medium rounded-md transition-all relative ${ selected === option ? 'bg-blue-600 text-white shadow-sm' : 'text-content-secondary hover:text-content hover:bg-surface-secondary' } `} > {option} {hasIndicator && selected === option && ( \u003Cspan className="absolute -top-1 -right-1 w-2 h-2 bg-amber-500 rounded-full border border-surface" /> )} \u003C/button> ))}\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"use-cases\">Use Cases\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#use-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Cases”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Factor selection in Boxplot/Pareto charts\u003C/li>\n\u003Cli>Tab-like selection with visual indicator\u003C/li>\n\u003Cli>When options are 2-5 items (use dropdown for more)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"states\">States\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “States”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Default\u003C/strong>: Secondary text on transparent\u003C/li>\n\u003Cli>\u003Cstrong>Selected\u003C/strong>: White text on blue background\u003C/li>\n\u003Cli>\u003Cstrong>Indicator\u003C/strong>: Amber dot when filter active on selection\u003C/li>\n\u003C/ul>", + { + "headings": 10849, + "localImagePaths": 10904, + "remoteImagePaths": 10905, + "frontmatter": 10906, + "imagePaths": 10907 + }, + [ + 10850, 10852, 10855, 10858, 10861, 10864, 10867, 10870, 10873, 10876, 10879, 10882, 10885, + 10888, 10891, 10894, 10897, 10900, 10901 + ], + { "depth": 30, "slug": 10851, "text": 10839 }, + "form-elements", + { "depth": 33, "slug": 10853, "text": 10854 }, + "text-input", + "Text Input", + { "depth": 33, "slug": 10856, "text": 10857 }, + "number-input", + "Number Input", + { "depth": 33, "slug": 10859, "text": 10860 }, + "select-dropdown", + "Select Dropdown", + { "depth": 79, "slug": 10862, "text": 10863 }, + "small-select", + "Small Select", + { "depth": 33, "slug": 10865, "text": 10866 }, + "checkbox", + "Checkbox", + { "depth": 33, "slug": 10868, "text": 10869 }, + "radio-group", + "Radio Group", + { "depth": 33, "slug": 10871, "text": 10872 }, + "toggle-switch-custom", + "Toggle Switch (Custom)", + { "depth": 33, "slug": 10874, "text": 10875 }, + "form-field-with-label", + "Form Field with Label", + { "depth": 33, "slug": 10877, "text": 10878 }, + "inline-form", + "Inline Form", + { "depth": 33, "slug": 10880, "text": 10881 }, + "input-with-button", + "Input with Button", + { "depth": 33, "slug": 10883, "text": 10884 }, + "file-input", + "File Input", + { "depth": 33, "slug": 10886, "text": 10887 }, + "validation-states", + "Validation States", + { "depth": 79, "slug": 10889, "text": 10890 }, + "error", + "Error", + { "depth": 79, "slug": 10892, "text": 10893 }, + "success", + "Success", + { "depth": 33, "slug": 10895, "text": 10896 }, + "disabled-state", + "Disabled State", + { "depth": 33, "slug": 10898, "text": 10899 }, + "segmented-control-factor-selector", + "Segmented Control (Factor Selector)", + { "depth": 79, "slug": 907, "text": 908 }, + { "depth": 79, "slug": 10902, "text": 10903 }, + "states", + "States", + [], + [], + { "title": 10839 }, + [], + "06-design-system/components/modals", + { + "id": 10908, + "data": 10910, + "body": 10915, + "filePath": 10916, + "digest": 10917, + "rendered": 10918 + }, + { + "title": 10911, + "editUrl": 16, + "head": 10912, + "template": 18, + "sidebar": 10913, + "pagefind": 16, + "draft": 20 + }, + "Modals", + [], + { "hidden": 20, "attrs": 10914 }, + {}, + "# Modals\n\nModal dialog patterns for PWA.\n\n## Standard Modal\n\n```jsx\n{\n isOpen && (\n \u003Cdiv className=\"fixed inset-0 z-50 bg-black/60 backdrop-blur-sm flex items-center justify-center p-4\">\n \u003Cdiv className=\"bg-slate-800 border border-slate-700 rounded-2xl shadow-2xl w-full max-w-lg\">\n {/* Header */}\n \u003Cdiv className=\"flex items-center justify-between p-6 border-b border-slate-700\">\n \u003Ch2 className=\"text-lg font-semibold text-white\">Modal Title\u003C/h2>\n \u003Cbutton\n onClick={onClose}\n className=\"p-2 text-slate-400 hover:text-white hover:bg-slate-700 rounded-lg\"\n >\n \u003CX size={20} />\n \u003C/button>\n \u003C/div>\n\n {/* Body */}\n \u003Cdiv className=\"p-6 max-h-[60vh] overflow-y-auto\">Content goes here\u003C/div>\n\n {/* Footer */}\n \u003Cdiv className=\"flex justify-end gap-3 p-4 border-t border-slate-700\">\n \u003Cbutton className=\"px-4 py-2 text-slate-400 hover:text-white\">Cancel\u003C/button>\n \u003Cbutton className=\"px-4 py-2 bg-blue-600 text-white rounded-lg\">Confirm\u003C/button>\n \u003C/div>\n \u003C/div>\n \u003C/div>\n );\n}\n```\n\n## Confirmation Modal\n\nCompact modal for confirmations:\n\n```jsx\n\u003Cdiv className=\"bg-slate-800 border border-slate-700 rounded-xl shadow-xl p-4 w-full max-w-sm\">\n \u003Ch3 className=\"text-sm font-semibold text-white mb-2\">Reset Analysis?\u003C/h3>\n \u003Cp className=\"text-xs text-slate-400 mb-4\">All data will be cleared. This cannot be undone.\u003C/p>\n \u003Cdiv className=\"flex justify-end gap-2\">\n \u003Cbutton className=\"px-3 py-1.5 text-xs text-slate-400 hover:text-white\">Cancel\u003C/button>\n \u003Cbutton className=\"px-3 py-1.5 text-xs bg-red-600 text-white rounded-lg\">Reset\u003C/button>\n \u003C/div>\n\u003C/div>\n```\n\n## Full-Screen Modal\n\nFor expanded chart views:\n\n```jsx\n\u003Cdiv className=\"fixed inset-0 z-50 bg-slate-900/95 flex flex-col\">\n {/* Header */}\n \u003Cdiv className=\"flex items-center justify-between p-4 border-b border-slate-700\">\n \u003Cdiv className=\"flex items-center gap-3\">\n \u003CTrendingUp className=\"text-blue-400\" />\n \u003Ch2 className=\"text-lg font-semibold text-white\">Chart Title\u003C/h2>\n \u003C/div>\n \u003Cbutton onClick={onClose} className=\"p-2 text-slate-400 hover:text-white\">\n \u003CX size={20} />\n \u003C/button>\n \u003C/div>\n\n {/* Full chart area */}\n \u003Cdiv className=\"flex-1 p-4\">\n \u003CChart />\n \u003C/div>\n\n {/* Footer stats */}\n \u003Cdiv className=\"p-4 border-t border-slate-700 bg-slate-800/50\">Stats bar\u003C/div>\n\u003C/div>\n```\n\n## Sheet/Drawer (Mobile)\n\nSlide-up panel for mobile:\n\n```jsx\n\u003Cdiv className=\"fixed inset-0 z-50 bg-black/50\">\n \u003Cdiv className=\"absolute bottom-0 left-0 right-0 bg-slate-800 rounded-t-2xl max-h-[85vh] flex flex-col\">\n {/* Drag handle */}\n \u003Cdiv className=\"flex justify-center py-3\">\n \u003Cdiv className=\"w-10 h-1 bg-slate-600 rounded-full\" />\n \u003C/div>\n\n {/* Content */}\n \u003Cdiv className=\"flex-1 overflow-y-auto p-4\">Content\u003C/div>\n \u003C/div>\n\u003C/div>\n```\n\n## Modal Sizing\n\n| Size | Max Width | Usage |\n| ---- | ------------------- | --------------- |\n| sm | `max-w-sm` (384px) | Confirmations |\n| md | `max-w-md` (448px) | Simple forms |\n| lg | `max-w-lg` (512px) | Standard modals |\n| xl | `max-w-xl` (576px) | Complex content |\n| 2xl | `max-w-2xl` (672px) | Data tables |\n\n## Keyboard Handling\n\n```jsx\nuseEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n}, [onClose]);\n```\n\n## Backdrop\n\nStandard backdrop with blur:\n\n```jsx\nclassName = 'fixed inset-0 z-50 bg-black/60 backdrop-blur-sm';\n```\n\nFor less prominent modals:\n\n```jsx\nclassName = 'fixed inset-0 z-50 bg-black/40';\n```\n\n## Z-Index Scale\n\n| Level | z-index | Usage |\n| ------- | --------- | -------------------- |\n| Modal | `z-50` | Standard modals |\n| Tooltip | `z-[60]` | Tooltips over modals |\n| Toast | `z-[100]` | Notifications |", + "src/content/docs/06-design-system/components/modals.md", + "5040b9ddd5ed465e", + { "html": 10919, "metadata": 10920 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"modals\">Modals\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#modals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Modals”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Modal dialog patterns for PWA.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"standard-modal\">Standard Modal\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#standard-modal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Modal”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">isOpen\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">fixed inset-0 z-50 bg-black/60 backdrop-blur-sm flex items-center justify-center p-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-slate-800 border border-slate-700 rounded-2xl shadow-2xl w-full max-w-lg\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Header */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center justify-between p-6 border-b border-slate-700\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-lg font-semibold text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Modal Title\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">onClose\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-2 text-slate-400 hover:text-white hover:bg-slate-700 rounded-lg\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">X\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Body */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-6 max-h-[60vh] overflow-y-auto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Content goes here\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Footer */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex justify-end gap-3 p-4 border-t border-slate-700\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-4 py-2 text-slate-400 hover:text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Cancel\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-4 py-2 bg-blue-600 text-white rounded-lg\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Confirm\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{ isOpen && ( \u003Cdiv className="fixed inset-0 z-50 bg-black/60 backdrop-blur-sm flex items-center justify-center p-4"> \u003Cdiv className="bg-slate-800 border border-slate-700 rounded-2xl shadow-2xl w-full max-w-lg"> {/* Header */} \u003Cdiv className="flex items-center justify-between p-6 border-b border-slate-700"> \u003Ch2 className="text-lg font-semibold text-white">Modal Title\u003C/h2> \u003Cbutton onClick={onClose} className="p-2 text-slate-400 hover:text-white hover:bg-slate-700 rounded-lg" > \u003CX size={20} /> \u003C/button> \u003C/div> {/* Body */} \u003Cdiv className="p-6 max-h-[60vh] overflow-y-auto">Content goes here\u003C/div> {/* Footer */} \u003Cdiv className="flex justify-end gap-3 p-4 border-t border-slate-700"> \u003Cbutton className="px-4 py-2 text-slate-400 hover:text-white">Cancel\u003C/button> \u003Cbutton className="px-4 py-2 bg-blue-600 text-white rounded-lg">Confirm\u003C/button> \u003C/div> \u003C/div> \u003C/div> );}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"confirmation-modal\">Confirmation Modal\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#confirmation-modal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Confirmation Modal”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Compact modal for confirmations:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-slate-800 border border-slate-700 rounded-xl shadow-xl p-4 w-full max-w-sm\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h3\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm font-semibold text-white mb-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Reset Analysis?\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h3\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs text-slate-400 mb-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">All data will be cleared. This cannot be undone.\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex justify-end gap-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-3 py-1.5 text-xs text-slate-400 hover:text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Cancel\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-3 py-1.5 text-xs bg-red-600 text-white rounded-lg\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Reset\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="bg-slate-800 border border-slate-700 rounded-xl shadow-xl p-4 w-full max-w-sm"> \u003Ch3 className="text-sm font-semibold text-white mb-2">Reset Analysis?\u003C/h3> \u003Cp className="text-xs text-slate-400 mb-4">All data will be cleared. This cannot be undone.\u003C/p> \u003Cdiv className="flex justify-end gap-2"> \u003Cbutton className="px-3 py-1.5 text-xs text-slate-400 hover:text-white">Cancel\u003C/button> \u003Cbutton className="px-3 py-1.5 text-xs bg-red-600 text-white rounded-lg">Reset\u003C/button> \u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"full-screen-modal\">Full-Screen Modal\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#full-screen-modal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Full-Screen Modal”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For expanded chart views:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">fixed inset-0 z-50 bg-slate-900/95 flex flex-col\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Header */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center justify-between p-4 border-b border-slate-700\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center gap-3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">TrendingUp\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-blue-400\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-lg font-semibold text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Chart Title\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">onClose\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-2 text-slate-400 hover:text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">X\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Full chart area */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-1 p-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Chart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Footer stats */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-4 border-t border-slate-700 bg-slate-800/50\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Stats bar\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="fixed inset-0 z-50 bg-slate-900/95 flex flex-col"> {/* Header */} \u003Cdiv className="flex items-center justify-between p-4 border-b border-slate-700"> \u003Cdiv className="flex items-center gap-3"> \u003CTrendingUp className="text-blue-400" /> \u003Ch2 className="text-lg font-semibold text-white">Chart Title\u003C/h2> \u003C/div> \u003Cbutton onClick={onClose} className="p-2 text-slate-400 hover:text-white"> \u003CX size={20} /> \u003C/button> \u003C/div> {/* Full chart area */} \u003Cdiv className="flex-1 p-4"> \u003CChart /> \u003C/div> {/* Footer stats */} \u003Cdiv className="p-4 border-t border-slate-700 bg-slate-800/50">Stats bar\u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sheetdrawer-mobile\">Sheet/Drawer (Mobile)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sheetdrawer-mobile\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sheet/Drawer (Mobile)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Slide-up panel for mobile:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">fixed inset-0 z-50 bg-black/50\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">absolute bottom-0 left-0 right-0 bg-slate-800 rounded-t-2xl max-h-[85vh] flex flex-col\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Drag handle */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex justify-center py-3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">w-10 h-1 bg-slate-600 rounded-full\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Content */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-1 overflow-y-auto p-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Content\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="fixed inset-0 z-50 bg-black/50"> \u003Cdiv className="absolute bottom-0 left-0 right-0 bg-slate-800 rounded-t-2xl max-h-[85vh] flex flex-col"> {/* Drag handle */} \u003Cdiv className="flex justify-center py-3"> \u003Cdiv className="w-10 h-1 bg-slate-600 rounded-full" /> \u003C/div> {/* Content */} \u003Cdiv className="flex-1 overflow-y-auto p-4">Content\u003C/div> \u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"modal-sizing\">Modal Sizing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#modal-sizing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Modal Sizing”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Size\u003C/th>\u003Cth>Max Width\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>sm\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">max-w-sm\u003C/code> (384px)\u003C/td>\u003Ctd>Confirmations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>md\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">max-w-md\u003C/code> (448px)\u003C/td>\u003Ctd>Simple forms\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>lg\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">max-w-lg\u003C/code> (512px)\u003C/td>\u003Ctd>Standard modals\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>xl\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">max-w-xl\u003C/code> (576px)\u003C/td>\u003Ctd>Complex content\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2xl\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">max-w-2xl\u003C/code> (672px)\u003C/td>\u003Ctd>Data tables\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyboard-handling\">Keyboard Handling\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyboard-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyboard Handling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useEffect\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleKeyDown\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#FFCB8B\">KeyboardEvent\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">e\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> === \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Escape\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onClose\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">window\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addEventListener\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">keydown\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">handleKeyDown\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">window\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeEventListener\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">keydown\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">handleKeyDown\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">}, [\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">onClose\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">]);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown);}, [onClose]);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"backdrop\">Backdrop\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#backdrop\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Backdrop”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standard backdrop with blur:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">className\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">fixed inset-0 z-50 bg-black/60 backdrop-blur-sm\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"className = 'fixed inset-0 z-50 bg-black/60 backdrop-blur-sm';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>For less prominent modals:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">className\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">fixed inset-0 z-50 bg-black/40\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"className = 'fixed inset-0 z-50 bg-black/40';\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"z-index-scale\">Z-Index Scale\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#z-index-scale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Z-Index Scale”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Level\u003C/th>\u003Cth>z-index\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Modal\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">z-50\u003C/code>\u003C/td>\u003Ctd>Standard modals\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tooltip\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">z-[60]\u003C/code>\u003C/td>\u003Ctd>Tooltips over modals\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Toast\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">z-[100]\u003C/code>\u003C/td>\u003Ctd>Notifications\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 10921, + "localImagePaths": 10948, + "remoteImagePaths": 10949, + "frontmatter": 10950, + "imagePaths": 10951 + }, + [10922, 10924, 10927, 10930, 10933, 10936, 10939, 10942, 10945], + { "depth": 30, "slug": 10923, "text": 10911 }, + "modals", + { "depth": 33, "slug": 10925, "text": 10926 }, + "standard-modal", + "Standard Modal", + { "depth": 33, "slug": 10928, "text": 10929 }, + "confirmation-modal", + "Confirmation Modal", + { "depth": 33, "slug": 10931, "text": 10932 }, + "full-screen-modal", + "Full-Screen Modal", + { "depth": 33, "slug": 10934, "text": 10935 }, + "sheetdrawer-mobile", + "Sheet/Drawer (Mobile)", + { "depth": 33, "slug": 10937, "text": 10938 }, + "modal-sizing", + "Modal Sizing", + { "depth": 33, "slug": 10940, "text": 10941 }, + "keyboard-handling", + "Keyboard Handling", + { "depth": 33, "slug": 10943, "text": 10944 }, + "backdrop", + "Backdrop", + { "depth": 33, "slug": 10946, "text": 10947 }, + "z-index-scale", + "Z-Index Scale", + [], + [], + { "title": 10911 }, + [], + "06-design-system/components/variation-funnel", + { + "id": 10952, + "data": 10954, + "body": 10959, + "filePath": 10960, + "digest": 10961, + "rendered": 10962 + }, + { + "title": 10955, + "editUrl": 16, + "head": 10956, + "template": 18, + "sidebar": 10957, + "pagefind": 16, + "draft": 20 + }, + "Variation Bar", + [], + { "hidden": 20, "attrs": 10958 }, + {}, + "# Variation Bar\n\nA visual progress bar showing variation scope in the drill-down breadcrumb.\n\n## Overview\n\nThe Variation Bar provides immediate visual feedback about what fraction of total variation is in focus through the current filter path. It appears below the breadcrumb navigation when filters are active.\n\n## Usage\n\n```tsx\nimport { VariationBar } from '@variscout/ui';\n\n\u003CVariationBar isolatedPct={60} showLabels={true} className=\"max-w-xs\" />;\n```\n\n## Props\n\n| Prop | Type | Default | Description |\n| ----------- | ----------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| isolatedPct | number | required | Percentage (0-100) of variation in focus |\n| showLabels | boolean | true | Show text labels below bar |\n| className | string | '' | Additional CSS classes for container |\n| colorScheme | VariationBarColorScheme | defaultColorScheme | Color scheme (semantic tokens, used by both PWA and Azure) |\n| onClick | () => void | undefined | Click handler --- opens the Investigation Mindmap panel when provided. Adds `cursor-pointer`, `role=\"button\"`, `tabIndex`, and keyboard support (Enter/Space). |\n\n## Visual Design\n\n```\n[████████████░░░░░░░░] 60% in focus | 40% outside scope\n ← colored → ← gray →\n```\n\n**Structure:**\n\n- Container: Flexbox column with 4px gap\n- Bar: 8px height, full width, rounded-full\n- Background: `bg-surface-tertiary/50`\n- Left segment: Colored based on impact level\n- Labels: 10px text, muted color\n\n## Color Rules\n\nUses `getVariationImpactLevel()` from `@variscout/core`:\n\n| Threshold | Impact Level | Bar Color | Text Color |\n| --------- | ------------ | -------------- | ---------------- |\n| ≥ 50% | high | `bg-green-500` | `text-green-400` |\n| 30-50% | moderate | `bg-amber-500` | `text-amber-400` |\n| \u003C 30% | low | `bg-blue-500` | `text-blue-400` |\n\n## Responsive Behavior\n\n- **Desktop:** Shows bar + labels below\n- **Mobile:** Set `showLabels={false}` to show bar only\n\n```tsx\n// Responsive usage in FilterBreadcrumb\n\u003CVariationBar isolatedPct={cumulativeVariationPct} showLabels={!isMobile} className=\"max-w-xs\" />\n```\n\n## Tooltip\n\nOn hover, displays a tooltip with:\n\n1. **Percentage header:** \"Focused on 60% of total variation\"\n2. **Insight text:** From `getVariationInsight()` (e.g., \"This combination accounts for more than half your total variation — strong focus.\")\n3. **Impact description:** \"High impact — strong case for action\"\n\n**Tooltip styling:**\n\n- Background: `bg-surface-secondary`\n- Border: `border-edge`\n- Position: Centered above bar\n- Arrow: Rotated square pointing down\n\n## Integration\n\n### In FilterBreadcrumb\n\n```tsx\n// FilterBreadcrumb uses VariationBar from @variscout/ui\n{\n cumulativeVariationPct !== undefined && (\n \u003CVariationBar\n isolatedPct={cumulativeVariationPct}\n showLabels={true}\n className=\"mt-2\"\n onClick={onOpenInvestigation}\n />\n );\n}\n```\n\n### Core Dependencies\n\n```typescript\nimport { getVariationImpactLevel, getVariationInsight } from '@variscout/core';\n\n// getVariationImpactLevel(60) → 'high'\n// getVariationInsight(60) → \"Fix this combination...\"\n```\n\n## Animations\n\n- Bar width: `transition-all duration-300` for smooth resize\n- Tooltip: `opacity-0 invisible` → `opacity-100 visible` on hover\n\n## Accessibility\n\n- Bar has no explicit ARIA role (decorative visual)\n- Labels provide text alternative for percentage values\n- Tooltip content duplicates label information with more context\n\n## Files\n\n| File | Purpose |\n| ---------------------------------------------------------- | ---------------------------------------------------- |\n| `packages/ui/src/components/VariationBar/VariationBar.tsx` | Shared component (PWA and Azure) |\n| `packages/ui/src/components/VariationBar/index.ts` | Barrel re-export |\n| `packages/core/src/navigation.ts` | `getVariationImpactLevel()`, `getVariationInsight()` |\n\n## Related Components\n\n- `FilterBreadcrumb.tsx` — Parent component that displays VariationBar\n- `InvestigationMindmap.tsx` — Uses same color scheme for node sizing\n- `@variscout/core` — Shared threshold constants and insight helpers", + "src/content/docs/06-design-system/components/variation-funnel.md", + "6a4e4123244adb15", + { "html": 10963, "metadata": 10964 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"variation-bar\">Variation Bar\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#variation-bar\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Variation Bar”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A visual progress bar showing variation scope in the drill-down breadcrumb.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Variation Bar provides immediate visual feedback about what fraction of total variation is in focus through the current filter path. It appears below the breadcrumb navigation when filters are active.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"usage\">Usage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { VariationBar } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">VariationBar\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">isolatedPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">60\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">showLabels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">max-w-xs\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { VariationBar } from '@variscout/ui';\u003CVariationBar isolatedPct={60} showLabels={true} className="max-w-xs" />;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"props\">Props\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#props\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Prop\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>isolatedPct\u003C/td>\u003Ctd>number\u003C/td>\u003Ctd>required\u003C/td>\u003Ctd>Percentage (0-100) of variation in focus\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>showLabels\u003C/td>\u003Ctd>boolean\u003C/td>\u003Ctd>true\u003C/td>\u003Ctd>Show text labels below bar\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>className\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>”\u003C/td>\u003Ctd>Additional CSS classes for container\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>colorScheme\u003C/td>\u003Ctd>VariationBarColorScheme\u003C/td>\u003Ctd>defaultColorScheme\u003C/td>\u003Ctd>Color scheme (semantic tokens, used by both PWA and Azure)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>onClick\u003C/td>\u003Ctd>() => void\u003C/td>\u003Ctd>undefined\u003C/td>\u003Ctd>Click handler --- opens the Investigation Mindmap panel when provided. Adds \u003Ccode dir=\"auto\">cursor-pointer\u003C/code>, \u003Ccode dir=\"auto\">role=\"button\"\u003C/code>, \u003Ccode dir=\"auto\">tabIndex\u003C/code>, and keyboard support (Enter/Space).\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"visual-design\">Visual Design\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#visual-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[████████████░░░░░░░░] 60% in focus | 40% outside scope\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">← colored → ← gray →\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[████████████░░░░░░░░] 60% in focus | 40% outside scope ← colored → ← gray →\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Structure:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Container: Flexbox column with 4px gap\u003C/li>\n\u003Cli>Bar: 8px height, full width, rounded-full\u003C/li>\n\u003Cli>Background: \u003Ccode dir=\"auto\">bg-surface-tertiary/50\u003C/code>\u003C/li>\n\u003Cli>Left segment: Colored based on impact level\u003C/li>\n\u003Cli>Labels: 10px text, muted color\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"color-rules\">Color Rules\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#color-rules\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color Rules”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Uses \u003Ccode dir=\"auto\">getVariationImpactLevel()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core\u003C/code>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Threshold\u003C/th>\u003Cth>Impact Level\u003C/th>\u003Cth>Bar Color\u003C/th>\u003Cth>Text Color\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>≥ 50%\u003C/td>\u003Ctd>high\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-green-500\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-green-400\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>30-50%\u003C/td>\u003Ctd>moderate\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-amber-500\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-amber-400\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>< 30%\u003C/td>\u003Ctd>low\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-blue-500\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-blue-400\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"responsive-behavior\">Responsive Behavior\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#responsive-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Responsive Behavior”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Desktop:\u003C/strong> Shows bar + labels below\u003C/li>\n\u003Cli>\u003Cstrong>Mobile:\u003C/strong> Set \u003Ccode dir=\"auto\">showLabels={false}\u003C/code> to show bar only\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Responsive usage in FilterBreadcrumb\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">VariationBar\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">isolatedPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cumulativeVariationPct\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">showLabels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isMobile\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">max-w-xs\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Responsive usage in FilterBreadcrumb\u003CVariationBar isolatedPct={cumulativeVariationPct} showLabels={!isMobile} className="max-w-xs" />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tooltip\">Tooltip\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tooltip\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tooltip”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>On hover, displays a tooltip with:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Percentage header:\u003C/strong> “Focused on 60% of total variation”\u003C/li>\n\u003Cli>\u003Cstrong>Insight text:\u003C/strong> From \u003Ccode dir=\"auto\">getVariationInsight()\u003C/code> (e.g., “This combination accounts for more than half your total variation — strong focus.”)\u003C/li>\n\u003Cli>\u003Cstrong>Impact description:\u003C/strong> “High impact — strong case for action”\u003C/li>\n\u003C/ol>\n\u003Cp>\u003Cstrong>Tooltip styling:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>Background: \u003Ccode dir=\"auto\">bg-surface-secondary\u003C/code>\u003C/li>\n\u003Cli>Border: \u003Ccode dir=\"auto\">border-edge\u003C/code>\u003C/li>\n\u003Cli>Position: Centered above bar\u003C/li>\n\u003Cli>Arrow: Rotated square pointing down\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"integration\">Integration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"in-filterbreadcrumb\">In FilterBreadcrumb\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#in-filterbreadcrumb\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “In FilterBreadcrumb”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// FilterBreadcrumb uses VariationBar from @variscout/ui\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cumulativeVariationPct \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!==\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">VariationBar\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">isolatedPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cumulativeVariationPct\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">showLabels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">mt-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">onOpenInvestigation\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// FilterBreadcrumb uses VariationBar from @variscout/ui{ cumulativeVariationPct !== undefined && ( \u003CVariationBar isolatedPct={cumulativeVariationPct} showLabels={true} className="mt-2" onClick={onOpenInvestigation} /> );}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"core-dependencies\">Core Dependencies\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#core-dependencies\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Dependencies”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { getVariationImpactLevel, getVariationInsight } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/core\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// getVariationImpactLevel(60) → 'high'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// getVariationInsight(60) → \"Fix this combination...\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { getVariationImpactLevel, getVariationInsight } from '@variscout/core';// getVariationImpactLevel(60) → 'high'// getVariationInsight(60) → "Fix this combination..."\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"animations\">Animations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#animations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Animations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Bar width: \u003Ccode dir=\"auto\">transition-all duration-300\u003C/code> for smooth resize\u003C/li>\n\u003Cli>Tooltip: \u003Ccode dir=\"auto\">opacity-0 invisible\u003C/code> → \u003Ccode dir=\"auto\">opacity-100 visible\u003C/code> on hover\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"accessibility\">Accessibility\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#accessibility\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Accessibility”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Bar has no explicit ARIA role (decorative visual)\u003C/li>\n\u003Cli>Labels provide text alternative for percentage values\u003C/li>\n\u003Cli>Tooltip content duplicates label information with more context\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"files\">Files\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#files\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Files”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/VariationBar/VariationBar.tsx\u003C/code>\u003C/td>\u003Ctd>Shared component (PWA and Azure)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/VariationBar/index.ts\u003C/code>\u003C/td>\u003Ctd>Barrel re-export\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">packages/core/src/navigation.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">getVariationImpactLevel()\u003C/code>, \u003Ccode dir=\"auto\">getVariationInsight()\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-components\">Related Components\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Components”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">FilterBreadcrumb.tsx\u003C/code> — Parent component that displays VariationBar\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">InvestigationMindmap.tsx\u003C/code> — Uses same color scheme for node sizing\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">@variscout/core\u003C/code> — Shared threshold constants and insight helpers\u003C/li>\n\u003C/ul>", + { + "headings": 10965, + "localImagePaths": 10996, + "remoteImagePaths": 10997, + "frontmatter": 10998, + "imagePaths": 10999 + }, + [ + 10966, 10968, 10969, 10970, 10971, 10972, 10975, 10976, 10977, 10980, 10983, 10986, 10989, + 10990, 10993 + ], + { "depth": 30, "slug": 10967, "text": 10955 }, + "variation-bar", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 2008, "text": 2009 }, + { "depth": 33, "slug": 10523, "text": 10524 }, + { "depth": 33, "slug": 3686, "text": 3687 }, + { "depth": 33, "slug": 10973, "text": 10974 }, + "color-rules", + "Color Rules", + { "depth": 33, "slug": 10421, "text": 10422 }, + { "depth": 33, "slug": 9962, "text": 9963 }, + { "depth": 33, "slug": 10978, "text": 10979 }, + "integration", + "Integration", + { "depth": 79, "slug": 10981, "text": 10982 }, + "in-filterbreadcrumb", + "In FilterBreadcrumb", + { "depth": 79, "slug": 10984, "text": 10985 }, + "core-dependencies", + "Core Dependencies", + { "depth": 33, "slug": 10987, "text": 10988 }, + "animations", + "Animations", + { "depth": 33, "slug": 3565, "text": 3566 }, + { "depth": 33, "slug": 10991, "text": 10992 }, + "files", + "Files", + { "depth": 33, "slug": 10994, "text": 10995 }, + "related-components", + "Related Components", + [], + [], + { "title": 10955 }, + [], + "06-design-system/components/what-if-simulator", + { + "id": 11000, + "data": 11002, + "body": 11007, + "filePath": 11008, + "digest": 11009, + "rendered": 11010 + }, + { + "title": 11003, + "editUrl": 16, + "head": 11004, + "template": 18, + "sidebar": 11005, + "pagefind": 16, + "draft": 20 + }, + "What-If Simulator", + [], + { "hidden": 20, "attrs": 11006 }, + {}, + "# What-If Simulator\n\nInteractive component for exploring process improvement scenarios.\n\n---\n\n## Purpose\n\nThe What-If Simulator allows users to explore hypothetical improvements:\n\n- \"What if we reduced variation in Factor X by 50%?\"\n- \"What would happen to Cpk if we centered the process?\"\n- \"How much defect reduction would we see?\"\n\n---\n\n## Shared Components\n\nBoth PWA and Azure App use shared components from `@variscout/ui`:\n\n| Component | Package | Purpose |\n| ----------------- | --------------- | ---------------------------------------------------- |\n| `WhatIfSimulator` | `@variscout/ui` | Standard simulator with mean-shift/variation sliders |\n| `WhatIfPageBase` | `@variscout/ui` | Full-page wrapper with back navigation |\n| `Slider` | `@variscout/ui` | Reusable range slider for factor adjustments |\n\n**Source:** `packages/ui/src/components/WhatIfSimulator/`, `packages/ui/src/components/WhatIfPage/`\n\n---\n\n## WhatIfSimulator\n\nCollapsible panel with factor-level reduction sliders and projected Cpk improvement.\n\n### Props\n\n```typescript\ninterface WhatIfSimulatorProps {\n currentStats: { mean: number; stdDev: number; cpk?: number };\n specs?: { usl?: number; lsl?: number; target?: number };\n defaultExpanded?: boolean;\n presets?: SimulatorPreset[];\n isExpanded?: boolean;\n onExpandChange?: (expanded: boolean) => void;\n initialPreset?: SimulatorPreset | null;\n colorScheme?: WhatIfSimulatorColorScheme;\n /** Cpk target for color thresholds (default 1.33) */\n cpkTarget?: number;\n}\n```\n\n### User Interaction\n\n1. Select a factor from drill-down results\n2. Adjust the \"reduction\" slider (0-100%)\n3. See projected impact on:\n - Cpk improvement\n - Defect reduction\n - Variation reduction\n\nUses `simulateDirectAdjustment()` from `@variscout/core` for projection calculations.\n\n### Smart Presets\n\nThe simulator auto-computes up to 6 one-click presets based on current stats and [characteristic type](../../../03-features/analysis/characteristic-types.md):\n\n| # | Preset | Logic |\n| --- | --------------- | ---------------------------------- |\n| 1 | Shift to target | Mean shift to target/midpoint |\n| 2 | Shift to median | Corrects skew |\n| 3 | Match best | Direction-aware best category mean |\n| 4 | Tighten spread | Match tightest category's std dev |\n| 5 | Reach 95% yield | Reverse-calc shift/reduction |\n| 6 | Best of both | Combine #3 + #4 |\n\nPreset 3 (\"Match best\") uses the characteristic type: for smaller-is-better, it targets the category with the lowest mean; for larger-is-better, the highest mean; for nominal, the closest to target.\n\n---\n\n## WhatIfPageBase\n\nFull-page view wrapping the simulator with navigation header and data context.\n\n### Props\n\n```typescript\ninterface WhatIfPageBaseProps {\n filteredData: DataRow[];\n rawData: DataRow[];\n outcome: string | null;\n specs: SpecLimits;\n filterCount: number;\n filterNames?: string[];\n onBack: () => void;\n colorScheme?: WhatIfPageColorScheme;\n simulatorColorScheme?: WhatIfSimulatorColorScheme;\n /** Cpk target for color thresholds */\n cpkTarget?: number;\n}\n```\n\n### Rendering\n\n`WhatIfPageBase` renders the standard `WhatIfSimulator` in its default expanded state, providing mean-shift and variation-reduction sliders for direct adjustment simulation.\n\n### Color Schemes\n\nAll components follow the standard colorScheme pattern:\n\n- `whatIfPageDefaultColorScheme` — Semantic tokens (used by both PWA and Azure)\n- `whatIfSimulatorDefaultColorScheme` — Semantic tokens (used by both PWA and Azure)\n\nThe `WhatIfSimulatorColorScheme` includes `improvementPositive` and `improvementNegative` for directional change indicators (Cpk/yield improvement or decline), and `cpkGood`/`cpkOk`/`cpkBad` for Cpk status coloring.\n\n---\n\n## See Also\n\n- [Variation Bar](variation-funnel.md) - Visual progress of isolated variation\n- [Drill-Down Feature](../../03-features/navigation/drill-down.md)", + "src/content/docs/06-design-system/components/what-if-simulator.md", + "8a2ca759e22ea39c", + { "html": 11011, "metadata": 11012 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"what-if-simulator\">What-If Simulator\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#what-if-simulator\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What-If Simulator”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Interactive component for exploring process improvement scenarios.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose\">Purpose\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The What-If Simulator allows users to explore hypothetical improvements:\u003C/p>\n\u003Cul>\n\u003Cli>“What if we reduced variation in Factor X by 50%?”\u003C/li>\n\u003Cli>“What would happen to Cpk if we centered the process?”\u003C/li>\n\u003Cli>“How much defect reduction would we see?”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"shared-components\">Shared Components\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#shared-components\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Shared Components”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both PWA and Azure App use shared components from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Package\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">WhatIfSimulator\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Standard simulator with mean-shift/variation sliders\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">WhatIfPageBase\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Full-page wrapper with back navigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Slider\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003Ctd>Reusable range slider for factor adjustments\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Source:\u003C/strong> \u003Ccode dir=\"auto\">packages/ui/src/components/WhatIfSimulator/\u003C/code>, \u003Ccode dir=\"auto\">packages/ui/src/components/WhatIfPage/\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whatifsimulator\">WhatIfSimulator\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whatifsimulator\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “WhatIfSimulator”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Collapsible panel with factor-level reduction sliders and projected Cpk improvement.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> WhatIfSimulatorProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">currentStats\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { mean\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; stdDev\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; cpk\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> };\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { usl\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; lsl\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; target\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> };\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">defaultExpanded\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">presets\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SimulatorPreset\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">isExpanded\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onExpandChange\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">expanded\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">boolean\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">initialPreset\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SimulatorPreset\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">colorScheme\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">WhatIfSimulatorColorScheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Cpk target for color thresholds (default 1.33) */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cpkTarget\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface WhatIfSimulatorProps { currentStats: { mean: number; stdDev: number; cpk?: number }; specs?: { usl?: number; lsl?: number; target?: number }; defaultExpanded?: boolean; presets?: SimulatorPreset[]; isExpanded?: boolean; onExpandChange?: (expanded: boolean) => void; initialPreset?: SimulatorPreset | null; colorScheme?: WhatIfSimulatorColorScheme; /** Cpk target for color thresholds (default 1.33) */ cpkTarget?: number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-interaction\">User Interaction\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-interaction\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Interaction”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Select a factor from drill-down results\u003C/li>\n\u003Cli>Adjust the “reduction” slider (0-100%)\u003C/li>\n\u003Cli>See projected impact on:\n\u003Cul>\n\u003Cli>Cpk improvement\u003C/li>\n\u003Cli>Defect reduction\u003C/li>\n\u003Cli>Variation reduction\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cp>Uses \u003Ccode dir=\"auto\">simulateDirectAdjustment()\u003C/code> from \u003Ccode dir=\"auto\">@variscout/core\u003C/code> for projection calculations.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"smart-presets\">Smart Presets\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#smart-presets\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Smart Presets”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The simulator auto-computes up to 6 one-click presets based on current stats and \u003Ca href=\"../../../03-features/analysis/characteristic-types.md\">characteristic type\u003C/a>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>#\u003C/th>\u003Cth>Preset\u003C/th>\u003Cth>Logic\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1\u003C/td>\u003Ctd>Shift to target\u003C/td>\u003Ctd>Mean shift to target/midpoint\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2\u003C/td>\u003Ctd>Shift to median\u003C/td>\u003Ctd>Corrects skew\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3\u003C/td>\u003Ctd>Match best\u003C/td>\u003Ctd>Direction-aware best category mean\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4\u003C/td>\u003Ctd>Tighten spread\u003C/td>\u003Ctd>Match tightest category’s std dev\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5\u003C/td>\u003Ctd>Reach 95% yield\u003C/td>\u003Ctd>Reverse-calc shift/reduction\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6\u003C/td>\u003Ctd>Best of both\u003C/td>\u003Ctd>Combine #3 + #4\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Preset 3 (“Match best”) uses the characteristic type: for smaller-is-better, it targets the category with the lowest mean; for larger-is-better, the highest mean; for nominal, the closest to target.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"whatifpagebase\">WhatIfPageBase\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#whatifpagebase\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “WhatIfPageBase”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Full-page view wrapping the simulator with navigation header and data context.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"props-1\">Props\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#props-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Props”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> WhatIfPageBaseProps {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filteredData\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DataRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">rawData\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">DataRow\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">null\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">SpecLimits\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterCount\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterNames\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onBack\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">void\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">colorScheme\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">WhatIfPageColorScheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">simulatorColorScheme\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">WhatIfSimulatorColorScheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/** Cpk target for color thresholds */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cpkTarget\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface WhatIfPageBaseProps { filteredData: DataRow[]; rawData: DataRow[]; outcome: string | null; specs: SpecLimits; filterCount: number; filterNames?: string[]; onBack: () => void; colorScheme?: WhatIfPageColorScheme; simulatorColorScheme?: WhatIfSimulatorColorScheme; /** Cpk target for color thresholds */ cpkTarget?: number;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"rendering\">Rendering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#rendering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Rendering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">WhatIfPageBase\u003C/code> renders the standard \u003Ccode dir=\"auto\">WhatIfSimulator\u003C/code> in its default expanded state, providing mean-shift and variation-reduction sliders for direct adjustment simulation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"color-schemes\">Color Schemes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#color-schemes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color Schemes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All components follow the standard colorScheme pattern:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">whatIfPageDefaultColorScheme\u003C/code> — Semantic tokens (used by both PWA and Azure)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">whatIfSimulatorDefaultColorScheme\u003C/code> — Semantic tokens (used by both PWA and Azure)\u003C/li>\n\u003C/ul>\n\u003Cp>The \u003Ccode dir=\"auto\">WhatIfSimulatorColorScheme\u003C/code> includes \u003Ccode dir=\"auto\">improvementPositive\u003C/code> and \u003Ccode dir=\"auto\">improvementNegative\u003C/code> for directional change indicators (Cpk/yield improvement or decline), and \u003Ccode dir=\"auto\">cpkGood\u003C/code>/\u003Ccode dir=\"auto\">cpkOk\u003C/code>/\u003Ccode dir=\"auto\">cpkBad\u003C/code> for Cpk status coloring.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"variation-funnel.md\">Variation Bar\u003C/a> - Visual progress of isolated variation\u003C/li>\n\u003Cli>\u003Ca href=\"../../03-features/navigation/drill-down.md\">Drill-Down Feature\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 11013, + "localImagePaths": 11039, + "remoteImagePaths": 11040, + "frontmatter": 11041, + "imagePaths": 11042 + }, + [11014, 11016, 11017, 11020, 11023, 11024, 11025, 11028, 11031, 11032, 11035, 11038], + { "depth": 30, "slug": 11015, "text": 11003 }, + "what-if-simulator", + { "depth": 33, "slug": 3911, "text": 3912 }, + { "depth": 33, "slug": 11018, "text": 11019 }, + "shared-components", + "Shared Components", + { "depth": 33, "slug": 11021, "text": 11022 }, + "whatifsimulator", + "WhatIfSimulator", + { "depth": 79, "slug": 10523, "text": 10524 }, + { "depth": 79, "slug": 7180, "text": 7181 }, + { "depth": 79, "slug": 11026, "text": 11027 }, + "smart-presets", + "Smart Presets", + { "depth": 33, "slug": 11029, "text": 11030 }, + "whatifpagebase", + "WhatIfPageBase", + { "depth": 79, "slug": 10533, "text": 10524 }, + { "depth": 79, "slug": 11033, "text": 11034 }, + "rendering", + "Rendering", + { "depth": 79, "slug": 11036, "text": 11037 }, + "color-schemes", + "Color Schemes", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11003 }, + [], + "06-design-system/foundations/accessibility", + { + "id": 11043, + "data": 11045, + "body": 11050, + "filePath": 11051, + "digest": 11052, + "rendered": 11053 + }, + { + "title": 11046, + "editUrl": 16, + "head": 11047, + "template": 18, + "sidebar": 11048, + "pagefind": 16, + "draft": 20 + }, + "Accessibility Guidelines", + [], + { "hidden": 20, "attrs": 11049 }, + {}, + "# Accessibility Guidelines\n\nVariScout Lite targets WCAG 2.1 AA compliance to ensure quality professionals with disabilities can effectively analyze variation data.\n\n## Color Contrast Requirements\n\n### Text Contrast (4.5:1 minimum)\n\n| Element | Dark Theme | Light Theme | Ratio |\n| -------------- | ---------------------- | ---------------------- | ------ |\n| Body text | `#f1f5f9` on `#0f172a` | `#1e293b` on `#ffffff` | >7:1 |\n| Secondary text | `#94a3b8` on `#0f172a` | `#64748b` on `#ffffff` | >4.5:1 |\n| Error text | `#ef4444` on `#0f172a` | `#dc2626` on `#ffffff` | >4.5:1 |\n\n### UI Component Contrast (3:1 minimum)\n\n| Element | Dark Theme | Light Theme | Ratio |\n| ----------- | ---------------------- | ---------------------- | ----- |\n| Buttons | `#3b82f6` on `#0f172a` | `#2563eb` on `#ffffff` | >3:1 |\n| Borders | `#334155` on `#0f172a` | `#e2e8f0` on `#ffffff` | >3:1 |\n| Focus rings | `#60a5fa` on `#0f172a` | `#3b82f6` on `#ffffff` | >3:1 |\n\n### Chart Colors\n\nStatus colors maintain contrast against chart backgrounds:\n\n```typescript\n// packages/ui/src/colors.ts\nstatusColors.pass; // #22c55e - Green for within spec\nstatusColors.fail; // #ef4444 - Red for above USL\nstatusColors.warning; // #f59e0b - Amber for below LSL\n```\n\nAll chart colors are tested against both dark (`#1e293b`) and light (`#f8fafc`) chart backgrounds.\n\n## Keyboard Navigation\n\n### Existing Implementation\n\nThe `useKeyboardNavigation` hook (`packages/hooks/src/useKeyboardNavigation.ts`) provides:\n\n- Arrow key navigation between interactive elements\n- Focus management for chart drill-down interactions\n- Tab order preservation\n\n### Navigation Patterns\n\n| Key | Action |\n| ------------------ | -------------------------------------------------- |\n| `Tab` | Move between major sections |\n| `Arrow Left/Right` | Navigate between items in a list |\n| `Arrow Up/Down` | Navigate between rows in tables |\n| `Enter` | Activate selected element (e.g., drill into chart) |\n| `Escape` | Close modals, cancel operations |\n| `Space` | Toggle checkboxes, activate buttons |\n\n### Focus Management\n\n```typescript\n// Example: Managing focus on drill-down\nconst { handleKeyDown, setFocusedIndex } = useKeyboardNavigation({\n items: chartPoints,\n onSelect: index => onDrillDown(chartPoints[index]),\n orientation: 'horizontal',\n});\n```\n\n## Screen Reader Support\n\n### ARIA Labels\n\nAll interactive elements require descriptive labels:\n\n```tsx\n// Chart container\n\u003Cdiv\n role=\"img\"\n aria-label=\"I-Chart showing measurement values over time with control limits\"\n>\n\n// Interactive chart points\n\u003Ccircle\n role=\"button\"\n aria-label={`Point ${index}: value ${value.toFixed(2)}, ${status}`}\n tabIndex={0}\n/>\n```\n\n### Live Regions\n\nAnnounce dynamic content changes:\n\n```tsx\n// Data validation feedback\n\u003Cdiv role=\"alert\" aria-live=\"polite\">\n {validationErrors.length} issues found in uploaded data\n\u003C/div>\n\n// Chart update announcements\n\u003Cdiv aria-live=\"polite\" className=\"sr-only\">\n Chart updated: now showing {selectedMeasure} data\n\u003C/div>\n```\n\n### Chart Accessibility Patterns\n\n1. **Summary First**: Announce chart type and key insight before details\n2. **Data Table Fallback**: Provide tabular data alternative for complex charts\n3. **Pattern Descriptions**: Describe visual patterns (trends, outliers) in text\n\n```tsx\n// Example: IChart with accessible summary\n\u003Cfigure>\n \u003Cfigcaption className=\"sr-only\">\n I-Chart for {measureName}. Mean: {mean.toFixed(2)}. Cpk: {cpk.toFixed(2)}.{outOfSpec} of {total}{' '}\n points outside specification limits.\n \u003C/figcaption>\n \u003CIChart data={data} specs={specs} />\n\u003C/figure>\n```\n\n## Focus Indicators\n\n### Visible Focus Rings\n\nAll interactive elements show visible focus:\n\n```css\n/* PWA Tailwind classes */\n.focus-visible:ring-2\n.focus-visible:ring-blue-400\n.focus-visible:ring-offset-2\n.focus-visible:ring-offset-slate-900 /* dark */\n.focus-visible:ring-offset-white /* light */\n```\n\n### Custom Focus Styles\n\nFor chart elements that can't use Tailwind:\n\n```typescript\n// packages/charts/src/colors.ts\nchromeColors.focus = '#60a5fa'; // Visible on both themes\n```\n\n## Skip Links\n\nProvide skip navigation for keyboard users:\n\n```tsx\n// apps/pwa/src/App.tsx\n\u003Ca\n href=\"#main-content\"\n className=\"sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:bg-slate-800 focus:px-4 focus:py-2 focus:text-white\"\n>\n Skip to main content\n\u003C/a>\n```\n\n## Semantic Structure\n\n### Landmarks\n\n```tsx\n\u003Cheader role=\"banner\">...\u003C/header>\n\u003Cnav role=\"navigation\" aria-label=\"Main\">...\u003C/nav>\n\u003Cmain role=\"main\" id=\"main-content\">...\u003C/main>\n\u003Caside role=\"complementary\" aria-label=\"Statistics\">...\u003C/aside>\n\u003Cfooter role=\"contentinfo\">...\u003C/footer>\n```\n\n### Heading Hierarchy\n\nMaintain proper heading order:\n\n```\nh1: App name / Page title\n h2: Major section (Dashboard, Analysis Setup)\n h3: Subsection (Chart title, Panel title)\n h4: Detail section (Statistics, Options)\n```\n\n## Form Accessibility\n\n### Input Labels\n\nAll form inputs have associated labels:\n\n```tsx\n\u003Clabel htmlFor=\"lsl-input\" className=\"block text-sm font-medium\">\n Lower Spec Limit (LSL)\n\u003C/label>\n\u003Cinput\n id=\"lsl-input\"\n type=\"number\"\n aria-describedby=\"lsl-help\"\n/>\n\u003Cspan id=\"lsl-help\" className=\"text-xs text-slate-400\">\n Enter the minimum acceptable value\n\u003C/span>\n```\n\n### Error States\n\nAnnounce validation errors:\n\n```tsx\n\u003Cinput aria-invalid={!!error} aria-describedby={error ? 'input-error' : undefined} />;\n{\n error && (\n \u003Cspan id=\"input-error\" role=\"alert\" className=\"text-red-400\">\n {error}\n \u003C/span>\n );\n}\n```\n\n## Motion and Animation\n\n### Reduced Motion Support\n\nRespect user preferences:\n\n```css\n@media (prefers-reduced-motion: reduce) {\n * {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n```\n\n### Safe Animations\n\n- Avoid flashing content (max 3 flashes/second)\n- Keep animations subtle and functional\n- Ensure animations don't convey essential information\n\n## Testing Checklist\n\n### Automated Testing\n\n- [ ] Run axe-core on all pages\n- [ ] Check color contrast ratios\n- [ ] Validate HTML semantics\n\n### Manual Testing\n\n- [ ] Navigate entire app using only keyboard\n- [ ] Test with screen reader (VoiceOver/NVDA)\n- [ ] Verify focus visibility in all states\n- [ ] Test at 200% zoom level\n\n### Screen Reader Testing\n\n| Reader | Browser | Platform |\n| --------- | ------- | -------- |\n| VoiceOver | Safari | macOS |\n| NVDA | Chrome | Windows |\n| JAWS | Chrome | Windows |\n\n## Implementation Priority\n\n### Phase 1 (Required)\n\n- Keyboard navigation for all interactive elements\n- Proper heading structure\n- Form labels and error announcements\n- Color contrast compliance\n\n### Phase 2 (Important)\n\n- Screen reader announcements for chart updates\n- Skip links\n- ARIA landmarks\n\n### Phase 3 (Enhanced)\n\n- Data table alternatives for charts\n- Detailed chart descriptions\n- Reduced motion support\n\n## Resources\n\n- [WCAG 2.1 Quick Reference](https://www.w3.org/WAI/WCAG21/quickref/)\n- [Accessible SVG Charts](https://www.smashingmagazine.com/2021/06/accessible-svg-patterns-comparison/)\n- [Data Visualization Accessibility](https://accessibility.digital.gov/visual-design/data-visualizations/)", + "src/content/docs/06-design-system/foundations/accessibility.md", + "2f4cfad9940a4e6c", + { "html": 11054, "metadata": 11055 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"accessibility-guidelines\">Accessibility Guidelines\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#accessibility-guidelines\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Accessibility Guidelines”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout Lite targets WCAG 2.1 AA compliance to ensure quality professionals with disabilities can effectively analyze variation data.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"color-contrast-requirements\">Color Contrast Requirements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#color-contrast-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color Contrast Requirements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"text-contrast-451-minimum\">Text Contrast (4.5:1 minimum)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#text-contrast-451-minimum\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Text Contrast (4.5:1 minimum)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Dark Theme\u003C/th>\u003Cth>Light Theme\u003C/th>\u003Cth>Ratio\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Body text\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f1f5f9\u003C/code> on \u003Ccode dir=\"auto\">#0f172a\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#1e293b\u003C/code> on \u003Ccode dir=\"auto\">#ffffff\u003C/code>\u003C/td>\u003Ctd>>7:1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Secondary text\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code> on \u003Ccode dir=\"auto\">#0f172a\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code> on \u003Ccode dir=\"auto\">#ffffff\u003C/code>\u003C/td>\u003Ctd>>4.5:1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Error text\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ef4444\u003C/code> on \u003Ccode dir=\"auto\">#0f172a\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#dc2626\u003C/code> on \u003Ccode dir=\"auto\">#ffffff\u003C/code>\u003C/td>\u003Ctd>>4.5:1\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ui-component-contrast-31-minimum\">UI Component Contrast (3:1 minimum)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ui-component-contrast-31-minimum\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “UI Component Contrast (3:1 minimum)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Dark Theme\u003C/th>\u003Cth>Light Theme\u003C/th>\u003Cth>Ratio\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Buttons\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#3b82f6\u003C/code> on \u003Ccode dir=\"auto\">#0f172a\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#2563eb\u003C/code> on \u003Ccode dir=\"auto\">#ffffff\u003C/code>\u003C/td>\u003Ctd>>3:1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Borders\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#334155\u003C/code> on \u003Ccode dir=\"auto\">#0f172a\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#e2e8f0\u003C/code> on \u003Ccode dir=\"auto\">#ffffff\u003C/code>\u003C/td>\u003Ctd>>3:1\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Focus rings\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#60a5fa\u003C/code> on \u003Ccode dir=\"auto\">#0f172a\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#3b82f6\u003C/code> on \u003Ccode dir=\"auto\">#ffffff\u003C/code>\u003C/td>\u003Ctd>>3:1\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"chart-colors\">Chart Colors\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#chart-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Status colors maintain contrast against chart backgrounds:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/ui/src/colors.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">statusColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">pass\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #22c55e - Green for within spec\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">statusColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">fail\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #ef4444 - Red for above USL\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">statusColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">warning\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// #f59e0b - Amber for below LSL\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"statusColors.pass; // #22c55e - Green for within specstatusColors.fail; // #ef4444 - Red for above USLstatusColors.warning; // #f59e0b - Amber for below LSL\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>All chart colors are tested against both dark (\u003Ccode dir=\"auto\">#1e293b\u003C/code>) and light (\u003Ccode dir=\"auto\">#f8fafc\u003C/code>) chart backgrounds.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyboard-navigation\">Keyboard Navigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyboard-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyboard Navigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"existing-implementation\">Existing Implementation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#existing-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Existing Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">useKeyboardNavigation\u003C/code> hook (\u003Ccode dir=\"auto\">packages/hooks/src/useKeyboardNavigation.ts\u003C/code>) provides:\u003C/p>\n\u003Cul>\n\u003Cli>Arrow key navigation between interactive elements\u003C/li>\n\u003Cli>Focus management for chart drill-down interactions\u003C/li>\n\u003Cli>Tab order preservation\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"navigation-patterns\">Navigation Patterns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#navigation-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Navigation Patterns”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Key\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Tab\u003C/code>\u003C/td>\u003Ctd>Move between major sections\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Arrow Left/Right\u003C/code>\u003C/td>\u003Ctd>Navigate between items in a list\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Arrow Up/Down\u003C/code>\u003C/td>\u003Ctd>Navigate between rows in tables\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Enter\u003C/code>\u003C/td>\u003Ctd>Activate selected element (e.g., drill into chart)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Escape\u003C/code>\u003C/td>\u003Ctd>Close modals, cancel operations\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Space\u003C/code>\u003C/td>\u003Ctd>Toggle checkboxes, activate buttons\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"focus-management\">Focus Management\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#focus-management\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Focus Management”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Example: Managing focus on drill-down\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleKeyDown\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setFocusedIndex\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useKeyboardNavigation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">items: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartPoints\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onSelect\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">: \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onDrillDown\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(chartPoints[index])\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">orientation: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">horizontal\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Example: Managing focus on drill-downconst { handleKeyDown, setFocusedIndex } = useKeyboardNavigation({ items: chartPoints, onSelect: index => onDrillDown(chartPoints[index]), orientation: 'horizontal',});\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"screen-reader-support\">Screen Reader Support\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#screen-reader-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Screen Reader Support”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"aria-labels\">ARIA Labels\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#aria-labels\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ARIA Labels”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All interactive elements require descriptive labels:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart container\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">role\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">img\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">aria-label\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">I-Chart showing measurement values over time with control limits\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">// Interactive chart points\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">circle\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">role\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">button\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">aria-label\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Point \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">index\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">: value \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toFixed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">, \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">status\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">tabIndex\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">0\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Chart container\u003Cdiv role="img" aria-label="I-Chart showing measurement values over time with control limits">// Interactive chart points\u003Ccircle role="button" aria-label={`Point ${index}: value ${value.toFixed(2)}, ${status}`} tabIndex={0}/>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"live-regions\">Live Regions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#live-regions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Live Regions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Announce dynamic content changes:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Data validation feedback\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">role\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">alert\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">aria-live\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">polite\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">validationErrors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">length\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> issues found in uploaded data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Chart update announcements\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">aria-live\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">polite\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">sr-only\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Chart updated: now showing \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">selectedMeasure\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Data validation feedback\u003Cdiv role="alert" aria-live="polite"> {validationErrors.length} issues found in uploaded data\u003C/div>// Chart update announcements\u003Cdiv aria-live="polite" className="sr-only"> Chart updated: now showing {selectedMeasure} data\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"chart-accessibility-patterns\">Chart Accessibility Patterns\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#chart-accessibility-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Accessibility Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Summary First\u003C/strong>: Announce chart type and key insight before details\u003C/li>\n\u003Cli>\u003Cstrong>Data Table Fallback\u003C/strong>: Provide tabular data alternative for complex charts\u003C/li>\n\u003Cli>\u003Cstrong>Pattern Descriptions\u003C/strong>: Describe visual patterns (trends, outliers) in text\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Example: IChart with accessible summary\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">figure\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">figcaption\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">sr-only\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">I-Chart for \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">measureName\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">. Mean: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">mean\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toFixed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">. Cpk: \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">cpk\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toFixed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">.\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outOfSpec\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> of \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">total\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">points outside specification limits.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">figcaption\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">data\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">specs\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">specs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">figure\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Example: IChart with accessible summary\u003Cfigure> \u003Cfigcaption className="sr-only"> I-Chart for {measureName}. Mean: {mean.toFixed(2)}. Cpk: {cpk.toFixed(2)}.{outOfSpec} of {total}{' '} points outside specification limits. \u003C/figcaption> \u003CIChart data={data} specs={specs} />\u003C/figure>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"focus-indicators\">Focus Indicators\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#focus-indicators\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Focus Indicators”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"visible-focus-rings\">Visible Focus Rings\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#visible-focus-rings\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visible Focus Rings”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All interactive elements show visible focus:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* PWA Tailwind classes */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">.focus-visible\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">ring-2\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">.focus-visible\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">ring-blue-400\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">.focus-visible\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">ring-offset-2\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">.focus-visible\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">ring-offset-slate-900\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* dark */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">.focus-visible\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">ring-offset-white\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* light */\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"/* PWA Tailwind classes */.focus-visible:ring-2.focus-visible:ring-blue-400.focus-visible:ring-offset-2.focus-visible:ring-offset-slate-900 /* dark */.focus-visible:ring-offset-white /* light */\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"custom-focus-styles\">Custom Focus Styles\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#custom-focus-styles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Custom Focus Styles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For chart elements that can’t use Tailwind:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/charts/src/colors.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chromeColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">focus\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#60a5fa\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Visible on both themes\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"chromeColors.focus = '#60a5fa'; // Visible on both themes\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"skip-links\">Skip Links\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#skip-links\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Skip Links”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Provide skip navigation for keyboard users:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">apps/pwa/src/App.tsx\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">href\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">#main-content\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:bg-slate-800 focus:px-4 focus:py-2 focus:text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Skip to main content\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ca href="#main-content" className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:bg-slate-800 focus:px-4 focus:py-2 focus:text-white"> Skip to main content\u003C/a>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"semantic-structure\">Semantic Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#semantic-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Semantic Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"landmarks\">Landmarks\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#landmarks\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Landmarks”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">header\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">role\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">banner\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">header\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">nav\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">role\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">navigation\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">aria-label\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Main\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">nav\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">main\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">role\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">main\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">id\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">main-content\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">main\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">aside\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">role\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">complementary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">aria-label\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Statistics\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">aside\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">footer\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">role\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">contentinfo\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">footer\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cheader role="banner">...\u003C/header>\u003Cnav role="navigation" aria-label="Main">...\u003C/nav>\u003Cmain role="main" id="main-content">...\u003C/main>\u003Caside role="complementary" aria-label="Statistics">...\u003C/aside>\u003Cfooter role="contentinfo">...\u003C/footer>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"heading-hierarchy\">Heading Hierarchy\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#heading-hierarchy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Heading Hierarchy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Maintain proper heading order:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">h1: App name / Page title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">h2: Major section (Dashboard, Analysis Setup)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">h3: Subsection (Chart title, Panel title)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">h4: Detail section (Statistics, Options)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"h1: App name / Page title h2: Major section (Dashboard, Analysis Setup) h3: Subsection (Chart title, Panel title) h4: Detail section (Statistics, Options)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"form-accessibility\">Form Accessibility\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#form-accessibility\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Form Accessibility”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"input-labels\">Input Labels\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#input-labels\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Input Labels”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All form inputs have associated labels:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">htmlFor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">lsl-input\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">block text-sm font-medium\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Lower Spec Limit (LSL)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">label\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">id\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">lsl-input\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">type\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">aria-describedby\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">lsl-help\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">id\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">lsl-help\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs text-slate-400\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Enter the minimum acceptable value\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Clabel htmlFor="lsl-input" className="block text-sm font-medium"> Lower Spec Limit (LSL)\u003C/label>\u003Cinput id="lsl-input" type="number" aria-describedby="lsl-help"/>\u003Cspan id="lsl-help" className="text-xs text-slate-400"> Enter the minimum acceptable value\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"error-states\">Error States\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#error-states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Error States”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Announce validation errors:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">aria-invalid\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!!\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">error\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">aria-describedby\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">error\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">input-error\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">error \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">id\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">input-error\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">role\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">alert\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-red-400\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">error\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cinput aria-invalid={!!error} aria-describedby={error ? 'input-error' : undefined} />;{ error && ( \u003Cspan id="input-error" role="alert" className="text-red-400"> {error} \u003C/span> );}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"motion-and-animation\">Motion and Animation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#motion-and-animation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Motion and Animation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"reduced-motion-support\">Reduced Motion Support\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#reduced-motion-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Reduced Motion Support”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Respect user preferences:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">@media\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">prefers-reduced-motion: reduce\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">*\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#80CBC4;--1:#096E72\">animation-duration\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--1:#AA0982\">\u003Cspan style=\"--0:#F78C6C\">0.01\u003C/span>\u003Cspan style=\"--0:#FFEB95\">ms\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!important\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#80CBC4;--1:#096E72\">transition-duration\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--1:#AA0982\">\u003Cspan style=\"--0:#F78C6C\">0.01\u003C/span>\u003Cspan style=\"--0:#FFEB95\">ms\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!important\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"@media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"safe-animations\">Safe Animations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#safe-animations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Safe Animations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Avoid flashing content (max 3 flashes/second)\u003C/li>\n\u003Cli>Keep animations subtle and functional\u003C/li>\n\u003Cli>Ensure animations don’t convey essential information\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"testing-checklist\">Testing Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#testing-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Testing Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"automated-testing\">Automated Testing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#automated-testing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Automated Testing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Run axe-core on all pages\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Check color contrast ratios\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Validate HTML semantics\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"manual-testing\">Manual Testing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#manual-testing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Manual Testing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Navigate entire app using only keyboard\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Test with screen reader (VoiceOver/NVDA)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Verify focus visibility in all states\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Test at 200% zoom level\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"screen-reader-testing\">Screen Reader Testing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#screen-reader-testing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Screen Reader Testing”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Reader\u003C/th>\u003Cth>Browser\u003C/th>\u003Cth>Platform\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>VoiceOver\u003C/td>\u003Ctd>Safari\u003C/td>\u003Ctd>macOS\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>NVDA\u003C/td>\u003Ctd>Chrome\u003C/td>\u003Ctd>Windows\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>JAWS\u003C/td>\u003Ctd>Chrome\u003C/td>\u003Ctd>Windows\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation-priority\">Implementation Priority\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-priority\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation Priority”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-1-required\">Phase 1 (Required)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-1-required\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 1 (Required)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Keyboard navigation for all interactive elements\u003C/li>\n\u003Cli>Proper heading structure\u003C/li>\n\u003Cli>Form labels and error announcements\u003C/li>\n\u003Cli>Color contrast compliance\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-2-important\">Phase 2 (Important)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-2-important\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 2 (Important)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Screen reader announcements for chart updates\u003C/li>\n\u003Cli>Skip links\u003C/li>\n\u003Cli>ARIA landmarks\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"phase-3-enhanced\">Phase 3 (Enhanced)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#phase-3-enhanced\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Phase 3 (Enhanced)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Data table alternatives for charts\u003C/li>\n\u003Cli>Detailed chart descriptions\u003C/li>\n\u003Cli>Reduced motion support\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"resources\">Resources\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#resources\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Resources”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.w3.org/WAI/WCAG21/quickref/\">WCAG 2.1 Quick Reference\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.smashingmagazine.com/2021/06/accessible-svg-patterns-comparison/\">Accessible SVG Charts\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://accessibility.digital.gov/visual-design/data-visualizations/\">Data Visualization Accessibility\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 11056, + "localImagePaths": 11152, + "remoteImagePaths": 11153, + "frontmatter": 11154, + "imagePaths": 11155 + }, + [ + 11057, 11059, 11062, 11065, 11068, 11069, 11070, 11073, 11076, 11079, 11082, 11085, 11088, + 11091, 11094, 11097, 11100, 11103, 11106, 11109, 11112, 11115, 11118, 11121, 11124, 11127, + 11130, 11131, 11134, 11136, 11139, 11140, 11143, 11146, 11149 + ], + { "depth": 30, "slug": 11058, "text": 11046 }, + "accessibility-guidelines", + { "depth": 33, "slug": 11060, "text": 11061 }, + "color-contrast-requirements", + "Color Contrast Requirements", + { "depth": 79, "slug": 11063, "text": 11064 }, + "text-contrast-451-minimum", + "Text Contrast (4.5:1 minimum)", + { "depth": 79, "slug": 11066, "text": 11067 }, + "ui-component-contrast-31-minimum", + "UI Component Contrast (3:1 minimum)", + { "depth": 79, "slug": 9937, "text": 9925 }, + { "depth": 33, "slug": 1194, "text": 1195 }, + { "depth": 79, "slug": 11071, "text": 11072 }, + "existing-implementation", + "Existing Implementation", + { "depth": 79, "slug": 11074, "text": 11075 }, + "navigation-patterns", + "Navigation Patterns", + { "depth": 79, "slug": 11077, "text": 11078 }, + "focus-management", + "Focus Management", + { "depth": 33, "slug": 11080, "text": 11081 }, + "screen-reader-support", + "Screen Reader Support", + { "depth": 79, "slug": 11083, "text": 11084 }, + "aria-labels", + "ARIA Labels", + { "depth": 79, "slug": 11086, "text": 11087 }, + "live-regions", + "Live Regions", + { "depth": 79, "slug": 11089, "text": 11090 }, + "chart-accessibility-patterns", + "Chart Accessibility Patterns", + { "depth": 33, "slug": 11092, "text": 11093 }, + "focus-indicators", + "Focus Indicators", + { "depth": 79, "slug": 11095, "text": 11096 }, + "visible-focus-rings", + "Visible Focus Rings", + { "depth": 79, "slug": 11098, "text": 11099 }, + "custom-focus-styles", + "Custom Focus Styles", + { "depth": 33, "slug": 11101, "text": 11102 }, + "skip-links", + "Skip Links", + { "depth": 33, "slug": 11104, "text": 11105 }, + "semantic-structure", + "Semantic Structure", + { "depth": 79, "slug": 11107, "text": 11108 }, + "landmarks", + "Landmarks", + { "depth": 79, "slug": 11110, "text": 11111 }, + "heading-hierarchy", + "Heading Hierarchy", + { "depth": 33, "slug": 11113, "text": 11114 }, + "form-accessibility", + "Form Accessibility", + { "depth": 79, "slug": 11116, "text": 11117 }, + "input-labels", + "Input Labels", + { "depth": 79, "slug": 11119, "text": 11120 }, + "error-states", + "Error States", + { "depth": 33, "slug": 11122, "text": 11123 }, + "motion-and-animation", + "Motion and Animation", + { "depth": 79, "slug": 11125, "text": 11126 }, + "reduced-motion-support", + "Reduced Motion Support", + { "depth": 79, "slug": 11128, "text": 11129 }, + "safe-animations", + "Safe Animations", + { "depth": 33, "slug": 3640, "text": 3641 }, + { "depth": 79, "slug": 11132, "text": 11133 }, + "automated-testing", + "Automated Testing", + { "depth": 79, "slug": 3414, "text": 11135 }, + "Manual Testing", + { "depth": 79, "slug": 11137, "text": 11138 }, + "screen-reader-testing", + "Screen Reader Testing", + { "depth": 33, "slug": 8680, "text": 8681 }, + { "depth": 79, "slug": 11141, "text": 11142 }, + "phase-1-required", + "Phase 1 (Required)", + { "depth": 79, "slug": 11144, "text": 11145 }, + "phase-2-important", + "Phase 2 (Important)", + { "depth": 79, "slug": 11147, "text": 11148 }, + "phase-3-enhanced", + "Phase 3 (Enhanced)", + { "depth": 33, "slug": 11150, "text": 11151 }, + "resources", + "Resources", + [], + [], + { "title": 11046 }, + [], + "06-design-system/foundations/colors", + { + "id": 11156, + "data": 11158, + "body": 11163, + "filePath": 11164, + "digest": 11165, + "rendered": 11166 + }, + { + "title": 11159, + "editUrl": 16, + "head": 11160, + "template": 18, + "sidebar": 11161, + "pagefind": 16, + "draft": 20 + }, + "Color System", + [], + { "hidden": 20, "attrs": 11162 }, + {}, + "# Color System\n\nVariScout uses CSS variables with Tailwind semantic classes for theme-aware styling.\n\n## Theme Support\n\n| Product | Dark | Light | System Pref | Company Accent |\n| ---------- | :--: | :---: | :---------: | :------------: |\n| PWA (Free) | ✓ | - | - | - |\n| Azure App | ✓ | ✓ | ✓ | ✓ |\n\n## CSS Variables\n\nDefined in `apps/pwa/src/index.css`, these variables use RGB format for alpha support:\n\n```css\n:root,\n[data-theme='dark'] {\n --surface-primary: 15 23 42; /* slate-900 */\n --surface-secondary: 30 41 59; /* slate-800 */\n --surface-tertiary: 51 65 85; /* slate-700 */\n --content-primary: 226 232 240; /* slate-200 */\n --content-secondary: 148 163 184; /* slate-400 */\n --content-muted: 100 116 139; /* slate-500 */\n --edge-primary: 51 65 85; /* slate-700 */\n}\n\n[data-theme='light'] {\n --surface-primary: 248 250 252; /* slate-50 */\n --surface-secondary: 241 245 249; /* slate-100 */\n --surface-tertiary: 226 232 240; /* slate-200 */\n --content-primary: 15 23 42; /* slate-900 */\n --content-secondary: 71 85 105; /* slate-600 */\n --content-muted: 100 116 139; /* slate-500 */\n --edge-primary: 226 232 240; /* slate-200 */\n}\n```\n\n## Semantic Tailwind Classes\n\nConfigured in `packages/ui/tailwind.config.cjs`:\n\n### Surface Colors (Backgrounds)\n\n| Semantic Class | CSS Variable | Dark | Light | Usage |\n| ---------------------- | --------------------- | --------- | --------- | --------------------- |\n| `bg-surface` | `--surface-primary` | `#0f172a` | `#f8fafc` | App background |\n| `bg-surface-secondary` | `--surface-secondary` | `#1e293b` | `#f1f5f9` | Cards, panels |\n| `bg-surface-tertiary` | `--surface-tertiary` | `#334155` | `#e2e8f0` | Hover states, inputs |\n| `bg-surface-elevated` | `--surface-elevated` | `#475569` | `#ffffff` | Active/pressed states |\n\n### Content Colors (Text)\n\n| Semantic Class | CSS Variable | Dark | Light | Usage |\n| ------------------------ | --------------------- | --------- | --------- | --------------------- |\n| `text-content` | `--content-primary` | `#e2e8f0` | `#0f172a` | Main text, headings |\n| `text-content-secondary` | `--content-secondary` | `#94a3b8` | `#475569` | Labels, descriptions |\n| `text-content-muted` | `--content-muted` | `#64748b` | `#64748b` | Placeholder, disabled |\n\n### Edge Colors (Borders)\n\n| Semantic Class | CSS Variable | Dark | Light | Usage |\n| ----------------------- | ------------------ | --------- | --------- | ------------ |\n| `border-edge` | `--edge-primary` | `#334155` | `#e2e8f0` | Card borders |\n| `border-edge-secondary` | `--edge-secondary` | `#475569` | `#cbd5e1` | Dividers |\n\n## Status Colors (Universal)\n\nThese colors have **consistent semantic meaning** across both themes:\n\n| Token | Hex | Tailwind Class | Usage |\n| ------- | --------- | ---------------- | ------------------------------- |\n| success | `#22c55e` | `text-green-500` | Pass, in-spec, valid |\n| danger | `#ef4444` | `text-red-500` | Fail, out of spec (high), error |\n| warning | `#f59e0b` | `text-amber-500` | Warning, out of spec (low) |\n\n### Status Usage in Data Analysis\n\n| Scenario | Color | Meaning |\n| ------------------------ | ----------------- | -------------------------------------- |\n| Value within spec limits | Green (`#22c55e`) | Pass |\n| Value > USL | Red (`#ef4444`) | Fail (too high) |\n| Value \u003C LSL | Amber (`#f59e0b`) | Fail (too low) |\n| Cpk >= target | Green | Meets capability target (default 1.33) |\n| Cpk >= 75% of target | Amber | Approaching target, monitor |\n| Cpk \u003C 75% of target | Red | Needs improvement |\n\n## Brand Colors\n\n| Token | Hex | Tailwind Class | Usage |\n| ------------- | --------- | ------------------- | ------------------------ |\n| brand-primary | `#3b82f6` | `bg-blue-600` | Primary buttons, accents |\n| brand-hover | `#2563eb` | `hover:bg-blue-700` | Hover state |\n| brand-light | `#60a5fa` | `text-blue-400` | Links, highlights |\n\n### Company Accent (Azure App Only)\n\nAzure App users can customize the accent color via Settings > Appearance. The `useThemeState` hook sets two CSS variables on `\u003Chtml>`:\n\n| Variable | Format | Example | Usage |\n| -------------- | ----------- | ------------ | -------------------------------------------- |\n| `--accent` | RGB triplet | `139 92 246` | Tailwind `rgb(var(--accent))` utilities |\n| `--accent-hex` | Hex string | `#8b5cf6` | Inline `style` where `rgb()` isn't practical |\n\nWhen no accent is set, both variables are removed and consumers fall back to their defaults.\n\n**Surfaces that consume `--accent-hex`:**\n\n| Component | Property | Fallback |\n| ------------------ | ------------------------- | ---------------------------------- |\n| `ChartSourceBar` | Branding dot fill | `accentColor` prop (blue-500) |\n| `FilterContextBar` | Variation percentage text | `#60a5fa` (blue-400) |\n| `ChartCard` | Hover border color | `var(--color-edge-hover, #475569)` |\n\nPWA has no accent set, so these surfaces always use their fallback values.\n\n## Chart Colors\n\nSee [Charts > Colors](../charts/colors.md) for data visualization colors.\n\nCharts use the `useChartTheme()` hook for theme-aware chrome colors:\n\n```tsx\nimport { useChartTheme } from '@variscout/charts';\n\nconst { isDark, chrome } = useChartTheme();\n// chrome.gridLine, chrome.labelPrimary, chrome.tooltipBg, etc.\n```\n\n## Implementation Examples\n\n### PWA Component\n\n```jsx\n// Theme-aware card\n\u003Cdiv className=\"bg-surface-secondary border border-edge rounded-lg p-4\">\n \u003Ch2 className=\"text-content font-semibold\">Title\u003C/h2>\n \u003Cp className=\"text-content-secondary\">Description\u003C/p>\n \u003Cspan className=\"text-content-muted text-sm\">Metadata\u003C/span>\n\u003C/div>\n\n// Status display\n\u003Cspan className=\"text-green-500\">In Spec\u003C/span>\n\u003Cspan className=\"text-red-500\">Out of Spec\u003C/span>\n```\n\n### Chart SVG\n\n```tsx\nimport { useChartTheme, chartColors } from '@variscout/charts';\n\nconst { chrome } = useChartTheme();\n\n// Theme-aware chrome\n\u003CLine stroke={chrome.gridLine} />\n\u003Ctext fill={chrome.labelPrimary}>Axis Label\u003C/text>\n\n// Universal data colors\nconst getPointColor = (value: number, usl?: number, lsl?: number) => {\n if (usl !== undefined && value > usl) return chartColors.fail; // Red\n if (lsl !== undefined && value \u003C lsl) return chartColors.warning; // Amber\n return chartColors.pass; // Green\n};\n```\n\n## Shared Component Color Schemes\n\nComponents in `@variscout/ui` use a **colorScheme prop pattern** for platform-agnostic styling:\n\n### Pattern Overview\n\n```tsx\n// Component defines color scheme interface\ninterface ComponentColorScheme {\n containerBg: string; // Tailwind class for background\n border: string; // Tailwind class for borders\n textMuted: string; // Tailwind class for muted text\n // ... component-specific color slots\n}\n\n// Default uses PWA semantic tokens\nconst defaultColorScheme: ComponentColorScheme = {\n containerBg: 'bg-surface-secondary',\n border: 'border-edge',\n textMuted: 'text-content-muted',\n};\n```\n\n### Color Scheme Mapping\n\nBoth PWA and Azure use the same semantic tokens. The Slate equivalents are shown for historical reference (Azure previously used hardcoded Slate classes before the visual convergence migration):\n\n| Semantic Token | Resolved Value (Dark) | Usage |\n| ------------------------ | ---------------------- | ------------------- |\n| `bg-surface` | `bg-slate-900` | Main container |\n| `bg-surface-secondary` | `bg-slate-800` | Cards, panels |\n| `bg-surface-tertiary/50` | `bg-slate-700/50` | Hover backgrounds |\n| `border-edge` | `border-slate-700` | Primary borders |\n| `border-edge-secondary` | `border-slate-600` | Secondary borders |\n| `text-content` | `text-white` | Primary text |\n| `text-content-secondary` | `text-slate-400` | Secondary text |\n| `text-content-muted` | `text-slate-500` | Muted/disabled text |\n| `hover:text-content` | `hover:text-slate-300` | Hover text |\n\n### Available Color Schemes\n\nEach component exports a single `defaultColorScheme` using semantic tokens. Both PWA and Azure apps use these defaults:\n\n| Component | Default Export | Notes |\n| --------------------------- | ----------------------------------------- | ---------------------------------- |\n| `FilterBreadcrumb` | `filterBreadcrumbDefaultColorScheme` | Semantic tokens, used by both apps |\n| `FilterChipDropdown` | `filterChipDropdownDefaultColorScheme` | Semantic tokens, used by both apps |\n| `VariationBar` | `variationBarDefaultColorScheme` | Semantic tokens, used by both apps |\n| `AnovaResults` | `anovaDefaultColorScheme` | Semantic tokens, used by both apps |\n| `YAxisPopover` | `yAxisPopoverDefaultColorScheme` | Semantic tokens, used by both apps |\n| `PerformanceSetupPanelBase` | `performanceSetupPanelDefaultColorScheme` | Semantic tokens, used by both apps |\n\n### Usage in Apps\n\nBoth PWA and Azure use the default color scheme (semantic tokens). No explicit `colorScheme` prop is needed:\n\n```tsx\nimport { FilterBreadcrumb } from '@variscout/ui';\n\n// Default colorScheme uses semantic tokens — works for both PWA and Azure\n\u003CFilterBreadcrumb {...props} />;\n```\n\n### Nested Color Schemes\n\nSome components contain other themeable components. They use nested color schemes:\n\n```tsx\ninterface FilterBreadcrumbColorScheme {\n containerBg: string;\n border: string;\n // Nested schemes for child components\n variationBar: VariationBarColorScheme;\n dropdown: FilterChipDropdownColorScheme;\n}\n```\n\n### Creating New Color Schemes\n\nWhen extracting a component to `@variscout/ui`:\n\n1. **Identify color slots** needed by the component\n2. **Create interface** with all color slots\n3. **Define default scheme** using semantic tokens\n4. **Export** from component index and main package index\n\n```tsx\n// packages/ui/src/components/MyComponent/MyComponent.tsx\nexport interface MyComponentColorScheme {\n background: string;\n text: string;\n border: string;\n}\n\nexport const defaultColorScheme: MyComponentColorScheme = {\n background: 'bg-surface-secondary',\n text: 'text-content',\n border: 'border-edge',\n};\n```\n\n## Accessibility\n\nAll color combinations meet WCAG AA contrast requirements:\n\n- Text on background: minimum 4.5:1 ratio\n- Large text: minimum 3:1 ratio\n- UI components: minimum 3:1 ratio\n\n| Combination | Dark Ratio | Light Ratio | Pass |\n| ---------------------------------------------- | ---------- | ----------- | ---- |\n| text-content on bg-surface | 13.5:1 | 15.4:1 | AAA |\n| text-content-secondary on bg-surface-secondary | 5.2:1 | 4.8:1 | AA |\n| green-500 on bg-surface-secondary | 4.8:1 | 4.5:1 | AA |\n| red-500 on bg-surface-secondary | 4.6:1 | 4.3:1 | AA |", + "src/content/docs/06-design-system/foundations/colors.md", + "99efdfd11273f823", + { "html": 11167, "metadata": 11168 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"color-system\">Color System\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#color-system\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color System”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses CSS variables with Tailwind semantic classes for theme-aware styling.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"theme-support\">Theme Support\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#theme-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Theme Support”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth align=\"center\">Dark\u003C/th>\u003Cth align=\"center\">Light\u003C/th>\u003Cth align=\"center\">System Pref\u003C/th>\u003Cth align=\"center\">Company Accent\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA (Free)\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003Ctd align=\"center\">-\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure App\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"css-variables\">CSS Variables\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#css-variables\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CSS Variables”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Defined in \u003Ccode dir=\"auto\">apps/pwa/src/index.css\u003C/code>, these variables use RGB format for alpha support:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">:root\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">[\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data-theme\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">dark\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">]\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--surface-primary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">15\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">23\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">42\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-900 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--surface-secondary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">30\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">41\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">59\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-800 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--surface-tertiary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">51\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">65\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">85\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-700 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--content-primary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">226\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">232\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">240\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-200 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--content-secondary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">148\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">163\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">184\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-400 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--content-muted\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">116\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">139\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-500 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--edge-primary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">51\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">65\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">85\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-700 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">[\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">data-theme\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">light\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">]\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--surface-primary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">248\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">250\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">252\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-50 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--surface-secondary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">241\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">245\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">249\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-100 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--surface-tertiary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">226\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">232\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">240\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-200 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--content-primary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">15\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">23\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">42\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-900 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--content-secondary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">71\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">85\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">105\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-600 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--content-muted\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">100\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">116\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">139\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-500 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">--edge-primary\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">226\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">232\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">240\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* slate-200 */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\":root,[data-theme='dark'] { --surface-primary: 15 23 42; /* slate-900 */ --surface-secondary: 30 41 59; /* slate-800 */ --surface-tertiary: 51 65 85; /* slate-700 */ --content-primary: 226 232 240; /* slate-200 */ --content-secondary: 148 163 184; /* slate-400 */ --content-muted: 100 116 139; /* slate-500 */ --edge-primary: 51 65 85; /* slate-700 */}[data-theme='light'] { --surface-primary: 248 250 252; /* slate-50 */ --surface-secondary: 241 245 249; /* slate-100 */ --surface-tertiary: 226 232 240; /* slate-200 */ --content-primary: 15 23 42; /* slate-900 */ --content-secondary: 71 85 105; /* slate-600 */ --content-muted: 100 116 139; /* slate-500 */ --edge-primary: 226 232 240; /* slate-200 */}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"semantic-tailwind-classes\">Semantic Tailwind Classes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#semantic-tailwind-classes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Semantic Tailwind Classes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Configured in \u003Ccode dir=\"auto\">packages/ui/tailwind.config.cjs\u003C/code>:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"surface-colors-backgrounds\">Surface Colors (Backgrounds)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#surface-colors-backgrounds\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Surface Colors (Backgrounds)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Semantic Class\u003C/th>\u003Cth>CSS Variable\u003C/th>\u003Cth>Dark\u003C/th>\u003Cth>Light\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">--surface-primary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#0f172a\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f8fafc\u003C/code>\u003C/td>\u003Ctd>App background\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface-secondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">--surface-secondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#1e293b\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f1f5f9\u003C/code>\u003C/td>\u003Ctd>Cards, panels\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface-tertiary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">--surface-tertiary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#334155\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#e2e8f0\u003C/code>\u003C/td>\u003Ctd>Hover states, inputs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface-elevated\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">--surface-elevated\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#475569\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ffffff\u003C/code>\u003C/td>\u003Ctd>Active/pressed states\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"content-colors-text\">Content Colors (Text)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#content-colors-text\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Content Colors (Text)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Semantic Class\u003C/th>\u003Cth>CSS Variable\u003C/th>\u003Cth>Dark\u003C/th>\u003Cth>Light\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">text-content\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">--content-primary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#e2e8f0\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#0f172a\u003C/code>\u003C/td>\u003Ctd>Main text, headings\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">text-content-secondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">--content-secondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#475569\u003C/code>\u003C/td>\u003Ctd>Labels, descriptions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">text-content-muted\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">--content-muted\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#64748b\u003C/code>\u003C/td>\u003Ctd>Placeholder, disabled\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"edge-colors-borders\">Edge Colors (Borders)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#edge-colors-borders\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Edge Colors (Borders)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Semantic Class\u003C/th>\u003Cth>CSS Variable\u003C/th>\u003Cth>Dark\u003C/th>\u003Cth>Light\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">border-edge\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">--edge-primary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#334155\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#e2e8f0\u003C/code>\u003C/td>\u003Ctd>Card borders\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">border-edge-secondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">--edge-secondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#475569\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#cbd5e1\u003C/code>\u003C/td>\u003Ctd>Dividers\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"status-colors-universal\">Status Colors (Universal)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#status-colors-universal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Status Colors (Universal)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These colors have \u003Cstrong>consistent semantic meaning\u003C/strong> across both themes:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Token\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Tailwind Class\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>success\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#22c55e\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-green-500\u003C/code>\u003C/td>\u003Ctd>Pass, in-spec, valid\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>danger\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#ef4444\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-red-500\u003C/code>\u003C/td>\u003Ctd>Fail, out of spec (high), error\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>warning\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f59e0b\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-amber-500\u003C/code>\u003C/td>\u003Ctd>Warning, out of spec (low)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"status-usage-in-data-analysis\">Status Usage in Data Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#status-usage-in-data-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Status Usage in Data Analysis”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Scenario\u003C/th>\u003Cth>Color\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Value within spec limits\u003C/td>\u003Ctd>Green (\u003Ccode dir=\"auto\">#22c55e\u003C/code>)\u003C/td>\u003Ctd>Pass\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Value > USL\u003C/td>\u003Ctd>Red (\u003Ccode dir=\"auto\">#ef4444\u003C/code>)\u003C/td>\u003Ctd>Fail (too high)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Value < LSL\u003C/td>\u003Ctd>Amber (\u003Ccode dir=\"auto\">#f59e0b\u003C/code>)\u003C/td>\u003Ctd>Fail (too low)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cpk >= target\u003C/td>\u003Ctd>Green\u003C/td>\u003Ctd>Meets capability target (default 1.33)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cpk >= 75% of target\u003C/td>\u003Ctd>Amber\u003C/td>\u003Ctd>Approaching target, monitor\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cpk < 75% of target\u003C/td>\u003Ctd>Red\u003C/td>\u003Ctd>Needs improvement\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"brand-colors\">Brand Colors\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#brand-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Brand Colors”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Token\u003C/th>\u003Cth>Hex\u003C/th>\u003Cth>Tailwind Class\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>brand-primary\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#3b82f6\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-blue-600\u003C/code>\u003C/td>\u003Ctd>Primary buttons, accents\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>brand-hover\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#2563eb\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">hover:bg-blue-700\u003C/code>\u003C/td>\u003Ctd>Hover state\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>brand-light\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#60a5fa\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-blue-400\u003C/code>\u003C/td>\u003Ctd>Links, highlights\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"company-accent-azure-app-only\">Company Accent (Azure App Only)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#company-accent-azure-app-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Company Accent (Azure App Only)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Azure App users can customize the accent color via Settings > Appearance. The \u003Ccode dir=\"auto\">useThemeState\u003C/code> hook sets two CSS variables on \u003Ccode dir=\"auto\"><html>\u003C/code>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Variable\u003C/th>\u003Cth>Format\u003C/th>\u003Cth>Example\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">--accent\u003C/code>\u003C/td>\u003Ctd>RGB triplet\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">139 92 246\u003C/code>\u003C/td>\u003Ctd>Tailwind \u003Ccode dir=\"auto\">rgb(var(--accent))\u003C/code> utilities\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">--accent-hex\u003C/code>\u003C/td>\u003Ctd>Hex string\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#8b5cf6\u003C/code>\u003C/td>\u003Ctd>Inline \u003Ccode dir=\"auto\">style\u003C/code> where \u003Ccode dir=\"auto\">rgb()\u003C/code> isn’t practical\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>When no accent is set, both variables are removed and consumers fall back to their defaults.\u003C/p>\n\u003Cp>\u003Cstrong>Surfaces that consume \u003Ccode dir=\"auto\">--accent-hex\u003C/code>:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Property\u003C/th>\u003Cth>Fallback\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChartSourceBar\u003C/code>\u003C/td>\u003Ctd>Branding dot fill\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">accentColor\u003C/code> prop (blue-500)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FilterContextBar\u003C/code>\u003C/td>\u003Ctd>Variation percentage text\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#60a5fa\u003C/code> (blue-400)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ChartCard\u003C/code>\u003C/td>\u003Ctd>Hover border color\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">var(--color-edge-hover, #475569)\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>PWA has no accent set, so these surfaces always use their fallback values.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-colors\">Chart Colors\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-colors\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Colors”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>See \u003Ca href=\"../charts/colors.md\">Charts > Colors\u003C/a> for data visualization colors.\u003C/p>\n\u003Cp>Charts use the \u003Ccode dir=\"auto\">useChartTheme()\u003C/code> hook for theme-aware chrome colors:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useChartTheme } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">isDark\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// chrome.gridLine, chrome.labelPrimary, chrome.tooltipBg, etc.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useChartTheme } from '@variscout/charts';const { isDark, chrome } = useChartTheme();// chrome.gridLine, chrome.labelPrimary, chrome.tooltipBg, etc.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"implementation-examples\">Implementation Examples\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#implementation-examples\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation Examples”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-component\">PWA Component\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-component\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA Component”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Theme-aware card\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-surface-secondary border border-edge rounded-lg p-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content font-semibold\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Title\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Description\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content-muted text-sm\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Metadata\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Status display\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-green-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">In Spec\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-red-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Out of Spec\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Theme-aware card\u003Cdiv className="bg-surface-secondary border border-edge rounded-lg p-4"> \u003Ch2 className="text-content font-semibold">Title\u003C/h2> \u003Cp className="text-content-secondary">Description\u003C/p> \u003Cspan className="text-content-muted text-sm">Metadata\u003C/span>\u003C/div>// Status display\u003Cspan className="text-green-500">In Spec\u003C/span>\u003Cspan className="text-red-500">Out of Spec\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"chart-svg\">Chart SVG\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#chart-svg\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart SVG”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useChartTheme, chartColors } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/charts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useChartTheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Theme-aware chrome\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Line\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">stroke\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">gridLine\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">fill\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chrome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">labelPrimary\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Axis Label\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Universal data colors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getPointColor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">usl\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">lsl\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">?:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(usl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> !== \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> && \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> > \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">usl)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">fail\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Red\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(lsl\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> !== \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> && \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> < \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">lsl)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">warning\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Amber\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartColors\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">pass\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Green\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useChartTheme, chartColors } from '@variscout/charts';const { chrome } = useChartTheme();// Theme-aware chrome\u003CLine stroke={chrome.gridLine} />\u003Ctext fill={chrome.labelPrimary}>Axis Label\u003C/text>// Universal data colorsconst getPointColor = (value: number, usl?: number, lsl?: number) => { if (usl !== undefined && value > usl) return chartColors.fail; // Red if (lsl !== undefined && value \u003C lsl) return chartColors.warning; // Amber return chartColors.pass; // Green};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"shared-component-color-schemes\">Shared Component Color Schemes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#shared-component-color-schemes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Shared Component Color Schemes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Components in \u003Ccode dir=\"auto\">@variscout/ui\u003C/code> use a \u003Cstrong>colorScheme prop pattern\u003C/strong> for platform-agnostic styling:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pattern-overview\">Pattern Overview\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pattern-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pattern Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Component defines color scheme interface\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ComponentColorScheme {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">containerBg\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Tailwind class for background\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">border\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Tailwind class for borders\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">textMuted\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Tailwind class for muted text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// ... component-specific color slots\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Default uses PWA semantic tokens\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">defaultColorScheme\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ComponentColorScheme\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">containerBg: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-surface-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">border: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">border-edge\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">textMuted: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content-muted\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Component defines color scheme interfaceinterface ComponentColorScheme { containerBg: string; // Tailwind class for background border: string; // Tailwind class for borders textMuted: string; // Tailwind class for muted text // ... component-specific color slots}// Default uses PWA semantic tokensconst defaultColorScheme: ComponentColorScheme = { containerBg: 'bg-surface-secondary', border: 'border-edge', textMuted: 'text-content-muted',};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"color-scheme-mapping\">Color Scheme Mapping\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#color-scheme-mapping\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Color Scheme Mapping”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both PWA and Azure use the same semantic tokens. The Slate equivalents are shown for historical reference (Azure previously used hardcoded Slate classes before the visual convergence migration):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Semantic Token\u003C/th>\u003Cth>Resolved Value (Dark)\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-slate-900\u003C/code>\u003C/td>\u003Ctd>Main container\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface-secondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-slate-800\u003C/code>\u003C/td>\u003Ctd>Cards, panels\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface-tertiary/50\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-slate-700/50\u003C/code>\u003C/td>\u003Ctd>Hover backgrounds\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">border-edge\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">border-slate-700\u003C/code>\u003C/td>\u003Ctd>Primary borders\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">border-edge-secondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">border-slate-600\u003C/code>\u003C/td>\u003Ctd>Secondary borders\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">text-content\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-white\u003C/code>\u003C/td>\u003Ctd>Primary text\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">text-content-secondary\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-slate-400\u003C/code>\u003C/td>\u003Ctd>Secondary text\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">text-content-muted\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-slate-500\u003C/code>\u003C/td>\u003Ctd>Muted/disabled text\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">hover:text-content\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">hover:text-slate-300\u003C/code>\u003C/td>\u003Ctd>Hover text\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"available-color-schemes\">Available Color Schemes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#available-color-schemes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Available Color Schemes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each component exports a single \u003Ccode dir=\"auto\">defaultColorScheme\u003C/code> using semantic tokens. Both PWA and Azure apps use these defaults:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Default Export\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FilterBreadcrumb\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">filterBreadcrumbDefaultColorScheme\u003C/code>\u003C/td>\u003Ctd>Semantic tokens, used by both apps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FilterChipDropdown\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">filterChipDropdownDefaultColorScheme\u003C/code>\u003C/td>\u003Ctd>Semantic tokens, used by both apps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">VariationBar\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">variationBarDefaultColorScheme\u003C/code>\u003C/td>\u003Ctd>Semantic tokens, used by both apps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">AnovaResults\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">anovaDefaultColorScheme\u003C/code>\u003C/td>\u003Ctd>Semantic tokens, used by both apps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">YAxisPopover\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">yAxisPopoverDefaultColorScheme\u003C/code>\u003C/td>\u003Ctd>Semantic tokens, used by both apps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceSetupPanelBase\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">performanceSetupPanelDefaultColorScheme\u003C/code>\u003C/td>\u003Ctd>Semantic tokens, used by both apps\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usage-in-apps\">Usage in Apps\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usage-in-apps\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Usage in Apps”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Both PWA and Azure use the default color scheme (semantic tokens). No explicit \u003Ccode dir=\"auto\">colorScheme\u003C/code> prop is needed:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { FilterBreadcrumb } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/ui\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Default colorScheme uses semantic tokens — works for both PWA and Azure\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">FilterBreadcrumb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">props\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { FilterBreadcrumb } from '@variscout/ui';// Default colorScheme uses semantic tokens — works for both PWA and Azure\u003CFilterBreadcrumb {...props} />;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"nested-color-schemes\">Nested Color Schemes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#nested-color-schemes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Nested Color Schemes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Some components contain other themeable components. They use nested color schemes:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> FilterBreadcrumbColorScheme {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">containerBg\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">border\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Nested schemes for child components\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">variationBar\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">VariationBarColorScheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">dropdown\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">FilterChipDropdownColorScheme\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"interface FilterBreadcrumbColorScheme { containerBg: string; border: string; // Nested schemes for child components variationBar: VariationBarColorScheme; dropdown: FilterChipDropdownColorScheme;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"creating-new-color-schemes\">Creating New Color Schemes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#creating-new-color-schemes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Creating New Color Schemes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When extracting a component to \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Identify color slots\u003C/strong> needed by the component\u003C/li>\n\u003Cli>\u003Cstrong>Create interface\u003C/strong> with all color slots\u003C/li>\n\u003Cli>\u003Cstrong>Define default scheme\u003C/strong> using semantic tokens\u003C/li>\n\u003Cli>\u003Cstrong>Export\u003C/strong> from component index and main package index\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">packages/ui/src/components/MyComponent/MyComponent.tsx\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> MyComponentColorScheme {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">background\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">text\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">border\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">defaultColorScheme\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">MyComponentColorScheme\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">background: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-surface-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">text: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-content\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">border: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">border-edge\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export interface MyComponentColorScheme { background: string; text: string; border: string;}export const defaultColorScheme: MyComponentColorScheme = { background: 'bg-surface-secondary', text: 'text-content', border: 'border-edge',};\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"accessibility\">Accessibility\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#accessibility\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Accessibility”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All color combinations meet WCAG AA contrast requirements:\u003C/p>\n\u003Cul>\n\u003Cli>Text on background: minimum 4.5:1 ratio\u003C/li>\n\u003Cli>Large text: minimum 3:1 ratio\u003C/li>\n\u003Cli>UI components: minimum 3:1 ratio\u003C/li>\n\u003C/ul>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Combination\u003C/th>\u003Cth>Dark Ratio\u003C/th>\u003Cth>Light Ratio\u003C/th>\u003Cth>Pass\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>text-content on bg-surface\u003C/td>\u003Ctd>13.5:1\u003C/td>\u003Ctd>15.4:1\u003C/td>\u003Ctd>AAA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>text-content-secondary on bg-surface-secondary\u003C/td>\u003Ctd>5.2:1\u003C/td>\u003Ctd>4.8:1\u003C/td>\u003Ctd>AA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>green-500 on bg-surface-secondary\u003C/td>\u003Ctd>4.8:1\u003C/td>\u003Ctd>4.5:1\u003C/td>\u003Ctd>AA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>red-500 on bg-surface-secondary\u003C/td>\u003Ctd>4.6:1\u003C/td>\u003Ctd>4.3:1\u003C/td>\u003Ctd>AA\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 11169, + "localImagePaths": 11232, + "remoteImagePaths": 11233, + "frontmatter": 11234, + "imagePaths": 11235 + }, + [ + 11170, 11172, 11173, 11176, 11179, 11182, 11185, 11188, 11191, 11194, 11197, 11200, 11201, + 11204, 11207, 11210, 11213, 11216, 11219, 11222, 11225, 11228, 11231 + ], + { "depth": 30, "slug": 11171, "text": 11159 }, + "color-system", + { "depth": 33, "slug": 9832, "text": 9833 }, + { "depth": 33, "slug": 11174, "text": 11175 }, + "css-variables", + "CSS Variables", + { "depth": 33, "slug": 11177, "text": 11178 }, + "semantic-tailwind-classes", + "Semantic Tailwind Classes", + { "depth": 79, "slug": 11180, "text": 11181 }, + "surface-colors-backgrounds", + "Surface Colors (Backgrounds)", + { "depth": 79, "slug": 11183, "text": 11184 }, + "content-colors-text", + "Content Colors (Text)", + { "depth": 79, "slug": 11186, "text": 11187 }, + "edge-colors-borders", + "Edge Colors (Borders)", + { "depth": 33, "slug": 11189, "text": 11190 }, + "status-colors-universal", + "Status Colors (Universal)", + { "depth": 79, "slug": 11192, "text": 11193 }, + "status-usage-in-data-analysis", + "Status Usage in Data Analysis", + { "depth": 33, "slug": 11195, "text": 11196 }, + "brand-colors", + "Brand Colors", + { "depth": 79, "slug": 11198, "text": 11199 }, + "company-accent-azure-app-only", + "Company Accent (Azure App Only)", + { "depth": 33, "slug": 9937, "text": 9925 }, + { "depth": 33, "slug": 11202, "text": 11203 }, + "implementation-examples", + "Implementation Examples", + { "depth": 79, "slug": 11205, "text": 11206 }, + "pwa-component", + "PWA Component", + { "depth": 79, "slug": 11208, "text": 11209 }, + "chart-svg", + "Chart SVG", + { "depth": 33, "slug": 11211, "text": 11212 }, + "shared-component-color-schemes", + "Shared Component Color Schemes", + { "depth": 79, "slug": 11214, "text": 11215 }, + "pattern-overview", + "Pattern Overview", + { "depth": 79, "slug": 11217, "text": 11218 }, + "color-scheme-mapping", + "Color Scheme Mapping", + { "depth": 79, "slug": 11220, "text": 11221 }, + "available-color-schemes", + "Available Color Schemes", + { "depth": 79, "slug": 11223, "text": 11224 }, + "usage-in-apps", + "Usage in Apps", + { "depth": 79, "slug": 11226, "text": 11227 }, + "nested-color-schemes", + "Nested Color Schemes", + { "depth": 79, "slug": 11229, "text": 11230 }, + "creating-new-color-schemes", + "Creating New Color Schemes", + { "depth": 33, "slug": 3565, "text": 3566 }, + [], + [], + { "title": 11159 }, + [], + "06-design-system/foundations/spacing", + { + "id": 11236, + "data": 11238, + "body": 11243, + "filePath": 11244, + "digest": 11245, + "rendered": 11246 + }, + { + "title": 11239, + "editUrl": 16, + "head": 11240, + "template": 18, + "sidebar": 11241, + "pagefind": 16, + "draft": 20 + }, + "Spacing", + [], + { "hidden": 20, "attrs": 11242 }, + {}, + "# Spacing\n\nVariScout uses a 4px base unit spacing scale.\n\n## Scale\n\n| Token | Value | PWA (Tailwind) | Usage |\n| ----- | ----- | -------------- | -------------- |\n| xs | 4px | `p-1`, `gap-1` | Minimal gaps |\n| sm | 8px | `p-2`, `gap-2` | Tight spacing |\n| md | 12px | `p-3`, `gap-3` | Default gaps |\n| lg | 16px | `p-4`, `gap-4` | Card padding |\n| xl | 24px | `p-6`, `gap-6` | Section gaps |\n| 2xl | 32px | `p-8`, `gap-8` | Major sections |\n\n## Common Patterns\n\n### Card Padding\n\n```jsx\n// Standard card\n\u003Cdiv className=\"p-6\">...\u003C/div>\n\n// Compact card\n\u003Cdiv className=\"p-4\">...\u003C/div>\n\n// Header/footer\n\u003Cdiv className=\"px-4 py-3\">...\u003C/div>\n```\n\n### Gap Spacing\n\n```jsx\n// Button group\n\u003Cdiv className=\"flex gap-2\">...\u003C/div>\n\n// Form fields\n\u003Cdiv className=\"flex flex-col gap-4\">...\u003C/div>\n\n// Section layout\n\u003Cdiv className=\"flex flex-col gap-6\">...\u003C/div>\n```\n\n### Margins\n\n```jsx\n// Between sections\n\u003Cdiv className=\"mb-6\">...\u003C/div>\n\n// Between related items\n\u003Cdiv className=\"mb-2\">...\u003C/div>\n\n// Card margin in grid\n\u003Cdiv className=\"m-4\">...\u003C/div>\n```\n\n## Border Radius\n\n| Token | Value | PWA (Tailwind) | Usage |\n| ----- | ------ | -------------- | ---------------------- |\n| sm | 4px | `rounded` | Small elements, badges |\n| md | 8px | `rounded-lg` | Buttons, inputs |\n| lg | 12px | `rounded-xl` | Cards |\n| xl | 16px | `rounded-2xl` | Modals, large cards |\n| full | 9999px | `rounded-full` | Pills, circular |\n\n## Component Spacing\n\n### Buttons\n\n```jsx\n// PWA — default (app context, mouse-primary)\n\u003Cbutton className=\"px-4 py-2\">...\u003C/button>\n\n// PWA — small\n\u003Cbutton className=\"px-3 py-1.5\">...\u003C/button>\n\n// PWA — icon button\n\u003Cbutton className=\"p-2\">...\u003C/button>\n```\n\n```html\n\u003C!-- Website — default (marketing site, larger touch targets) -->\n\u003Ca class=\"btn btn-primary\">...\u003C/a>\n\u003C!-- py-2.5, ~40px height -->\n\n\u003C!-- Website — CTA override for 44px+ touch target -->\n\u003Ca class=\"btn btn-primary py-3\">...\u003C/a>\n```\n\n### Inputs\n\n```jsx\n\u003Cinput className=\"px-3 py-2\" />\n```\n\n### Filter Chips\n\n```jsx\n\u003Cspan className=\"px-2.5 py-1\">...\u003C/span>\n```\n\n### Modal\n\n```jsx\n\u003Cdiv className=\"p-6\"> {/* Header */}\n\u003Cdiv className=\"p-6\"> {/* Body */}\n\u003Cdiv className=\"px-6 py-4\"> {/* Footer */}\n```\n\n## Chart Margins\n\nSee [Charts > Responsive](../charts/responsive.md) for chart-specific margins.", + "src/content/docs/06-design-system/foundations/spacing.md", + "a0a001d1ba12d242", + { "html": 11247, "metadata": 11248 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"spacing\">Spacing\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#spacing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Spacing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses a 4px base unit spacing scale.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"scale\">Scale\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#scale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scale”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Token\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>PWA (Tailwind)\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>xs\u003C/td>\u003Ctd>4px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">p-1\u003C/code>, \u003Ccode dir=\"auto\">gap-1\u003C/code>\u003C/td>\u003Ctd>Minimal gaps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>sm\u003C/td>\u003Ctd>8px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">p-2\u003C/code>, \u003Ccode dir=\"auto\">gap-2\u003C/code>\u003C/td>\u003Ctd>Tight spacing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>md\u003C/td>\u003Ctd>12px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">p-3\u003C/code>, \u003Ccode dir=\"auto\">gap-3\u003C/code>\u003C/td>\u003Ctd>Default gaps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>lg\u003C/td>\u003Ctd>16px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">p-4\u003C/code>, \u003Ccode dir=\"auto\">gap-4\u003C/code>\u003C/td>\u003Ctd>Card padding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>xl\u003C/td>\u003Ctd>24px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">p-6\u003C/code>, \u003Ccode dir=\"auto\">gap-6\u003C/code>\u003C/td>\u003Ctd>Section gaps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2xl\u003C/td>\u003Ctd>32px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">p-8\u003C/code>, \u003Ccode dir=\"auto\">gap-8\u003C/code>\u003C/td>\u003Ctd>Major sections\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"common-patterns\">Common Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#common-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"card-padding\">Card Padding\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#card-padding\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Card Padding”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Standard card\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-6\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Compact card\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Header/footer\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-4 py-3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Standard card\u003Cdiv className="p-6">...\u003C/div>// Compact card\u003Cdiv className="p-4">...\u003C/div>// Header/footer\u003Cdiv className="px-4 py-3">...\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"gap-spacing\">Gap Spacing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#gap-spacing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Gap Spacing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Button group\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex gap-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Form fields\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col gap-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Section layout\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col gap-6\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Button group\u003Cdiv className="flex gap-2">...\u003C/div>// Form fields\u003Cdiv className="flex flex-col gap-4">...\u003C/div>// Section layout\u003Cdiv className="flex flex-col gap-6">...\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"margins\">Margins\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#margins\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Margins”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Between sections\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">mb-6\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Between related items\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">mb-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Card margin in grid\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">m-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Between sections\u003Cdiv className="mb-6">...\u003C/div>// Between related items\u003Cdiv className="mb-2">...\u003C/div>// Card margin in grid\u003Cdiv className="m-4">...\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"border-radius\">Border Radius\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#border-radius\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Border Radius”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Token\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>PWA (Tailwind)\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>sm\u003C/td>\u003Ctd>4px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">rounded\u003C/code>\u003C/td>\u003Ctd>Small elements, badges\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>md\u003C/td>\u003Ctd>8px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">rounded-lg\u003C/code>\u003C/td>\u003Ctd>Buttons, inputs\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>lg\u003C/td>\u003Ctd>12px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">rounded-xl\u003C/code>\u003C/td>\u003Ctd>Cards\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>xl\u003C/td>\u003Ctd>16px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">rounded-2xl\u003C/code>\u003C/td>\u003Ctd>Modals, large cards\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>full\u003C/td>\u003Ctd>9999px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">rounded-full\u003C/code>\u003C/td>\u003Ctd>Pills, circular\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"component-spacing\">Component Spacing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#component-spacing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Component Spacing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"buttons\">Buttons\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#buttons\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Buttons”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PWA — default (app context, mouse-primary)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-4 py-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PWA — small\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-3 py-1.5\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// PWA — icon button\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// PWA — default (app context, mouse-primary)\u003Cbutton className="px-4 py-2">...\u003C/button>// PWA — small\u003Cbutton className="px-3 py-1.5">...\u003C/button>// PWA — icon button\u003Cbutton className="p-2">...\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"html\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"><!-- Website — default (marketing site, larger touch targets) -->\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">class\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">btn btn-primary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"><!-- py-2.5, ~40px height -->\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"><!-- Website — CTA override for 44px+ touch target -->\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">class\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">btn btn-primary py-3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">a\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003C!-- Website — default (marketing site, larger touch targets) -->\u003Ca class="btn btn-primary">...\u003C/a>\u003C!-- py-2.5, ~40px height -->\u003C!-- Website — CTA override for 44px+ touch target -->\u003Ca class="btn btn-primary py-3">...\u003C/a>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"inputs\">Inputs\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#inputs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Inputs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">input\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-3 py-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cinput className="px-3 py-2" />\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filter-chips\">Filter Chips\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filter-chips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter Chips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-2.5 py-1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cspan className="px-2.5 py-1">...\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"modal\">Modal\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#modal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Modal”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-6\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Header */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">p-6\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Body */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-6 py-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Footer */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="p-6"> {/* Header */}\u003Cdiv className="p-6"> {/* Body */}\u003Cdiv className="px-6 py-4"> {/* Footer */}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-margins\">Chart Margins\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-margins\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Margins”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>See \u003Ca href=\"../charts/responsive.md\">Charts > Responsive\u003C/a> for chart-specific margins.\u003C/p>", + { + "headings": 11249, + "localImagePaths": 11280, + "remoteImagePaths": 11281, + "frontmatter": 11282, + "imagePaths": 11283 + }, + [11250, 11252, 11255, 11256, 11259, 11262, 11263, 11266, 11269, 11270, 11273, 11274, 11277], + { "depth": 30, "slug": 11251, "text": 11239 }, + "spacing", + { "depth": 33, "slug": 11253, "text": 11254 }, + "scale", + "Scale", + { "depth": 33, "slug": 7805, "text": 7806 }, + { "depth": 79, "slug": 11257, "text": 11258 }, + "card-padding", + "Card Padding", + { "depth": 79, "slug": 11260, "text": 11261 }, + "gap-spacing", + "Gap Spacing", + { "depth": 79, "slug": 10598, "text": 10599 }, + { "depth": 33, "slug": 11264, "text": 11265 }, + "border-radius", + "Border Radius", + { "depth": 33, "slug": 11267, "text": 11268 }, + "component-spacing", + "Component Spacing", + { "depth": 79, "slug": 10732, "text": 10720 }, + { "depth": 79, "slug": 11271, "text": 11272 }, + "inputs", + "Inputs", + { "depth": 79, "slug": 7397, "text": 7398 }, + { "depth": 79, "slug": 11275, "text": 11276 }, + "modal", + "Modal", + { "depth": 33, "slug": 11278, "text": 11279 }, + "chart-margins", + "Chart Margins", + [], + [], + { "title": 11239 }, + [], + "06-design-system/foundations/typography", + { + "id": 11284, + "data": 11286, + "body": 11290, + "filePath": 11291, + "digest": 11292, + "rendered": 11293 + }, + { + "title": 10029, + "editUrl": 16, + "head": 11287, + "template": 18, + "sidebar": 11288, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 11289 }, + {}, + "# Typography\n\n## Font Stack\n\nVariScout uses system fonts for optimal performance and native appearance.\n\n```css\nfont-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n sans-serif;\n```\n\nFor numeric/data values:\n\n```css\nfont-family: ui-monospace, 'SF Mono', Monaco, 'Cascadia Code', monospace;\n```\n\n## Size Scale\n\n| Token | Size | PWA (Tailwind) | Usage |\n| ------- | ---- | -------------- | ---------------------- |\n| caption | 10px | `text-[10px]` | Chart labels, branding |\n| small | 12px | `text-xs` | Helper text, badges |\n| body | 14px | `text-sm` | Default body text |\n| medium | 16px | `text-base` | Emphasized text |\n| large | 18px | `text-lg` | Section headings |\n| title | 20px | `text-xl` | Page titles |\n\n## Weight Scale\n\n| Token | Weight | PWA (Tailwind) | Usage |\n| -------- | ------ | --------------- | --------------- |\n| regular | 400 | `font-normal` | Body text |\n| medium | 500 | `font-medium` | Labels, buttons |\n| semibold | 600 | `font-semibold` | Emphasis |\n| bold | 700 | `font-bold` | Headings |\n\n## Line Height\n\n| Context | Value | PWA (Tailwind) |\n| ------- | ----- | ----------------- |\n| Tight | 1.25 | `leading-tight` |\n| Normal | 1.5 | `leading-normal` |\n| Relaxed | 1.75 | `leading-relaxed` |\n\n## Text Styles\n\n### Headings\n\n```jsx\n// Page title\n\u003Ch1 className=\"text-lg font-bold text-white\">Dashboard\u003C/h1>\n\n// Section heading\n\u003Ch2 className=\"text-sm font-semibold text-slate-400 uppercase tracking-wider\">\n Analysis Summary\n\u003C/h2>\n\n// Card title\n\u003Ch3 className=\"text-base font-semibold text-white\">I-Chart\u003C/h3>\n```\n\n### Body Text\n\n```jsx\n// Primary text\n\u003Cp className=\"text-sm text-slate-100\">Main content\u003C/p>\n\n// Secondary text\n\u003Cp className=\"text-xs text-slate-400\">Description or helper\u003C/p>\n\n// Muted text\n\u003Cspan className=\"text-xs text-slate-500\">Timestamp\u003C/span>\n```\n\n### Data Values\n\n```jsx\n// Numeric values (monospace)\n\u003Cspan className=\"font-mono text-white\">{value.toFixed(2)}\u003C/span>\n\n// Stat labels (uppercase)\n\u003Cspan className=\"text-[10px] text-slate-400 uppercase tracking-wider\">\n Mean\n\u003C/span>\n\n// Large stats\n\u003Cspan className=\"text-2xl font-bold text-white\">{stats.cpk.toFixed(2)}\u003C/span>\n```\n\n## Special Treatments\n\n### Gradient Text (Logo)\n\n```jsx\n\u003Ch1 className=\"bg-gradient-to-r from-white to-slate-400 bg-clip-text text-transparent\">\n VariScout\n\u003C/h1>\n```\n\n### Truncation\n\n```jsx\n\u003Cspan className=\"truncate max-w-[200px]\">{longText}\u003C/span>\n```\n\n## Chart Typography\n\n| Element | Size | Weight | Color |\n| ------------- | ---- | ------ | --------- |\n| Axis labels | 11px | 400 | `#94a3b8` |\n| Tick labels | 10px | 400 | `#94a3b8` |\n| Stat overlays | 12px | 600 | `#f1f5f9` |\n| Branding | 10px | 500 | `#94a3b8` |\n\n### Responsive Scaling\n\n| Breakpoint | Tick | Axis | Stat |\n| ------------------ | ---- | ---- | ---- |\n| Mobile (\u003C400px) | 8px | 9px | 10px |\n| Tablet (400-768px) | 9px | 10px | 11px |\n| Desktop (>768px) | 11px | 13px | 12px |", + "src/content/docs/06-design-system/foundations/typography.md", + "9e5cce0eda0eddb3", + { "html": 11294, "metadata": 11295 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"typography\">Typography\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#typography\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Typography”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"font-stack\">Font Stack\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#font-stack\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Font Stack”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses system fonts for optimal performance and native appearance.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">font-family\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">system-ui\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">-apple-system,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">BlinkMacSystemFont,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">'Segoe UI',\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Roboto,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">sans-serif\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>For numeric/data values:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">font-family\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">: \u003C/span>\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">ui-monospace\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, 'SF Mono', Monaco, 'Cascadia Code', monospace;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"font-family: ui-monospace, 'SF Mono', Monaco, 'Cascadia Code', monospace;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"size-scale\">Size Scale\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#size-scale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Size Scale”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Token\u003C/th>\u003Cth>Size\u003C/th>\u003Cth>PWA (Tailwind)\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>caption\u003C/td>\u003Ctd>10px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-[10px]\u003C/code>\u003C/td>\u003Ctd>Chart labels, branding\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>small\u003C/td>\u003Ctd>12px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-xs\u003C/code>\u003C/td>\u003Ctd>Helper text, badges\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>body\u003C/td>\u003Ctd>14px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-sm\u003C/code>\u003C/td>\u003Ctd>Default body text\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>medium\u003C/td>\u003Ctd>16px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-base\u003C/code>\u003C/td>\u003Ctd>Emphasized text\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>large\u003C/td>\u003Ctd>18px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-lg\u003C/code>\u003C/td>\u003Ctd>Section headings\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>title\u003C/td>\u003Ctd>20px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-xl\u003C/code>\u003C/td>\u003Ctd>Page titles\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"weight-scale\">Weight Scale\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#weight-scale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Weight Scale”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Token\u003C/th>\u003Cth>Weight\u003C/th>\u003Cth>PWA (Tailwind)\u003C/th>\u003Cth>Usage\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>regular\u003C/td>\u003Ctd>400\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">font-normal\u003C/code>\u003C/td>\u003Ctd>Body text\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>medium\u003C/td>\u003Ctd>500\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">font-medium\u003C/code>\u003C/td>\u003Ctd>Labels, buttons\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>semibold\u003C/td>\u003Ctd>600\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">font-semibold\u003C/code>\u003C/td>\u003Ctd>Emphasis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>bold\u003C/td>\u003Ctd>700\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">font-bold\u003C/code>\u003C/td>\u003Ctd>Headings\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"line-height\">Line Height\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#line-height\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Line Height”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Context\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>PWA (Tailwind)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Tight\u003C/td>\u003Ctd>1.25\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">leading-tight\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Normal\u003C/td>\u003Ctd>1.5\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">leading-normal\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Relaxed\u003C/td>\u003Ctd>1.75\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">leading-relaxed\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"text-styles\">Text Styles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#text-styles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Text Styles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"headings\">Headings\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#headings\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Headings”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Page title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h1\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-lg font-bold text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Dashboard\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h1\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Section heading\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm font-semibold text-slate-400 uppercase tracking-wider\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Analysis Summary\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Card title\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h3\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-base font-semibold text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">I-Chart\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h3\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Page title\u003Ch1 className="text-lg font-bold text-white">Dashboard\u003C/h1>// Section heading\u003Ch2 className="text-sm font-semibold text-slate-400 uppercase tracking-wider"> Analysis Summary\u003C/h2>// Card title\u003Ch3 className="text-base font-semibold text-white">I-Chart\u003C/h3>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"body-text\">Body Text\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#body-text\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Body Text”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Primary text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm text-slate-100\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Main content\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Secondary text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs text-slate-400\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Description or helper\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Muted text\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs text-slate-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Timestamp\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Primary text\u003Cp className="text-sm text-slate-100">Main content\u003C/p>// Secondary text\u003Cp className="text-xs text-slate-400">Description or helper\u003C/p>// Muted text\u003Cspan className="text-xs text-slate-500">Timestamp\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-values\">Data Values\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-values\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Values”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Numeric values (monospace)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">font-mono text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toFixed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Stat labels (uppercase)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-[10px] text-slate-400 uppercase tracking-wider\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Mean\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Large stats\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-2xl font-bold text-white\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">stats\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">cpk\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">toFixed\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Numeric values (monospace)\u003Cspan className="font-mono text-white">{value.toFixed(2)}\u003C/span>// Stat labels (uppercase)\u003Cspan className="text-[10px] text-slate-400 uppercase tracking-wider"> Mean\u003C/span>// Large stats\u003Cspan className="text-2xl font-bold text-white">{stats.cpk.toFixed(2)}\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"special-treatments\">Special Treatments\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#special-treatments\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Special Treatments”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"gradient-text-logo\">Gradient Text (Logo)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#gradient-text-logo\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Gradient Text (Logo)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h1\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-gradient-to-r from-white to-slate-400 bg-clip-text text-transparent\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">VariScout\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h1\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Ch1 className="bg-gradient-to-r from-white to-slate-400 bg-clip-text text-transparent"> VariScout\u003C/h1>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"truncation\">Truncation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#truncation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Truncation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">truncate max-w-[200px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">longText\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cspan className="truncate max-w-[200px]">{longText}\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-typography\">Chart Typography\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-typography\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Typography”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Size\u003C/th>\u003Cth>Weight\u003C/th>\u003Cth>Color\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Axis labels\u003C/td>\u003Ctd>11px\u003C/td>\u003Ctd>400\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tick labels\u003C/td>\u003Ctd>10px\u003C/td>\u003Ctd>400\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Stat overlays\u003C/td>\u003Ctd>12px\u003C/td>\u003Ctd>600\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#f1f5f9\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Branding\u003C/td>\u003Ctd>10px\u003C/td>\u003Ctd>500\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">#94a3b8\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"responsive-scaling\">Responsive Scaling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#responsive-scaling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Responsive Scaling”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Breakpoint\u003C/th>\u003Cth>Tick\u003C/th>\u003Cth>Axis\u003C/th>\u003Cth>Stat\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Mobile (<400px)\u003C/td>\u003Ctd>8px\u003C/td>\u003Ctd>9px\u003C/td>\u003Ctd>10px\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tablet (400-768px)\u003C/td>\u003Ctd>9px\u003C/td>\u003Ctd>10px\u003C/td>\u003Ctd>11px\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Desktop (>768px)\u003C/td>\u003Ctd>11px\u003C/td>\u003Ctd>13px\u003C/td>\u003Ctd>12px\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 11296, + "localImagePaths": 11337, + "remoteImagePaths": 11338, + "frontmatter": 11339, + "imagePaths": 11340 + }, + [ + 11297, 11298, 11301, 11304, 11307, 11310, 11313, 11316, 11319, 11322, 11325, 11328, 11331, 11334 + ], + { "depth": 30, "slug": 10028, "text": 10029 }, + { "depth": 33, "slug": 11299, "text": 11300 }, + "font-stack", + "Font Stack", + { "depth": 33, "slug": 11302, "text": 11303 }, + "size-scale", + "Size Scale", + { "depth": 33, "slug": 11305, "text": 11306 }, + "weight-scale", + "Weight Scale", + { "depth": 33, "slug": 11308, "text": 11309 }, + "line-height", + "Line Height", + { "depth": 33, "slug": 11311, "text": 11312 }, + "text-styles", + "Text Styles", + { "depth": 79, "slug": 11314, "text": 11315 }, + "headings", + "Headings", + { "depth": 79, "slug": 11317, "text": 11318 }, + "body-text", + "Body Text", + { "depth": 79, "slug": 11320, "text": 11321 }, + "data-values", + "Data Values", + { "depth": 33, "slug": 11323, "text": 11324 }, + "special-treatments", + "Special Treatments", + { "depth": 79, "slug": 11326, "text": 11327 }, + "gradient-text-logo", + "Gradient Text (Logo)", + { "depth": 79, "slug": 11329, "text": 11330 }, + "truncation", + "Truncation", + { "depth": 33, "slug": 11332, "text": 11333 }, + "chart-typography", + "Chart Typography", + { "depth": 79, "slug": 11335, "text": 11336 }, + "responsive-scaling", + "Responsive Scaling", + [], + [], + { "title": 10029 }, + [], + "08-products/azure/arm-template", + { + "id": 11341, + "data": 11343, + "body": 11348, + "filePath": 11349, + "digest": 11350, + "rendered": 11351 + }, + { + "title": 11344, + "editUrl": 16, + "head": 11345, + "template": 18, + "sidebar": 11346, + "pagefind": 16, + "draft": 20 + }, + "ARM Template Documentation", + [], + { "hidden": 20, "attrs": 11347 }, + {}, + "# ARM Template Documentation\n\nAzure Resource Manager (ARM) template for VariScout Managed Application deployment.\n\n---\n\n## Overview\n\nThe ARM template deploys VariScout to a customer's Azure subscription as a Managed Application with:\n\n- Azure App Service (hosting via `WEBSITE_RUN_FROM_PACKAGE`)\n- App Service Authentication (EasyAuth) with Azure AD\n- Configuration settings (all features enabled)\n\nThe customer provides their own App Registration (created before deployment) so that VariScout can authenticate users and access OneDrive via Graph API (Team plan).\n\n**No backend resources** - the app runs entirely in the browser. The App Service serves the static build as a zip package.\n\n### Managed Application Package\n\nThe template is packaged as a `.zip` file for Partner Center:\n\n```\nvariscout-managed-app.zip\n├── mainTemplate.json # ARM template (this document)\n└── createUiDefinition.json # Azure portal deployment wizard\n```\n\n---\n\n## Pre-Deployment: Create App Registration\n\nBefore deploying VariScout, the customer must create an App Registration in Azure AD. This is required because Managed Applications cannot create App Registrations in the customer's tenant.\n\n### Step-by-Step\n\n1. Go to **Azure Portal > Azure Active Directory > App registrations > New registration**\n2. Set **Name** to something like `VariScout`\n3. Set **Supported account types** to \"Accounts in this organizational directory only\" (single tenant)\n4. Set **Redirect URI** (Web platform) to:\n ```\n https://\u003Cyour-app-name>.azurewebsites.net/.auth/login/aad/callback\n ```\n Replace `\u003Cyour-app-name>` with the App Service name you'll use during deployment.\n5. Click **Register**\n6. Go to **Authentication** > **Implicit grant and hybrid flows** and check **ID tokens**. This is required for EasyAuth's hybrid authentication flow.\n7. Copy the **Application (client) ID** from the Overview page — you'll need this during deployment\n\n### Add API Permissions\n\n1. Go to **API permissions > Add a permission > Microsoft Graph > Delegated permissions**\n2. Add permissions based on your plan:\n\n **Standard plan (€99/month):**\n - `User.Read` — sign-in and read user profile\n\n **Team plan (€299/month) — add all of the above, plus:**\n - `Files.ReadWrite` — read and write user's OneDrive files (for project sync)\n - `Files.ReadWrite.All` — channel SharePoint access (for shared projects)\n - `Channel.ReadBasic.All` — channel listing (for Teams integration)\n\n3. Click **Grant admin consent** (optional for Standard; recommended for Team plan, otherwise users consent on first login)\n\n### Create Client Secret\n\n1. Go to **Certificates & secrets > Client secrets > New client secret**\n2. Set a description (e.g., \"VariScout EasyAuth\") and expiration (recommended: 24 months)\n3. Click **Add**\n4. **Copy the secret value immediately** — it won't be shown again. You'll need this during deployment.\n\n---\n\n## Parameters\n\n### Required Parameters\n\n| Parameter | Type | Description |\n| -------------- | ------------ | ------------------------------------------------- |\n| `clientId` | string | Application (client) ID from the App Registration |\n| `clientSecret` | secureString | Client secret value from the App Registration |\n\n### Optional Parameters\n\n| Parameter | Type | Default | Description |\n| --------------- | ------ | ----------------------- | ------------------------------------------------------------ |\n| `location` | string | Resource group location | Azure region for deployment |\n| `appName` | string | `variscout-{unique}` | Name for App Service (3-24) |\n| `variscoutPlan` | string | `standard` | Plan: `standard` (local files) or `team` (+ OneDrive, Teams) |\n\n---\n\n## Resources\n\nAll resources are tagged with `product: VariScout`, `plan: \u003Cselected>`, and `managedBy: AzureMarketplace` for cost tracking and governance.\n\n### 1. App Service Plan\n\nLinux B1 plan for hosting the App Service:\n\n```json\n{\n \"type\": \"Microsoft.Web/serverfarms\",\n \"apiVersion\": \"2024-04-01\",\n \"name\": \"[variables('appServicePlanName')]\",\n \"location\": \"[parameters('location')]\",\n \"kind\": \"linux\",\n \"sku\": {\n \"name\": \"B1\",\n \"tier\": \"Basic\"\n },\n \"properties\": {\n \"reserved\": true\n }\n}\n```\n\n### 2. App Service\n\nServes the VariScout build via `WEBSITE_RUN_FROM_PACKAGE`. The client secret is stored as an app setting for EasyAuth to use:\n\n```json\n{\n \"type\": \"Microsoft.Web/sites\",\n \"apiVersion\": \"2024-04-01\",\n \"name\": \"[variables('webAppName')]\",\n \"location\": \"[parameters('location')]\",\n \"properties\": {\n \"serverFarmId\": \"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]\",\n \"httpsOnly\": true,\n \"siteConfig\": {\n \"linuxFxVersion\": \"NODE|22-lts\",\n \"appSettings\": [\n { \"name\": \"WEBSITE_RUN_FROM_PACKAGE\", \"value\": \"[variables('packageUrl')]\" },\n { \"name\": \"VITE_LICENSE_TIER\", \"value\": \"enterprise\" },\n {\n \"name\": \"MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\",\n \"value\": \"[parameters('clientSecret')]\"\n }\n ],\n \"minTlsVersion\": \"1.2\",\n \"ftpsState\": \"Disabled\"\n }\n }\n}\n```\n\n### 3. EasyAuth Configuration (authsettingsV2)\n\nApp Service Authentication configured for Azure AD, referencing the customer-provided App Registration:\n\n```json\n{\n \"type\": \"Microsoft.Web/sites/config\",\n \"apiVersion\": \"2024-04-01\",\n \"name\": \"[concat(variables('webAppName'), '/authsettingsV2')]\",\n \"properties\": {\n \"platform\": { \"enabled\": true },\n \"globalValidation\": {\n \"requireAuthentication\": true,\n \"unauthenticatedClientAction\": \"RedirectToLoginPage\",\n \"redirectToProvider\": \"azureactivedirectory\",\n \"excludedPaths\": [\"/health\"]\n },\n \"identityProviders\": {\n \"azureActiveDirectory\": {\n \"enabled\": true,\n \"registration\": {\n \"openIdIssuer\": \"[concat('https://login.microsoftonline.com/', subscription().tenantId, '/v2.0')]\",\n \"clientId\": \"[parameters('clientId')]\",\n \"clientSecretSettingName\": \"MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\"\n },\n \"login\": {\n \"loginParameters\": [\"scope=openid profile email User.Read Files.ReadWrite\"]\n // Actual template uses conditional: Standard = \"User.Read\" only,\n // Team = \"User.Read Files.ReadWrite\"\n }\n }\n },\n \"login\": {\n \"tokenStore\": { \"enabled\": true }\n }\n }\n}\n```\n\nKey configuration:\n\n- **Token store enabled**: tokens available at `/.auth/me` for Graph API calls\n- **Login parameters**: conditional by plan — Standard requests `User.Read` only; Team requests `User.Read` + `Files.ReadWrite` for OneDrive access\n- **Redirect to login**: unauthenticated users are automatically redirected to Azure AD sign-in\n\n---\n\n## Outputs\n\n```json\n{\n \"outputs\": {\n \"appUrl\": {\n \"type\": \"string\",\n \"value\": \"[concat('https://', reference(resourceId('Microsoft.Web/sites', variables('webAppName'))).defaultHostName)]\"\n }\n }\n}\n```\n\n---\n\n## createUiDefinition.json\n\nThe `createUiDefinition.json` defines the Azure portal wizard shown to customers during deployment:\n\n### Basics Step\n\nThe customer provides an app name and selects a region.\n\n### Plan Selection Step\n\nThe customer selects their VariScout plan:\n\n- **Standard (€99/month)** — Full analysis, local file storage\n- **Team (€299/month)** — Teams, OneDrive, SharePoint, mobile, photos\n\nThe selected `variscoutPlan` parameter is passed to the ARM template, which conditionally provisions Team plan resources (Function App, Storage Account) and adjusts EasyAuth login scopes.\n\n### Authentication Step\n\nThe customer provides their App Registration credentials:\n\n- **InfoBox** with step-by-step instructions for creating an App Registration\n- **Client ID** text box with GUID validation\n- **Client Secret** password box (hidden input, no confirmation)\n\nThe wizard outputs `clientId` and `clientSecret` to the ARM template parameters.\n\n---\n\n## Deployment Methods\n\n### Azure Marketplace (Primary)\n\n1. Customer creates an App Registration (see [Pre-Deployment](#pre-deployment-create-app-registration))\n2. Customer finds VariScout on Azure Marketplace\n3. Clicks \"Create\"\n4. Enters app name, selects region\n5. Enters App Registration Client ID and Client Secret\n6. ARM template deploys automatically to managed resource group\n\n### Azure CLI (Development/Testing)\n\n```bash\n# Create resource group\naz group create --name rg-variscout --location westeurope\n\n# Deploy template (will prompt for clientId and clientSecret)\naz deployment group create \\\n --resource-group rg-variscout \\\n --template-file infra/mainTemplate.json \\\n --parameters clientId=\u003Cyour-client-id> clientSecret=\u003Cyour-client-secret>\n\n# Get outputs\naz deployment group show \\\n --resource-group rg-variscout \\\n --name mainTemplate \\\n --query properties.outputs\n```\n\n---\n\n## Post-Deployment\n\nAfter deployment, EasyAuth is fully configured:\n\n- Users visit the app URL and are redirected to Azure AD sign-in\n- Consent for `User.Read` (Standard) or `User.Read` + `Files.ReadWrite` (Team) is requested on first login\n- Tokens are stored in the EasyAuth token store and accessible via `/.auth/me`\n\n### Verify Redirect URI\n\nAfter deployment, confirm the App Registration redirect URI matches the deployed App Service URL:\n\n```\nhttps://\u003Cdeployed-app-name>.azurewebsites.net/.auth/login/aad/callback\n```\n\nIf the app name was auto-generated (e.g., `variscout-abc123`), update the App Registration redirect URI to match.\n\n### Custom Domain (Optional)\n\nAdd a custom domain to the App Service:\n\n```bash\naz webapp config hostname add \\\n --webapp-name variscout-xyz123 \\\n --resource-group rg-variscout \\\n --hostname variscout.contoso.com\n```\n\nWhen adding a custom domain, also add the new redirect URI to the App Registration.\n\nA custom domain also enables seamless Teams SSO (without it, users get a one-time login redirect because Microsoft blocks SSO on `*.azurewebsites.net`).\n\n### Teams Integration (Optional)\n\nThe app includes an Admin page (Admin > Teams Setup) that generates a Teams app package. See the in-app instructions for uploading to your Teams admin center.\n\n---\n\n## Troubleshooting\n\n### Deployment Fails\n\n| Error | Cause | Fix |\n| --------------------- | ------------------------ | --------------------------------------- |\n| `ResourceNotFound` | Invalid location | Use supported region |\n| `AuthorizationFailed` | Insufficient permissions | Requires Contributor role |\n| `QuotaExceeded` | App Service Plan limit | Delete unused plans or request increase |\n\n### Authentication Issues\n\nIf users can't sign in:\n\n1. Verify the App Registration redirect URI matches the App Service URL + `/.auth/login/aad/callback`\n2. Check the client secret hasn't expired\n3. Verify **ID tokens** is enabled under App Registration > Authentication > Implicit grant and hybrid flows\n4. Confirm the OpenID issuer uses `login.microsoftonline.com` (not `sts.windows.net`)\n5. Check the EasyAuth configuration in Azure Portal > App Service > Authentication\n6. Verify user is in the correct tenant\n7. Check `/.auth/me` returns a valid response (should return JSON array)\n\n---\n\n## Security Considerations\n\n### Principle of Least Privilege\n\nThe template requests only necessary permissions:\n\n**Standard plan:**\n\n| Permission | Scope | Purpose |\n| ----------- | --------- | ---------------- |\n| `User.Read` | Delegated | Get user profile |\n\n**Team plan adds:**\n\n| Permission | Scope | Purpose |\n| ----------------- | --------- | --------------------- |\n| `Files.ReadWrite` | Delegated | OneDrive project sync |\n\n### Secret Handling\n\n- The client secret is passed as a `secureString` parameter — ARM never logs it\n- The secret is stored as an App Service app setting (server-side, not in client code)\n- The secret is not included in template outputs\n- EasyAuth uses the token store (server-side) for access tokens\n\n### Customer Data Isolation\n\n- Each deployment is isolated to customer's tenant\n- No cross-tenant data access\n- No outbound connections to publisher systems\n- Publisher management is disabled (zero publisher access)\n\n---\n\n## Template Versioning\n\n| Version | Date | Changes |\n| ------- | ---------- | ---------------------------------------------------------------------------------------------- |\n| 1.0.0 | 2026-02-01 | Initial release (Solution Template) |\n| 2.0.0 | 2026-02-13 | Managed Application format, single plan |\n| 3.0.0 | 2026-02-16 | App Service + EasyAuth (replaces Static Web App + MSAL) |\n| 4.0.0 | 2026-02-16 | Customer-provided App Registration (removes deployment script) |\n| 5.0.0 | 2026-02-25 | API version → 2024-04-01, /health excluded from EasyAuth |\n| 5.1.0 | 2026-02-26 | Fix OpenID issuer (sts.windows.net → login.microsoftonline.com), document ID token requirement |\n| 6.0.0 | 2026-03-14 | Plan selector (Standard/Team), resource tags, conditional Function App + Storage for Team plan |\n\n---\n\n## See Also\n\n- [How It Works](how-it-works.md) — end-to-end architecture guide\n- [Azure Marketplace Guide](marketplace.md)\n- [Pricing](pricing-tiers.md)\n- [Authentication](authentication.md)\n- [Azure ARM Template Reference](https://docs.microsoft.com/azure/azure-resource-manager/templates/)", + "src/content/docs/08-products/azure/arm-template.md", + "5271d933450422fd", + { "html": 11352, "metadata": 11353 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"arm-template-documentation\">ARM Template Documentation\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#arm-template-documentation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ARM Template Documentation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Azure Resource Manager (ARM) template for VariScout Managed Application deployment.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The ARM template deploys VariScout to a customer’s Azure subscription as a Managed Application with:\u003C/p>\n\u003Cul>\n\u003Cli>Azure App Service (hosting via \u003Ccode dir=\"auto\">WEBSITE_RUN_FROM_PACKAGE\u003C/code>)\u003C/li>\n\u003Cli>App Service Authentication (EasyAuth) with Azure AD\u003C/li>\n\u003Cli>Configuration settings (all features enabled)\u003C/li>\n\u003C/ul>\n\u003Cp>The customer provides their own App Registration (created before deployment) so that VariScout can authenticate users and access OneDrive via Graph API (Team plan).\u003C/p>\n\u003Cp>\u003Cstrong>No backend resources\u003C/strong> - the app runs entirely in the browser. The App Service serves the static build as a zip package.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"managed-application-package\">Managed Application Package\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#managed-application-package\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Managed Application Package”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The template is packaged as a \u003Ccode dir=\"auto\">.zip\u003C/code> file for Partner Center:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">variscout-managed-app.zip\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── mainTemplate.json # ARM template (this document)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── createUiDefinition.json # Azure portal deployment wizard\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"variscout-managed-app.zip├── mainTemplate.json # ARM template (this document)└── createUiDefinition.json # Azure portal deployment wizard\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pre-deployment-create-app-registration\">Pre-Deployment: Create App Registration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pre-deployment-create-app-registration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pre-Deployment: Create App Registration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Before deploying VariScout, the customer must create an App Registration in Azure AD. This is required because Managed Applications cannot create App Registrations in the customer’s tenant.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"step-by-step\">Step-by-Step\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#step-by-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Step-by-Step”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Go to \u003Cstrong>Azure Portal > Azure Active Directory > App registrations > New registration\u003C/strong>\u003C/li>\n\u003Cli>Set \u003Cstrong>Name\u003C/strong> to something like \u003Ccode dir=\"auto\">VariScout\u003C/code>\u003C/li>\n\u003Cli>Set \u003Cstrong>Supported account types\u003C/strong> to “Accounts in this organizational directory only” (single tenant)\u003C/li>\n\u003Cli>Set \u003Cstrong>Redirect URI\u003C/strong> (Web platform) to:\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">https://<your-app-name>.azurewebsites.net/.auth/login/aad/callback\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"https://\u003Cyour-app-name>.azurewebsites.net/.auth/login/aad/callback\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\nReplace \u003Ccode dir=\"auto\"><your-app-name>\u003C/code> with the App Service name you’ll use during deployment.\u003C/li>\n\u003Cli>Click \u003Cstrong>Register\u003C/strong>\u003C/li>\n\u003Cli>Go to \u003Cstrong>Authentication\u003C/strong> > \u003Cstrong>Implicit grant and hybrid flows\u003C/strong> and check \u003Cstrong>ID tokens\u003C/strong>. This is required for EasyAuth’s hybrid authentication flow.\u003C/li>\n\u003Cli>Copy the \u003Cstrong>Application (client) ID\u003C/strong> from the Overview page — you’ll need this during deployment\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"add-api-permissions\">Add API Permissions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#add-api-permissions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Add API Permissions”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>Go to \u003Cstrong>API permissions > Add a permission > Microsoft Graph > Delegated permissions\u003C/strong>\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>Add permissions based on your plan:\u003C/p>\n\u003Cp>\u003Cstrong>Standard plan (€99/month):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">User.Read\u003C/code> — sign-in and read user profile\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Team plan (€299/month) — add all of the above, plus:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> — read and write user’s OneDrive files (for project sync)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> — channel SharePoint access (for shared projects)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code> — channel listing (for Teams integration)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\n\u003Cp>Click \u003Cstrong>Grant admin consent\u003C/strong> (optional for Standard; recommended for Team plan, otherwise users consent on first login)\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"create-client-secret\">Create Client Secret\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#create-client-secret\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Create Client Secret”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Go to \u003Cstrong>Certificates & secrets > Client secrets > New client secret\u003C/strong>\u003C/li>\n\u003Cli>Set a description (e.g., “VariScout EasyAuth”) and expiration (recommended: 24 months)\u003C/li>\n\u003Cli>Click \u003Cstrong>Add\u003C/strong>\u003C/li>\n\u003Cli>\u003Cstrong>Copy the secret value immediately\u003C/strong> — it won’t be shown again. You’ll need this during deployment.\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"parameters\">Parameters\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#parameters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Parameters”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"required-parameters\">Required Parameters\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#required-parameters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Required Parameters”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">clientId\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Application (client) ID from the App Registration\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">clientSecret\u003C/code>\u003C/td>\u003Ctd>secureString\u003C/td>\u003Ctd>Client secret value from the App Registration\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"optional-parameters\">Optional Parameters\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#optional-parameters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Optional Parameters”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">location\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Resource group location\u003C/td>\u003Ctd>Azure region for deployment\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">appName\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">variscout-{unique}\u003C/code>\u003C/td>\u003Ctd>Name for App Service (3-24)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">variscoutPlan\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">standard\u003C/code>\u003C/td>\u003Ctd>Plan: \u003Ccode dir=\"auto\">standard\u003C/code> (local files) or \u003Ccode dir=\"auto\">team\u003C/code> (+ OneDrive, Teams)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"resources\">Resources\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#resources\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Resources”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All resources are tagged with \u003Ccode dir=\"auto\">product: VariScout\u003C/code>, \u003Ccode dir=\"auto\">plan: <selected>\u003C/code>, and \u003Ccode dir=\"auto\">managedBy: AzureMarketplace\u003C/code> for cost tracking and governance.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-app-service-plan\">1. App Service Plan\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-app-service-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. App Service Plan”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Linux B1 plan for hosting the App Service:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"type\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Microsoft.Web/serverfarms\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"apiVersion\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">2024-04-01\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[variables('appServicePlanName')]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"location\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[parameters('location')]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"kind\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">linux\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"sku\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">B1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"tier\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Basic\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"properties\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"reserved\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{ "type": "Microsoft.Web/serverfarms", "apiVersion": "2024-04-01", "name": "[variables('appServicePlanName')]", "location": "[parameters('location')]", "kind": "linux", "sku": { "name": "B1", "tier": "Basic" }, "properties": { "reserved": true }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-app-service\">2. App Service\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-app-service\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. App Service”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Serves the VariScout build via \u003Ccode dir=\"auto\">WEBSITE_RUN_FROM_PACKAGE\u003C/code>. The client secret is stored as an app setting for EasyAuth to use:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"type\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Microsoft.Web/sites\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"apiVersion\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">2024-04-01\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[variables('webAppName')]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"location\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[parameters('location')]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"properties\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"serverFarmId\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"httpsOnly\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"siteConfig\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"linuxFxVersion\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">NODE|22-lts\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"appSettings\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">WEBSITE_RUN_FROM_PACKAGE\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"value\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[variables('packageUrl')]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">VITE_LICENSE_TIER\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"value\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">enterprise\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"value\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[parameters('clientSecret')]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"minTlsVersion\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">1.2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"ftpsState\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Disabled\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{ "type": "Microsoft.Web/sites", "apiVersion": "2024-04-01", "name": "[variables('webAppName')]", "location": "[parameters('location')]", "properties": { "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]", "httpsOnly": true, "siteConfig": { "linuxFxVersion": "NODE|22-lts", "appSettings": [ { "name": "WEBSITE_RUN_FROM_PACKAGE", "value": "[variables('packageUrl')]" }, { "name": "VITE_LICENSE_TIER", "value": "enterprise" }, { "name": "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET", "value": "[parameters('clientSecret')]" } ], "minTlsVersion": "1.2", "ftpsState": "Disabled" } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-easyauth-configuration-authsettingsv2\">3. EasyAuth Configuration (authsettingsV2)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-easyauth-configuration-authsettingsv2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. EasyAuth Configuration (authsettingsV2)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>App Service Authentication configured for Azure AD, referencing the customer-provided App Registration:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"type\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Microsoft.Web/sites/config\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"apiVersion\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">2024-04-01\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[concat(variables('webAppName'), '/authsettingsV2')]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"properties\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"platform\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: { \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"enabled\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"globalValidation\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"requireAuthentication\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"unauthenticatedClientAction\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">RedirectToLoginPage\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"redirectToProvider\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">azureactivedirectory\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"excludedPaths\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">/health\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"identityProviders\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"azureActiveDirectory\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"enabled\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"registration\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"openIdIssuer\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[concat('https://login.microsoftonline.com/', subscription().tenantId, '/v2.0')]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"clientId\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[parameters('clientId')]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"clientSecretSettingName\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"login\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"loginParameters\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">scope=openid profile email User.Read Files.ReadWrite\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Actual template uses conditional: Standard = \"User.Read\" only,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Team = \"User.Read Files.ReadWrite\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"login\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"tokenStore\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: { \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"enabled\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{ "type": "Microsoft.Web/sites/config", "apiVersion": "2024-04-01", "name": "[concat(variables('webAppName'), '/authsettingsV2')]", "properties": { "platform": { "enabled": true }, "globalValidation": { "requireAuthentication": true, "unauthenticatedClientAction": "RedirectToLoginPage", "redirectToProvider": "azureactivedirectory", "excludedPaths": ["/health"] }, "identityProviders": { "azureActiveDirectory": { "enabled": true, "registration": { "openIdIssuer": "[concat('https://login.microsoftonline.com/', subscription().tenantId, '/v2.0')]", "clientId": "[parameters('clientId')]", "clientSecretSettingName": "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET" }, "login": { "loginParameters": ["scope=openid profile email User.Read Files.ReadWrite"] // Actual template uses conditional: Standard = "User.Read" only, // Team = "User.Read Files.ReadWrite" } } }, "login": { "tokenStore": { "enabled": true } } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Key configuration:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Token store enabled\u003C/strong>: tokens available at \u003Ccode dir=\"auto\">/.auth/me\u003C/code> for Graph API calls\u003C/li>\n\u003Cli>\u003Cstrong>Login parameters\u003C/strong>: conditional by plan — Standard requests \u003Ccode dir=\"auto\">User.Read\u003C/code> only; Team requests \u003Ccode dir=\"auto\">User.Read\u003C/code> + \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> for OneDrive access\u003C/li>\n\u003Cli>\u003Cstrong>Redirect to login\u003C/strong>: unauthenticated users are automatically redirected to Azure AD sign-in\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"outputs\">Outputs\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#outputs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Outputs”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"outputs\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"appUrl\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"type\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"value\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[concat('https://', reference(resourceId('Microsoft.Web/sites', variables('webAppName'))).defaultHostName)]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{ "outputs": { "appUrl": { "type": "string", "value": "[concat('https://', reference(resourceId('Microsoft.Web/sites', variables('webAppName'))).defaultHostName)]" } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"createuidefinitionjson\">createUiDefinition.json\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#createuidefinitionjson\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “createUiDefinition.json”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">createUiDefinition.json\u003C/code> defines the Azure portal wizard shown to customers during deployment:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"basics-step\">Basics Step\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#basics-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Basics Step”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The customer provides an app name and selects a region.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"plan-selection-step\">Plan Selection Step\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#plan-selection-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Plan Selection Step”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The customer selects their VariScout plan:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Standard (€99/month)\u003C/strong> — Full analysis, local file storage\u003C/li>\n\u003Cli>\u003Cstrong>Team (€299/month)\u003C/strong> — Teams, OneDrive, SharePoint, mobile, photos\u003C/li>\n\u003C/ul>\n\u003Cp>The selected \u003Ccode dir=\"auto\">variscoutPlan\u003C/code> parameter is passed to the ARM template, which conditionally provisions Team plan resources (Function App, Storage Account) and adjusts EasyAuth login scopes.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"authentication-step\">Authentication Step\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#authentication-step\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Authentication Step”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The customer provides their App Registration credentials:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>InfoBox\u003C/strong> with step-by-step instructions for creating an App Registration\u003C/li>\n\u003Cli>\u003Cstrong>Client ID\u003C/strong> text box with GUID validation\u003C/li>\n\u003Cli>\u003Cstrong>Client Secret\u003C/strong> password box (hidden input, no confirmation)\u003C/li>\n\u003C/ul>\n\u003Cp>The wizard outputs \u003Ccode dir=\"auto\">clientId\u003C/code> and \u003Ccode dir=\"auto\">clientSecret\u003C/code> to the ARM template parameters.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"deployment-methods\">Deployment Methods\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#deployment-methods\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment Methods”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-marketplace-primary\">Azure Marketplace (Primary)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-marketplace-primary\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Marketplace (Primary)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Customer creates an App Registration (see \u003Ca href=\"#pre-deployment-create-app-registration\">Pre-Deployment\u003C/a>)\u003C/li>\n\u003Cli>Customer finds VariScout on Azure Marketplace\u003C/li>\n\u003Cli>Clicks “Create”\u003C/li>\n\u003Cli>Enters app name, selects region\u003C/li>\n\u003Cli>Enters App Registration Client ID and Client Secret\u003C/li>\n\u003Cli>ARM template deploys automatically to managed resource group\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"azure-cli-developmenttesting\">Azure CLI (Development/Testing)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#azure-cli-developmenttesting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure CLI (Development/Testing)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Create resource group\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--location\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">westeurope\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Deploy template (will prompt for clientId and clientSecret)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deployment\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--template-file\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">infra/mainTemplate.json\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--parameters\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">clientId=<your-client-id>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">clientSecret=<your-client-secret>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Get outputs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deployment\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">show\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">mainTemplate\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--query\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">properties.outputs\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az group create --name rg-variscout --location westeuropeaz deployment group create \\ --resource-group rg-variscout \\ --template-file infra/mainTemplate.json \\ --parameters clientId=\u003Cyour-client-id> clientSecret=\u003Cyour-client-secret>az deployment group show \\ --resource-group rg-variscout \\ --name mainTemplate \\ --query properties.outputs\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"post-deployment\">Post-Deployment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#post-deployment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Post-Deployment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After deployment, EasyAuth is fully configured:\u003C/p>\n\u003Cul>\n\u003Cli>Users visit the app URL and are redirected to Azure AD sign-in\u003C/li>\n\u003Cli>Consent for \u003Ccode dir=\"auto\">User.Read\u003C/code> (Standard) or \u003Ccode dir=\"auto\">User.Read\u003C/code> + \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code> (Team) is requested on first login\u003C/li>\n\u003Cli>Tokens are stored in the EasyAuth token store and accessible via \u003Ccode dir=\"auto\">/.auth/me\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"verify-redirect-uri\">Verify Redirect URI\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#verify-redirect-uri\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Verify Redirect URI”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After deployment, confirm the App Registration redirect URI matches the deployed App Service URL:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">https://<deployed-app-name>.azurewebsites.net/.auth/login/aad/callback\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"https://\u003Cdeployed-app-name>.azurewebsites.net/.auth/login/aad/callback\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>If the app name was auto-generated (e.g., \u003Ccode dir=\"auto\">variscout-abc123\u003C/code>), update the App Registration redirect URI to match.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"custom-domain-optional\">Custom Domain (Optional)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#custom-domain-optional\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Custom Domain (Optional)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Add a custom domain to the App Service:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">webapp\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">config\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">hostname\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">add\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--webapp-name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-xyz123\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--hostname\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout.contoso.com\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az webapp config hostname add \\ --webapp-name variscout-xyz123 \\ --resource-group rg-variscout \\ --hostname variscout.contoso.com\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>When adding a custom domain, also add the new redirect URI to the App Registration.\u003C/p>\n\u003Cp>A custom domain also enables seamless Teams SSO (without it, users get a one-time login redirect because Microsoft blocks SSO on \u003Ccode dir=\"auto\">*.azurewebsites.net\u003C/code>).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"teams-integration-optional\">Teams Integration (Optional)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#teams-integration-optional\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teams Integration (Optional)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The app includes an Admin page (Admin > Teams Setup) that generates a Teams app package. See the in-app instructions for uploading to your Teams admin center.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"troubleshooting\">Troubleshooting\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#troubleshooting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Troubleshooting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deployment-fails\">Deployment Fails\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deployment-fails\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment Fails”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Error\u003C/th>\u003Cth>Cause\u003C/th>\u003Cth>Fix\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ResourceNotFound\u003C/code>\u003C/td>\u003Ctd>Invalid location\u003C/td>\u003Ctd>Use supported region\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">AuthorizationFailed\u003C/code>\u003C/td>\u003Ctd>Insufficient permissions\u003C/td>\u003Ctd>Requires Contributor role\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">QuotaExceeded\u003C/code>\u003C/td>\u003Ctd>App Service Plan limit\u003C/td>\u003Ctd>Delete unused plans or request increase\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"authentication-issues\">Authentication Issues\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#authentication-issues\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Authentication Issues”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>If users can’t sign in:\u003C/p>\n\u003Col>\n\u003Cli>Verify the App Registration redirect URI matches the App Service URL + \u003Ccode dir=\"auto\">/.auth/login/aad/callback\u003C/code>\u003C/li>\n\u003Cli>Check the client secret hasn’t expired\u003C/li>\n\u003Cli>Verify \u003Cstrong>ID tokens\u003C/strong> is enabled under App Registration > Authentication > Implicit grant and hybrid flows\u003C/li>\n\u003Cli>Confirm the OpenID issuer uses \u003Ccode dir=\"auto\">login.microsoftonline.com\u003C/code> (not \u003Ccode dir=\"auto\">sts.windows.net\u003C/code>)\u003C/li>\n\u003Cli>Check the EasyAuth configuration in Azure Portal > App Service > Authentication\u003C/li>\n\u003Cli>Verify user is in the correct tenant\u003C/li>\n\u003Cli>Check \u003Ccode dir=\"auto\">/.auth/me\u003C/code> returns a valid response (should return JSON array)\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"security-considerations\">Security Considerations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#security-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"principle-of-least-privilege\">Principle of Least Privilege\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#principle-of-least-privilege\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Principle of Least Privilege”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The template requests only necessary permissions:\u003C/p>\n\u003Cp>\u003Cstrong>Standard plan:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Permission\u003C/th>\u003Cth>Scope\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">User.Read\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Get user profile\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Team plan adds:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Permission\u003C/th>\u003Cth>Scope\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>OneDrive project sync\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"secret-handling\">Secret Handling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#secret-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Secret Handling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>The client secret is passed as a \u003Ccode dir=\"auto\">secureString\u003C/code> parameter — ARM never logs it\u003C/li>\n\u003Cli>The secret is stored as an App Service app setting (server-side, not in client code)\u003C/li>\n\u003Cli>The secret is not included in template outputs\u003C/li>\n\u003Cli>EasyAuth uses the token store (server-side) for access tokens\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"customer-data-isolation\">Customer Data Isolation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#customer-data-isolation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Customer Data Isolation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Each deployment is isolated to customer’s tenant\u003C/li>\n\u003Cli>No cross-tenant data access\u003C/li>\n\u003Cli>No outbound connections to publisher systems\u003C/li>\n\u003Cli>Publisher management is disabled (zero publisher access)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"template-versioning\">Template Versioning\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#template-versioning\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Template Versioning”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Version\u003C/th>\u003Cth>Date\u003C/th>\u003Cth>Changes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>1.0.0\u003C/td>\u003Ctd>2026-02-01\u003C/td>\u003Ctd>Initial release (Solution Template)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>2.0.0\u003C/td>\u003Ctd>2026-02-13\u003C/td>\u003Ctd>Managed Application format, single plan\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>3.0.0\u003C/td>\u003Ctd>2026-02-16\u003C/td>\u003Ctd>App Service + EasyAuth (replaces Static Web App + MSAL)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>4.0.0\u003C/td>\u003Ctd>2026-02-16\u003C/td>\u003Ctd>Customer-provided App Registration (removes deployment script)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5.0.0\u003C/td>\u003Ctd>2026-02-25\u003C/td>\u003Ctd>API version → 2024-04-01, /health excluded from EasyAuth\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>5.1.0\u003C/td>\u003Ctd>2026-02-26\u003C/td>\u003Ctd>Fix OpenID issuer (sts.windows.net → login.microsoftonline.com), document ID token requirement\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>6.0.0\u003C/td>\u003Ctd>2026-03-14\u003C/td>\u003Ctd>Plan selector (Standard/Team), resource tags, conditional Function App + Storage for Team plan\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"how-it-works.md\">How It Works\u003C/a> — end-to-end architecture guide\u003C/li>\n\u003Cli>\u003Ca href=\"marketplace.md\">Azure Marketplace Guide\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"pricing-tiers.md\">Pricing\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"authentication.md\">Authentication\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://docs.microsoft.com/azure/azure-resource-manager/templates/\">Azure ARM Template Reference\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 11354, + "localImagePaths": 11445, + "remoteImagePaths": 11446, + "frontmatter": 11447, + "imagePaths": 11448 + }, + [ + 11355, 11357, 11358, 11359, 11362, 11363, 11366, 11369, 11372, 11375, 11378, 11379, 11382, + 11385, 11388, 11391, 11394, 11397, 11400, 11403, 11406, 11409, 11412, 11415, 11418, 11421, + 11424, 11425, 11428, 11431, 11432, 11435, 11438, 11441, 11444 + ], + { "depth": 30, "slug": 11356, "text": 11344 }, + "arm-template-documentation", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 79, "slug": 2364, "text": 2365 }, + { "depth": 33, "slug": 11360, "text": 11361 }, + "pre-deployment-create-app-registration", + "Pre-Deployment: Create App Registration", + { "depth": 79, "slug": 4137, "text": 4138 }, + { "depth": 79, "slug": 11364, "text": 11365 }, + "add-api-permissions", + "Add API Permissions", + { "depth": 79, "slug": 11367, "text": 11368 }, + "create-client-secret", + "Create Client Secret", + { "depth": 33, "slug": 11370, "text": 11371 }, + "parameters", + "Parameters", + { "depth": 79, "slug": 11373, "text": 11374 }, + "required-parameters", + "Required Parameters", + { "depth": 79, "slug": 11376, "text": 11377 }, + "optional-parameters", + "Optional Parameters", + { "depth": 33, "slug": 11150, "text": 11151 }, + { "depth": 79, "slug": 11380, "text": 11381 }, + "1-app-service-plan", + "1. App Service Plan", + { "depth": 79, "slug": 11383, "text": 11384 }, + "2-app-service", + "2. App Service", + { "depth": 79, "slug": 11386, "text": 11387 }, + "3-easyauth-configuration-authsettingsv2", + "3. EasyAuth Configuration (authsettingsV2)", + { "depth": 33, "slug": 11389, "text": 11390 }, + "outputs", + "Outputs", + { "depth": 33, "slug": 11392, "text": 11393 }, + "createuidefinitionjson", + "createUiDefinition.json", + { "depth": 79, "slug": 11395, "text": 11396 }, + "basics-step", + "Basics Step", + { "depth": 79, "slug": 11398, "text": 11399 }, + "plan-selection-step", + "Plan Selection Step", + { "depth": 79, "slug": 11401, "text": 11402 }, + "authentication-step", + "Authentication Step", + { "depth": 33, "slug": 11404, "text": 11405 }, + "deployment-methods", + "Deployment Methods", + { "depth": 79, "slug": 11407, "text": 11408 }, + "azure-marketplace-primary", + "Azure Marketplace (Primary)", + { "depth": 79, "slug": 11410, "text": 11411 }, + "azure-cli-developmenttesting", + "Azure CLI (Development/Testing)", + { "depth": 33, "slug": 11413, "text": 11414 }, + "post-deployment", + "Post-Deployment", + { "depth": 79, "slug": 11416, "text": 11417 }, + "verify-redirect-uri", + "Verify Redirect URI", + { "depth": 79, "slug": 11419, "text": 11420 }, + "custom-domain-optional", + "Custom Domain (Optional)", + { "depth": 79, "slug": 11422, "text": 11423 }, + "teams-integration-optional", + "Teams Integration (Optional)", + { "depth": 33, "slug": 3221, "text": 3222 }, + { "depth": 79, "slug": 11426, "text": 11427 }, + "deployment-fails", + "Deployment Fails", + { "depth": 79, "slug": 11429, "text": 11430 }, + "authentication-issues", + "Authentication Issues", + { "depth": 33, "slug": 2930, "text": 2931 }, + { "depth": 79, "slug": 11433, "text": 11434 }, + "principle-of-least-privilege", + "Principle of Least Privilege", + { "depth": 79, "slug": 11436, "text": 11437 }, + "secret-handling", + "Secret Handling", + { "depth": 79, "slug": 11439, "text": 11440 }, + "customer-data-isolation", + "Customer Data Isolation", + { "depth": 33, "slug": 11442, "text": 11443 }, + "template-versioning", + "Template Versioning", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11344 }, + [], + "08-products/azure/authentication", + { + "id": 11449, + "data": 11451, + "body": 11456, + "filePath": 11457, + "digest": 11458, + "rendered": 11459 + }, + { + "title": 11452, + "editUrl": 16, + "head": 11453, + "template": 18, + "sidebar": 11454, + "pagefind": 16, + "draft": 20 + }, + "Authentication (EasyAuth)", + [], + { "hidden": 20, "attrs": 11455 }, + {}, + "# Authentication (EasyAuth)\n\nApp Service Authentication (EasyAuth) integration for Azure AD SSO.\n\n---\n\n## Overview\n\nThe Azure app uses **EasyAuth** (App Service Authentication) — a platform-level auth feature that handles Azure AD login without any client-side auth libraries:\n\n- Zero auth code in the application\n- Platform-managed token refresh\n- Built-in token store at `/.auth/me`\n- Automatic redirect to Azure AD login\n\nThis replaces the previous MSAL library approach, eliminating `@azure/msal-browser` and `@azure/msal-react` dependencies.\n\n---\n\n## How It Works\n\nEasyAuth runs as middleware in the App Service platform. The app never sees unauthenticated requests — Azure handles the login flow before the request reaches the application code.\n\n```\nUSER APP SERVICE (EasyAuth) ENTRA ID\n │ │ │\n │── Visit app URL ────────────▶│ │\n │ │── Not authenticated ───▶│\n │ │ Redirect to login │\n │ │ │\n │◀───────────── User authenticates ─────────────────────▶│\n │ │ │\n │ │◀── Session cookie ──────│\n │ │ + tokens in store │\n │◀── Serve app ────────────────│ │\n```\n\n---\n\n## Auth Endpoints\n\nEasyAuth provides built-in endpoints on every App Service:\n\n| Endpoint | Purpose |\n| ------------------ | ------------------------------------- |\n| `/.auth/login/aad` | Redirect to Azure AD sign-in |\n| `/.auth/logout` | Sign out and clear session |\n| `/.auth/me` | Get current user info + access tokens |\n| `/.auth/refresh` | Refresh the session token |\n\n### `/.auth/me` Response Structure\n\n```json\n[\n {\n \"provider_name\": \"aad\",\n \"user_id\": \"user@contoso.com\",\n \"user_claims\": [\n { \"typ\": \"name\", \"val\": \"Jane Smith\" },\n {\n \"typ\": \"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress\",\n \"val\": \"jane@contoso.com\"\n },\n { \"typ\": \"preferred_username\", \"val\": \"jane@contoso.com\" }\n ],\n \"access_token\": \"eyJ0eXAi...\",\n \"expires_on\": \"2026-02-16T12:00:00.0000000Z\"\n }\n]\n```\n\n---\n\n## Client-Side Helper\n\nThe `easyAuth.ts` module provides typed helpers for accessing EasyAuth:\n\n```typescript\n// auth/easyAuth.ts\nimport { getEasyAuthUser, getAccessToken, login, logout } from './auth/easyAuth';\n\n// Get the current user (name, email, userId)\nconst user = await getEasyAuthUser();\n\n// Get an access token for Graph API calls\nconst token = await getAccessToken();\n\n// Redirect to Azure AD login\nlogin();\n\n// Sign out\nlogout();\n```\n\n### Local Development\n\nEasyAuth only works on deployed App Services. For local development, the helper detects `localhost` and returns mock data:\n\n- `getEasyAuthUser()` returns a mock \"Local Developer\" user\n- `getAccessToken()` throws an error (Graph API not available locally)\n- `login()` / `logout()` reload the page\n\n---\n\n## Error Handling\n\n### AuthError Class\n\nTyped authentication errors with machine-readable codes:\n\n| Code | Meaning |\n| ------------------- | --------------------------------------- |\n| `not_authenticated` | No auth session found |\n| `no_provider` | `/.auth/me` returned empty array |\n| `no_token` | Provider entry has no `access_token` |\n| `refresh_failed` | `/.auth/refresh` returned non-OK status |\n| `local_dev` | Graph API unavailable on localhost |\n\nSource: `apps/azure/src/auth/easyAuth.ts`\n\n### Proactive Token Refresh\n\n`getAccessToken()` checks `expires_on` from the `/.auth/me` response. If the token expires within **5 minutes**, it calls `/.auth/refresh` before returning the token. If refresh fails but the token hasn't actually expired, the existing token is returned as a fallback.\n\nFlow:\n\n1. Fetch `/.auth/me` → extract `access_token` + `expires_on`\n2. If expires within 5 min → call `/.auth/refresh`\n - Success → re-fetch `/.auth/me` → return new token\n - Failure → return existing token (still valid)\n3. If not near expiry → return token directly\n\n### Periodic Background Refresh\n\n`startPeriodicRefresh()` runs a 45-minute interval that calls `/.auth/refresh` in the background. This prevents session expiry during long analysis sessions (EasyAuth tokens typically expire after 1 hour).\n\n- Started on app mount, stopped on unmount\n- Safe to call multiple times — clears any existing interval first\n- Failures are logged but do not interrupt the user session\n- Companion: `stopPeriodicRefresh()` for cleanup\n\nSource: `apps/azure/src/auth/easyAuth.ts`\n\n---\n\n## Graph API Token Usage\n\nThe `/.auth/me` response includes an `access_token` that can be used for Microsoft Graph API calls:\n\n```typescript\nconst token = await getAccessToken();\n\nconst response = await fetch('https://graph.microsoft.com/v1.0/me/drive/root:/VariScout/Projects', {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n});\n```\n\nThe token is automatically scoped to the permissions configured in the EasyAuth login parameters. Standard plan: `User.Read`. Team plan adds: `Files.ReadWrite`, `Files.ReadWrite.All`, `Channel.ReadBasic.All`.\n\n---\n\n## ARM Template Configuration\n\nEasyAuth is configured in the ARM template via `authsettingsV2`:\n\n```json\n{\n \"type\": \"Microsoft.Web/sites/config\",\n \"name\": \"[concat(webAppName, '/authsettingsV2')]\",\n \"properties\": {\n \"platform\": { \"enabled\": true },\n \"globalValidation\": {\n \"requireAuthentication\": true,\n \"unauthenticatedClientAction\": \"RedirectToLoginPage\",\n \"redirectToProvider\": \"azureactivedirectory\"\n },\n \"identityProviders\": {\n \"azureActiveDirectory\": {\n \"enabled\": true,\n \"registration\": {\n \"clientId\": \"\u003Capp-registration-client-id>\",\n \"clientSecretSettingName\": \"MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\"\n },\n \"login\": {\n \"loginParameters\": [\"scope=openid profile email User.Read Files.ReadWrite\"]\n }\n }\n },\n \"login\": {\n \"tokenStore\": { \"enabled\": true }\n }\n }\n}\n```\n\n> **Note:** The `loginParameters` scope shown above is for the **Team plan**. The actual ARM template uses a conditional expression — Standard plan requests `User.Read` only, Team plan requests the full scope including `Files.ReadWrite`.\n\nSee [ARM Template](arm-template.md) for the complete deployment configuration.\n\n---\n\n## Required Permissions\n\n**Standard plan (€99/month):**\n\n| Permission | Type | Admin Consent | Purpose |\n| ---------- | --------- | ------------- | ---------------- |\n| User.Read | Delegated | No | Get user profile |\n\nNo admin consent required — users grant consent on first login.\n\n**Team plan (€299/month) additional scopes:**\n\n| Permission | Type | Admin Consent | Purpose |\n| --------------------- | --------- | ------------- | ------------------------- |\n| Files.ReadWrite | Delegated | No | OneDrive analysis sync |\n| Files.ReadWrite.All | Delegated | Yes | Channel SharePoint access |\n| Channel.ReadBasic.All | Delegated | Yes | Channel listing |\n\n---\n\n## Teams SSO (Team Plan)\n\nWhen running inside Microsoft Teams, the app uses the Teams SDK for single sign-on:\n\n### Client-side token acquisition\n\n1. `@microsoft/teams-js` `authentication.getAuthToken()` acquires an Azure AD token scoped to the app's client ID\n2. This token identifies the user but cannot call Graph API directly\n3. For Graph API access, the app falls back to EasyAuth redirect (standard flow)\n\n### On-Behalf-Of (OBO) Function\n\nWhen running inside Teams, the app exchanges the Teams SSO token for a Graph API token via an Azure Function:\n\n1. `getTeamsSsoToken()` acquires an Azure AD token scoped to the app's client ID\n2. The token is POST-ed to the OBO function (`/api/token-exchange`)\n3. The function validates the token's audience matches `CLIENT_ID`, then exchanges it via MSAL OBO flow\n4. The Graph API token is returned and cached client-side (5 min margin)\n5. If OBO fails, the app falls back to EasyAuth redirect (graceful degradation)\n\nThis enables **silent SSO** — no redirect flash when saving to OneDrive or uploading photos from within Teams.\n\n**Security controls on the OBO function:**\n\n| Control | Detail |\n| ------------------- | ------------------------------------------------------------------------------------------------- |\n| Audience validation | JWT `aud` must match `CLIENT_ID` — prevents exchanging tokens issued for other apps |\n| Scope allowlist | Only `Files.ReadWrite.All`, `ChannelMessage.Send`, `People.Read` — other scopes rejected with 400 |\n| CORS | Configurable `ALLOWED_ORIGIN` env var (defaults to `*` for dev); `OPTIONS` preflight supported |\n| Function-key auth | Optional `FUNCTION_KEY` env var — if set, requests must include `X-Functions-Key` header |\n| Generic errors | Catch block returns `\"Token exchange failed\"` — no MSAL internals leaked to clients |\n| Method restriction | Only `POST` accepted; other methods return 405 |\n\n- Function code: `infra/functions/token-exchange/index.js`\n- Client module: `apps/azure/src/auth/graphToken.ts`\n- Used by: `storage.ts` (OneDrive sync) and `photoUpload.ts` (photo uploads)\n- See [ADR-016](../../07-decisions/adr-016-teams-integration.md) Phase 6\n\n### Teams SSO in the manifest\n\n- `webApplicationInfo` in the Teams manifest enables SSO\n- Requires the App Registration's Client ID\n- Custom domains recommended (SSO blocked on `*.azurewebsites.net`)\n\n### Code reference\n\n- Teams SDK init: `apps/azure/src/teams/teamsContext.ts`\n- SSO token: `getTeamsSsoToken()` in the same module\n- Tab configuration: `apps/azure/src/teams/TeamsTabConfig.tsx`\n\n---\n\n## See Also\n\n- [OneDrive Sync](onedrive-sync.md)\n- [ARM Template](arm-template.md)\n- [App Service Authentication Docs](https://learn.microsoft.com/en-us/azure/app-service/overview-authentication-authorization)", + "src/content/docs/08-products/azure/authentication.md", + "e01e2a03eda66234", + { "html": 11460, "metadata": 11461 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"authentication-easyauth\">Authentication (EasyAuth)\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#authentication-easyauth\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Authentication (EasyAuth)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>App Service Authentication (EasyAuth) integration for Azure AD SSO.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure app uses \u003Cstrong>EasyAuth\u003C/strong> (App Service Authentication) — a platform-level auth feature that handles Azure AD login without any client-side auth libraries:\u003C/p>\n\u003Cul>\n\u003Cli>Zero auth code in the application\u003C/li>\n\u003Cli>Platform-managed token refresh\u003C/li>\n\u003Cli>Built-in token store at \u003Ccode dir=\"auto\">/.auth/me\u003C/code>\u003C/li>\n\u003Cli>Automatic redirect to Azure AD login\u003C/li>\n\u003C/ul>\n\u003Cp>This replaces the previous MSAL library approach, eliminating \u003Ccode dir=\"auto\">@azure/msal-browser\u003C/code> and \u003Ccode dir=\"auto\">@azure/msal-react\u003C/code> dependencies.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-it-works\">How It Works\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-it-works\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How It Works”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>EasyAuth runs as middleware in the App Service platform. The app never sees unauthenticated requests — Azure handles the login flow before the request reaches the application code.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USER APP SERVICE (EasyAuth) ENTRA ID\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│── Visit app URL ────────────▶│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │── Not authenticated ───▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Redirect to login │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀───────────── User authenticates ─────────────────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │◀── Session cookie ──────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ + tokens in store │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀── Serve app ────────────────│ │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"USER APP SERVICE (EasyAuth) ENTRA ID │ │ │ │── Visit app URL ────────────▶│ │ │ │── Not authenticated ───▶│ │ │ Redirect to login │ │ │ │ │◀───────────── User authenticates ─────────────────────▶│ │ │ │ │ │◀── Session cookie ──────│ │ │ + tokens in store │ │◀── Serve app ────────────────│ │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"auth-endpoints\">Auth Endpoints\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#auth-endpoints\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Auth Endpoints”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>EasyAuth provides built-in endpoints on every App Service:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Endpoint\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">/.auth/login/aad\u003C/code>\u003C/td>\u003Ctd>Redirect to Azure AD sign-in\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">/.auth/logout\u003C/code>\u003C/td>\u003Ctd>Sign out and clear session\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">/.auth/me\u003C/code>\u003C/td>\u003Ctd>Get current user info + access tokens\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">/.auth/refresh\u003C/code>\u003C/td>\u003Ctd>Refresh the session token\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"authme-response-structure\">\u003Ccode dir=\"auto\">/.auth/me\u003C/code> Response Structure\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#authme-response-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “/.auth/me Response Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"provider_name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">aad\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"user_id\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">user@contoso.com\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"user_claims\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: [\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"typ\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">name\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"val\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Jane Smith\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"typ\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"val\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">jane@contoso.com\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{ \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"typ\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">preferred_username\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"val\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">jane@contoso.com\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">],\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"access_token\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">eyJ0eXAi...\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"expires_on\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">2026-02-16T12:00:00.0000000Z\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[ { "provider_name": "aad", "user_id": "user@contoso.com", "user_claims": [ { "typ": "name", "val": "Jane Smith" }, { "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "val": "jane@contoso.com" }, { "typ": "preferred_username", "val": "jane@contoso.com" } ], "access_token": "eyJ0eXAi...", "expires_on": "2026-02-16T12:00:00.0000000Z" }]\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"client-side-helper\">Client-Side Helper\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#client-side-helper\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Client-Side Helper”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">easyAuth.ts\u003C/code> module provides typed helpers for accessing EasyAuth:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame has-title not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">auth/easyAuth.ts\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { getEasyAuthUser, getAccessToken, login, logout } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">./auth/easyAuth\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Get the current user (name, email, userId)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">user\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getEasyAuthUser\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Get an access token for Graph API calls\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">token\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getAccessToken\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Redirect to Azure AD login\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">login\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Sign out\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">logout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { getEasyAuthUser, getAccessToken, login, logout } from './auth/easyAuth';// Get the current user (name, email, userId)const user = await getEasyAuthUser();// Get an access token for Graph API callsconst token = await getAccessToken();// Redirect to Azure AD loginlogin();// Sign outlogout();\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"local-development\">Local Development\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#local-development\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Local Development”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>EasyAuth only works on deployed App Services. For local development, the helper detects \u003Ccode dir=\"auto\">localhost\u003C/code> and returns mock data:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">getEasyAuthUser()\u003C/code> returns a mock “Local Developer” user\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">getAccessToken()\u003C/code> throws an error (Graph API not available locally)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">login()\u003C/code> / \u003Ccode dir=\"auto\">logout()\u003C/code> reload the page\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"error-handling\">Error Handling\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#error-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Error Handling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"autherror-class\">AuthError Class\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#autherror-class\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “AuthError Class”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Typed authentication errors with machine-readable codes:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Code\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">not_authenticated\u003C/code>\u003C/td>\u003Ctd>No auth session found\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">no_provider\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/.auth/me\u003C/code> returned empty array\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">no_token\u003C/code>\u003C/td>\u003Ctd>Provider entry has no \u003Ccode dir=\"auto\">access_token\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">refresh_failed\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/.auth/refresh\u003C/code> returned non-OK status\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">local_dev\u003C/code>\u003C/td>\u003Ctd>Graph API unavailable on localhost\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Source: \u003Ccode dir=\"auto\">apps/azure/src/auth/easyAuth.ts\u003C/code>\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"proactive-token-refresh\">Proactive Token Refresh\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#proactive-token-refresh\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Proactive Token Refresh”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">getAccessToken()\u003C/code> checks \u003Ccode dir=\"auto\">expires_on\u003C/code> from the \u003Ccode dir=\"auto\">/.auth/me\u003C/code> response. If the token expires within \u003Cstrong>5 minutes\u003C/strong>, it calls \u003Ccode dir=\"auto\">/.auth/refresh\u003C/code> before returning the token. If refresh fails but the token hasn’t actually expired, the existing token is returned as a fallback.\u003C/p>\n\u003Cp>Flow:\u003C/p>\n\u003Col>\n\u003Cli>Fetch \u003Ccode dir=\"auto\">/.auth/me\u003C/code> → extract \u003Ccode dir=\"auto\">access_token\u003C/code> + \u003Ccode dir=\"auto\">expires_on\u003C/code>\u003C/li>\n\u003Cli>If expires within 5 min → call \u003Ccode dir=\"auto\">/.auth/refresh\u003C/code>\n\u003Cul>\n\u003Cli>Success → re-fetch \u003Ccode dir=\"auto\">/.auth/me\u003C/code> → return new token\u003C/li>\n\u003Cli>Failure → return existing token (still valid)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>If not near expiry → return token directly\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"periodic-background-refresh\">Periodic Background Refresh\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#periodic-background-refresh\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Periodic Background Refresh”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">startPeriodicRefresh()\u003C/code> runs a 45-minute interval that calls \u003Ccode dir=\"auto\">/.auth/refresh\u003C/code> in the background. This prevents session expiry during long analysis sessions (EasyAuth tokens typically expire after 1 hour).\u003C/p>\n\u003Cul>\n\u003Cli>Started on app mount, stopped on unmount\u003C/li>\n\u003Cli>Safe to call multiple times — clears any existing interval first\u003C/li>\n\u003Cli>Failures are logged but do not interrupt the user session\u003C/li>\n\u003Cli>Companion: \u003Ccode dir=\"auto\">stopPeriodicRefresh()\u003C/code> for cleanup\u003C/li>\n\u003C/ul>\n\u003Cp>Source: \u003Ccode dir=\"auto\">apps/azure/src/auth/easyAuth.ts\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"graph-api-token-usage\">Graph API Token Usage\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#graph-api-token-usage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Graph API Token Usage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">/.auth/me\u003C/code> response includes an \u003Ccode dir=\"auto\">access_token\u003C/code> that can be used for Microsoft Graph API calls:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">token\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getAccessToken\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fetch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">https://graph.microsoft.com/v1.0/me/drive/root:/VariScout/Projects\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">headers: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">Authorization: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Bearer \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">token\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const token = await getAccessToken();const response = await fetch('https://graph.microsoft.com/v1.0/me/drive/root:/VariScout/Projects', { headers: { Authorization: `Bearer ${token}`, },});\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The token is automatically scoped to the permissions configured in the EasyAuth login parameters. Standard plan: \u003Ccode dir=\"auto\">User.Read\u003C/code>. Team plan adds: \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code>, \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>, \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"arm-template-configuration\">ARM Template Configuration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#arm-template-configuration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ARM Template Configuration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>EasyAuth is configured in the ARM template via \u003Ccode dir=\"auto\">authsettingsV2\u003C/code>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"json\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"type\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">Microsoft.Web/sites/config\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"name\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">[concat(webAppName, '/authsettingsV2')]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"properties\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"platform\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: { \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"enabled\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> },\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"globalValidation\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"requireAuthentication\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"unauthenticatedClientAction\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">RedirectToLoginPage\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"redirectToProvider\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">azureactivedirectory\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"identityProviders\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"azureActiveDirectory\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"enabled\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"registration\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"clientId\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\"><app-registration-client-id>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"clientSecretSettingName\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"login\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"loginParameters\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: [\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#C789D6;--1:#7C5686\">scope=openid profile email User.Read Files.ReadWrite\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"login\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"tokenStore\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: { \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">\"enabled\"\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{ "type": "Microsoft.Web/sites/config", "name": "[concat(webAppName, '/authsettingsV2')]", "properties": { "platform": { "enabled": true }, "globalValidation": { "requireAuthentication": true, "unauthenticatedClientAction": "RedirectToLoginPage", "redirectToProvider": "azureactivedirectory" }, "identityProviders": { "azureActiveDirectory": { "enabled": true, "registration": { "clientId": "\u003Capp-registration-client-id>", "clientSecretSettingName": "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET" }, "login": { "loginParameters": ["scope=openid profile email User.Read Files.ReadWrite"] } } }, "login": { "tokenStore": { "enabled": true } } }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Note:\u003C/strong> The \u003Ccode dir=\"auto\">loginParameters\u003C/code> scope shown above is for the \u003Cstrong>Team plan\u003C/strong>. The actual ARM template uses a conditional expression — Standard plan requests \u003Ccode dir=\"auto\">User.Read\u003C/code> only, Team plan requests the full scope including \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code>.\u003C/p>\n\u003C/blockquote>\n\u003Cp>See \u003Ca href=\"arm-template.md\">ARM Template\u003C/a> for the complete deployment configuration.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"required-permissions\">Required Permissions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#required-permissions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Required Permissions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Standard plan (€99/month):\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Permission\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Admin Consent\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>User.Read\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Get user profile\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>No admin consent required — users grant consent on first login.\u003C/p>\n\u003Cp>\u003Cstrong>Team plan (€299/month) additional scopes:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Permission\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Admin Consent\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Files.ReadWrite\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>OneDrive analysis sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Files.ReadWrite.All\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Channel SharePoint access\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Channel.ReadBasic.All\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Channel listing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teams-sso-team-plan\">Teams SSO (Team Plan)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teams-sso-team-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teams SSO (Team Plan)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When running inside Microsoft Teams, the app uses the Teams SDK for single sign-on:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"client-side-token-acquisition\">Client-side token acquisition\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#client-side-token-acquisition\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Client-side token acquisition”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Ccode dir=\"auto\">@microsoft/teams-js\u003C/code> \u003Ccode dir=\"auto\">authentication.getAuthToken()\u003C/code> acquires an Azure AD token scoped to the app’s client ID\u003C/li>\n\u003Cli>This token identifies the user but cannot call Graph API directly\u003C/li>\n\u003Cli>For Graph API access, the app falls back to EasyAuth redirect (standard flow)\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"on-behalf-of-obo-function\">On-Behalf-Of (OBO) Function\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#on-behalf-of-obo-function\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “On-Behalf-Of (OBO) Function”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When running inside Teams, the app exchanges the Teams SSO token for a Graph API token via an Azure Function:\u003C/p>\n\u003Col>\n\u003Cli>\u003Ccode dir=\"auto\">getTeamsSsoToken()\u003C/code> acquires an Azure AD token scoped to the app’s client ID\u003C/li>\n\u003Cli>The token is POST-ed to the OBO function (\u003Ccode dir=\"auto\">/api/token-exchange\u003C/code>)\u003C/li>\n\u003Cli>The function validates the token’s audience matches \u003Ccode dir=\"auto\">CLIENT_ID\u003C/code>, then exchanges it via MSAL OBO flow\u003C/li>\n\u003Cli>The Graph API token is returned and cached client-side (5 min margin)\u003C/li>\n\u003Cli>If OBO fails, the app falls back to EasyAuth redirect (graceful degradation)\u003C/li>\n\u003C/ol>\n\u003Cp>This enables \u003Cstrong>silent SSO\u003C/strong> — no redirect flash when saving to OneDrive or uploading photos from within Teams.\u003C/p>\n\u003Cp>\u003Cstrong>Security controls on the OBO function:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Control\u003C/th>\u003Cth>Detail\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Audience validation\u003C/td>\u003Ctd>JWT \u003Ccode dir=\"auto\">aud\u003C/code> must match \u003Ccode dir=\"auto\">CLIENT_ID\u003C/code> — prevents exchanging tokens issued for other apps\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Scope allowlist\u003C/td>\u003Ctd>Only \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>, \u003Ccode dir=\"auto\">ChannelMessage.Send\u003C/code>, \u003Ccode dir=\"auto\">People.Read\u003C/code> — other scopes rejected with 400\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CORS\u003C/td>\u003Ctd>Configurable \u003Ccode dir=\"auto\">ALLOWED_ORIGIN\u003C/code> env var (defaults to \u003Ccode dir=\"auto\">*\u003C/code> for dev); \u003Ccode dir=\"auto\">OPTIONS\u003C/code> preflight supported\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Function-key auth\u003C/td>\u003Ctd>Optional \u003Ccode dir=\"auto\">FUNCTION_KEY\u003C/code> env var — if set, requests must include \u003Ccode dir=\"auto\">X-Functions-Key\u003C/code> header\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Generic errors\u003C/td>\u003Ctd>Catch block returns \u003Ccode dir=\"auto\">\"Token exchange failed\"\u003C/code> — no MSAL internals leaked to clients\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Method restriction\u003C/td>\u003Ctd>Only \u003Ccode dir=\"auto\">POST\u003C/code> accepted; other methods return 405\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cul>\n\u003Cli>Function code: \u003Ccode dir=\"auto\">infra/functions/token-exchange/index.js\u003C/code>\u003C/li>\n\u003Cli>Client module: \u003Ccode dir=\"auto\">apps/azure/src/auth/graphToken.ts\u003C/code>\u003C/li>\n\u003Cli>Used by: \u003Ccode dir=\"auto\">storage.ts\u003C/code> (OneDrive sync) and \u003Ccode dir=\"auto\">photoUpload.ts\u003C/code> (photo uploads)\u003C/li>\n\u003Cli>See \u003Ca href=\"../../07-decisions/adr-016-teams-integration.md\">ADR-016\u003C/a> Phase 6\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"teams-sso-in-the-manifest\">Teams SSO in the manifest\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#teams-sso-in-the-manifest\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teams SSO in the manifest”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">webApplicationInfo\u003C/code> in the Teams manifest enables SSO\u003C/li>\n\u003Cli>Requires the App Registration’s Client ID\u003C/li>\n\u003Cli>Custom domains recommended (SSO blocked on \u003Ccode dir=\"auto\">*.azurewebsites.net\u003C/code>)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"code-reference\">Code reference\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#code-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Code reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Teams SDK init: \u003Ccode dir=\"auto\">apps/azure/src/teams/teamsContext.ts\u003C/code>\u003C/li>\n\u003Cli>SSO token: \u003Ccode dir=\"auto\">getTeamsSsoToken()\u003C/code> in the same module\u003C/li>\n\u003Cli>Tab configuration: \u003Ccode dir=\"auto\">apps/azure/src/teams/TeamsTabConfig.tsx\u003C/code>\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"onedrive-sync.md\">OneDrive Sync\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"arm-template.md\">ARM Template\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://learn.microsoft.com/en-us/azure/app-service/overview-authentication-authorization\">App Service Authentication Docs\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 11462, + "localImagePaths": 11516, + "remoteImagePaths": 11517, + "frontmatter": 11518, + "imagePaths": 11519 + }, + [ + 11463, 11465, 11466, 11467, 11470, 11473, 11476, 11479, 11482, 11485, 11488, 11491, 11494, + 11497, 11500, 11503, 11506, 11509, 11512, 11515 + ], + { "depth": 30, "slug": 11464, "text": 11452 }, + "authentication-easyauth", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 1173, "text": 1174 }, + { "depth": 33, "slug": 11468, "text": 11469 }, + "auth-endpoints", + "Auth Endpoints", + { "depth": 79, "slug": 11471, "text": 11472 }, + "authme-response-structure", + "/.auth/me Response Structure", + { "depth": 33, "slug": 11474, "text": 11475 }, + "client-side-helper", + "Client-Side Helper", + { "depth": 79, "slug": 11477, "text": 11478 }, + "local-development", + "Local Development", + { "depth": 33, "slug": 11480, "text": 11481 }, + "error-handling", + "Error Handling", + { "depth": 79, "slug": 11483, "text": 11484 }, + "autherror-class", + "AuthError Class", + { "depth": 79, "slug": 11486, "text": 11487 }, + "proactive-token-refresh", + "Proactive Token Refresh", + { "depth": 79, "slug": 11489, "text": 11490 }, + "periodic-background-refresh", + "Periodic Background Refresh", + { "depth": 33, "slug": 11492, "text": 11493 }, + "graph-api-token-usage", + "Graph API Token Usage", + { "depth": 33, "slug": 11495, "text": 11496 }, + "arm-template-configuration", + "ARM Template Configuration", + { "depth": 33, "slug": 11498, "text": 11499 }, + "required-permissions", + "Required Permissions", + { "depth": 33, "slug": 11501, "text": 11502 }, + "teams-sso-team-plan", + "Teams SSO (Team Plan)", + { "depth": 79, "slug": 11504, "text": 11505 }, + "client-side-token-acquisition", + "Client-side token acquisition", + { "depth": 79, "slug": 11507, "text": 11508 }, + "on-behalf-of-obo-function", + "On-Behalf-Of (OBO) Function", + { "depth": 79, "slug": 11510, "text": 11511 }, + "teams-sso-in-the-manifest", + "Teams SSO in the manifest", + { "depth": 79, "slug": 11513, "text": 11514 }, + "code-reference", + "Code reference", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11452 }, + [], + "08-products/azure/certification-guide", + { + "id": 11520, + "data": 11522, + "body": 11527, + "filePath": 11528, + "digest": 11529, + "rendered": 11530 + }, + { + "title": 11523, + "editUrl": 16, + "head": 11524, + "template": 18, + "sidebar": 11525, + "pagefind": 16, + "draft": 20 + }, + "Azure Marketplace Certification Guide", + [], + { "hidden": 20, "attrs": 11526 }, + {}, + "# Azure Marketplace Certification Guide\n\nPermanent reference for what Microsoft evaluates during Managed Application certification review, mapped to VariScout's architecture.\n\n---\n\n## Three Layers of Review\n\n### Layer 1: Publisher Business Eligibility\n\nPrerequisites before any code is reviewed:\n\n| Requirement | Details |\n| ------------------------------- | --------------------------------------------------------------------- |\n| Partner Center account | Registered at [partner.microsoft.com](https://partner.microsoft.com/) |\n| Publisher profile | Company name (RDMAIC Oy), logo, description |\n| Bank verification | Finnish IBAN for payouts, 2–5 business days |\n| Marketplace Publisher Agreement | Legal review and acceptance |\n| App Certification Policies | Acceptance required |\n\n**Timeline:** Varies, typically 1–2 weeks for new publishers.\n\n---\n\n### Layer 2: Content Validation (Manual, ~2–5 days)\n\nMicrosoft reviewers manually check listing quality:\n\n| Check | Requirement | VariScout Status |\n| ------------------ | ------------------------------------------------- | ----------------------------------------- |\n| Listing text | Accurate, no misleading claims | Draft in [marketplace.md](marketplace.md) |\n| Screenshots | 1280×720+ PNG, no browser chrome, product UI only | Not yet created |\n| Privacy policy URL | HTTPS, must return 200 | variscout.com/legal/privacy |\n| Terms of use URL | HTTPS, must return 200 | variscout.com/legal/terms |\n| Support contact | Email with response time commitment | hello@variscout.com |\n| Categories | Correct marketplace category selection | Pending |\n| Keywords | Relevant search terms | Pending |\n\n**Common rejections:** Broken legal URLs, screenshots with browser chrome, description too vague, missing response time commitment on support contact.\n\n---\n\n### Layer 3: Technical Validation (Automated + Manual, ~3–10 days)\n\nThe deepest review layer. Covers ARM template, security, and functionality.\n\n#### ARM Template (arm-ttk automated tests)\n\n| Rule | Requirement | VariScout |\n| -------------------------- | ------------------------------------------------------------------ | ------------------------------------------ |\n| Valid JSON schema | `2019-04-01/deploymentTemplate.json#` | ✅ Correct |\n| `apiVersion` freshness | ≤24 months old on all resources | ✅ `2025-01-01` |\n| `secureString` for secrets | Passwords and keys use `secureString` type | ✅ `clientSecret` is `secureString` |\n| Parameter descriptions | All parameters have `metadata.description` | ✅ All 5 parameters described |\n| No hardcoded URIs | Portal/management endpoints, deployment URLs must be parameterized | ✅ `packageUrl` is a parameter |\n| No unnecessary Owner RBAC | Publisher shouldn't request Owner over managed RG | ✅ No publisher access set |\n| `uniqueString()` in names | Resource names must be globally unique | ✅ `appName` default uses `uniqueString()` |\n| Correct `dependsOn` | Resources reference dependencies properly | ✅ Site → Plan, Auth → Site |\n| Zip structure | `mainTemplate.json` + `createUiDefinition.json` at zip root | Manual step at packaging |\n\n#### createUiDefinition Validation\n\n| Rule | Requirement | VariScout |\n| ------------------------- | ----------------------------------------------------- | ------------------------------------ |\n| Outputs map to parameters | Every CUID output must match a mainTemplate parameter | ✅ 4 outputs → 4 parameters |\n| `PasswordBox` for secrets | Secrets use password input, not TextBox | ✅ `clientSecret` uses `PasswordBox` |\n| Regex constraints | Input validation where appropriate | ✅ `appName` + `clientId` have regex |\n| Sandbox rendering | Must render without errors in portal sandbox | Needs testing |\n\n#### Security Scan\n\n| Check | Details | VariScout |\n| ------------------- | -------------------------------------- | ----------------------------------------- |\n| Malware scan | Automated scan of deployment package | Low risk — static SPA |\n| Network monitoring | No unexpected outbound calls | Only Graph API (OneDrive) |\n| Data exfiltration | No data sent to unauthorized endpoints | Offline-first, data stays in browser |\n| npm vulnerabilities | Dependency audit | Verify with `npm audit` before submission |\n\n#### Functionality Test\n\nMicrosoft deploys the app through the marketplace flow and verifies:\n\n1. Deployment completes successfully (target: \u003C10 minutes)\n2. App loads at the deployed URL\n3. Authentication redirects work (EasyAuth → Azure AD)\n4. Core functionality operates (charts render, data can be loaded)\n\n#### Managed Application Specific\n\n| Check | Details | VariScout |\n| ---------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------ |\n| CUID tracking | Customer Usage Attribution — auto-injected by Partner Center at publish time | ✅ No manual action needed (no nested `Microsoft.Resources/deployments`) |\n| Publisher access | Authorization level over managed resource group | ✅ No publisher access (customer-controlled) |\n| Lock level | Resource lock on managed RG | Default (customer controls) |\n\n---\n\n## VariScout-Specific Notes\n\n### Why CUID Is Automatic\n\nPartner Center auto-injects the Customer Usage Attribution tracking ID into the deployment template at publish time. This works because our template doesn't use nested `Microsoft.Resources/deployments` — the resources deploy directly. No manual GUID injection or tracking code is needed.\n\n### Security Posture\n\nVariScout has a minimal attack surface for certification:\n\n- **Offline-first SPA** — all statistical processing runs in the browser\n- **No backend API** — no server-side code to exploit\n- **Only external call** — Microsoft Graph API for OneDrive sync (Team plan only; delegated permissions: `User.Read` + `Files.ReadWrite`). Standard plan has no external API calls.\n- **EasyAuth** — authentication handled entirely by Azure App Service platform\n- **HTTPS enforced** — `httpsOnly: true` in ARM template\n- **TLS 1.2 minimum** — `minTlsVersion: \"1.2\"` in site config\n- **FTP disabled** — `ftpsState: \"Disabled\"` in site config\n\n### Template Validation\n\n```bash\n# Install arm-ttk (PowerShell)\nInstall-Module -Name arm-ttk -Force\n\n# Run validation\nTest-AzTemplate -TemplatePath infra/mainTemplate.json\n\n# Test createUiDefinition in portal sandbox\n# https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/SandboxBlade\n```\n\n---\n\n## See Also\n\n- [Submission Checklist](submission-checklist.md) — live tracker of submission status\n- [Marketplace Guide](marketplace.md) — listing content and pricing\n- [ARM Template](arm-template.md) — template documentation\n- [Authentication](authentication.md) — EasyAuth setup", + "src/content/docs/08-products/azure/certification-guide.md", + "8dd6d3bb9d04bf5f", + { "html": 11531, "metadata": 11532 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"azure-marketplace-certification-guide\">Azure Marketplace Certification Guide\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#azure-marketplace-certification-guide\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Marketplace Certification Guide”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Permanent reference for what Microsoft evaluates during Managed Application certification review, mapped to VariScout’s architecture.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"three-layers-of-review\">Three Layers of Review\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#three-layers-of-review\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Three Layers of Review”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layer-1-publisher-business-eligibility\">Layer 1: Publisher Business Eligibility\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layer-1-publisher-business-eligibility\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layer 1: Publisher Business Eligibility”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Prerequisites before any code is reviewed:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Requirement\u003C/th>\u003Cth>Details\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Partner Center account\u003C/td>\u003Ctd>Registered at \u003Ca href=\"https://partner.microsoft.com/\">partner.microsoft.com\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Publisher profile\u003C/td>\u003Ctd>Company name (RDMAIC Oy), logo, description\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Bank verification\u003C/td>\u003Ctd>Finnish IBAN for payouts, 2–5 business days\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Marketplace Publisher Agreement\u003C/td>\u003Ctd>Legal review and acceptance\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>App Certification Policies\u003C/td>\u003Ctd>Acceptance required\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Timeline:\u003C/strong> Varies, typically 1–2 weeks for new publishers.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layer-2-content-validation-manual-25-days\">Layer 2: Content Validation (Manual, ~2–5 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layer-2-content-validation-manual-25-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layer 2: Content Validation (Manual, ~2–5 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Microsoft reviewers manually check listing quality:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Check\u003C/th>\u003Cth>Requirement\u003C/th>\u003Cth>VariScout Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Listing text\u003C/td>\u003Ctd>Accurate, no misleading claims\u003C/td>\u003Ctd>Draft in \u003Ca href=\"marketplace.md\">marketplace.md\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Screenshots\u003C/td>\u003Ctd>1280×720+ PNG, no browser chrome, product UI only\u003C/td>\u003Ctd>Not yet created\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Privacy policy URL\u003C/td>\u003Ctd>HTTPS, must return 200\u003C/td>\u003Ctd>variscout.com/legal/privacy\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Terms of use URL\u003C/td>\u003Ctd>HTTPS, must return 200\u003C/td>\u003Ctd>variscout.com/legal/terms\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Support contact\u003C/td>\u003Ctd>Email with response time commitment\u003C/td>\u003Ctd>\u003Ca href=\"mailto:hello@variscout.com\">hello@variscout.com\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Categories\u003C/td>\u003Ctd>Correct marketplace category selection\u003C/td>\u003Ctd>Pending\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Keywords\u003C/td>\u003Ctd>Relevant search terms\u003C/td>\u003Ctd>Pending\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Common rejections:\u003C/strong> Broken legal URLs, screenshots with browser chrome, description too vague, missing response time commitment on support contact.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"layer-3-technical-validation-automated--manual-310-days\">Layer 3: Technical Validation (Automated + Manual, ~3–10 days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#layer-3-technical-validation-automated--manual-310-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layer 3: Technical Validation (Automated + Manual, ~3–10 days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The deepest review layer. Covers ARM template, security, and functionality.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"arm-template-arm-ttk-automated-tests\">ARM Template (arm-ttk automated tests)\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#arm-template-arm-ttk-automated-tests\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ARM Template (arm-ttk automated tests)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Rule\u003C/th>\u003Cth>Requirement\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Valid JSON schema\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">2019-04-01/deploymentTemplate.json#\u003C/code>\u003C/td>\u003Ctd>✅ Correct\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">apiVersion\u003C/code> freshness\u003C/td>\u003Ctd>≤24 months old on all resources\u003C/td>\u003Ctd>✅ \u003Ccode dir=\"auto\">2025-01-01\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">secureString\u003C/code> for secrets\u003C/td>\u003Ctd>Passwords and keys use \u003Ccode dir=\"auto\">secureString\u003C/code> type\u003C/td>\u003Ctd>✅ \u003Ccode dir=\"auto\">clientSecret\u003C/code> is \u003Ccode dir=\"auto\">secureString\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Parameter descriptions\u003C/td>\u003Ctd>All parameters have \u003Ccode dir=\"auto\">metadata.description\u003C/code>\u003C/td>\u003Ctd>✅ All 5 parameters described\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No hardcoded URIs\u003C/td>\u003Ctd>Portal/management endpoints, deployment URLs must be parameterized\u003C/td>\u003Ctd>✅ \u003Ccode dir=\"auto\">packageUrl\u003C/code> is a parameter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No unnecessary Owner RBAC\u003C/td>\u003Ctd>Publisher shouldn’t request Owner over managed RG\u003C/td>\u003Ctd>✅ No publisher access set\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">uniqueString()\u003C/code> in names\u003C/td>\u003Ctd>Resource names must be globally unique\u003C/td>\u003Ctd>✅ \u003Ccode dir=\"auto\">appName\u003C/code> default uses \u003Ccode dir=\"auto\">uniqueString()\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Correct \u003Ccode dir=\"auto\">dependsOn\u003C/code>\u003C/td>\u003Ctd>Resources reference dependencies properly\u003C/td>\u003Ctd>✅ Site → Plan, Auth → Site\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Zip structure\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">mainTemplate.json\u003C/code> + \u003Ccode dir=\"auto\">createUiDefinition.json\u003C/code> at zip root\u003C/td>\u003Ctd>Manual step at packaging\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"createuidefinition-validation\">createUiDefinition Validation\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#createuidefinition-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “createUiDefinition Validation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Rule\u003C/th>\u003Cth>Requirement\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Outputs map to parameters\u003C/td>\u003Ctd>Every CUID output must match a mainTemplate parameter\u003C/td>\u003Ctd>✅ 4 outputs → 4 parameters\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PasswordBox\u003C/code> for secrets\u003C/td>\u003Ctd>Secrets use password input, not TextBox\u003C/td>\u003Ctd>✅ \u003Ccode dir=\"auto\">clientSecret\u003C/code> uses \u003Ccode dir=\"auto\">PasswordBox\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regex constraints\u003C/td>\u003Ctd>Input validation where appropriate\u003C/td>\u003Ctd>✅ \u003Ccode dir=\"auto\">appName\u003C/code> + \u003Ccode dir=\"auto\">clientId\u003C/code> have regex\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sandbox rendering\u003C/td>\u003Ctd>Must render without errors in portal sandbox\u003C/td>\u003Ctd>Needs testing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"security-scan\">Security Scan\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#security-scan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Scan”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Check\u003C/th>\u003Cth>Details\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Malware scan\u003C/td>\u003Ctd>Automated scan of deployment package\u003C/td>\u003Ctd>Low risk — static SPA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Network monitoring\u003C/td>\u003Ctd>No unexpected outbound calls\u003C/td>\u003Ctd>Only Graph API (OneDrive)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Data exfiltration\u003C/td>\u003Ctd>No data sent to unauthorized endpoints\u003C/td>\u003Ctd>Offline-first, data stays in browser\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>npm vulnerabilities\u003C/td>\u003Ctd>Dependency audit\u003C/td>\u003Ctd>Verify with \u003Ccode dir=\"auto\">npm audit\u003C/code> before submission\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"functionality-test\">Functionality Test\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#functionality-test\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Functionality Test”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Microsoft deploys the app through the marketplace flow and verifies:\u003C/p>\n\u003Col>\n\u003Cli>Deployment completes successfully (target: <10 minutes)\u003C/li>\n\u003Cli>App loads at the deployed URL\u003C/li>\n\u003Cli>Authentication redirects work (EasyAuth → Azure AD)\u003C/li>\n\u003Cli>Core functionality operates (charts render, data can be loaded)\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h4\">\u003Ch4 id=\"managed-application-specific\">Managed Application Specific\u003C/h4>\u003Ca class=\"sl-anchor-link\" href=\"#managed-application-specific\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Managed Application Specific”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Check\u003C/th>\u003Cth>Details\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>CUID tracking\u003C/td>\u003Ctd>Customer Usage Attribution — auto-injected by Partner Center at publish time\u003C/td>\u003Ctd>✅ No manual action needed (no nested \u003Ccode dir=\"auto\">Microsoft.Resources/deployments\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Publisher access\u003C/td>\u003Ctd>Authorization level over managed resource group\u003C/td>\u003Ctd>✅ No publisher access (customer-controlled)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Lock level\u003C/td>\u003Ctd>Resource lock on managed RG\u003C/td>\u003Ctd>Default (customer controls)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"variscout-specific-notes\">VariScout-Specific Notes\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-specific-notes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout-Specific Notes”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-cuid-is-automatic\">Why CUID Is Automatic\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-cuid-is-automatic\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why CUID Is Automatic”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Partner Center auto-injects the Customer Usage Attribution tracking ID into the deployment template at publish time. This works because our template doesn’t use nested \u003Ccode dir=\"auto\">Microsoft.Resources/deployments\u003C/code> — the resources deploy directly. No manual GUID injection or tracking code is needed.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"security-posture\">Security Posture\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#security-posture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Security Posture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout has a minimal attack surface for certification:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Offline-first SPA\u003C/strong> — all statistical processing runs in the browser\u003C/li>\n\u003Cli>\u003Cstrong>No backend API\u003C/strong> — no server-side code to exploit\u003C/li>\n\u003Cli>\u003Cstrong>Only external call\u003C/strong> — Microsoft Graph API for OneDrive sync (Team plan only; delegated permissions: \u003Ccode dir=\"auto\">User.Read\u003C/code> + \u003Ccode dir=\"auto\">Files.ReadWrite\u003C/code>). Standard plan has no external API calls.\u003C/li>\n\u003Cli>\u003Cstrong>EasyAuth\u003C/strong> — authentication handled entirely by Azure App Service platform\u003C/li>\n\u003Cli>\u003Cstrong>HTTPS enforced\u003C/strong> — \u003Ccode dir=\"auto\">httpsOnly: true\u003C/code> in ARM template\u003C/li>\n\u003Cli>\u003Cstrong>TLS 1.2 minimum\u003C/strong> — \u003Ccode dir=\"auto\">minTlsVersion: \"1.2\"\u003C/code> in site config\u003C/li>\n\u003Cli>\u003Cstrong>FTP disabled\u003C/strong> — \u003Ccode dir=\"auto\">ftpsState: \"Disabled\"\u003C/code> in site config\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"template-validation\">Template Validation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#template-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Template Validation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Install arm-ttk (PowerShell)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Install-Module\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-Name\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">arm-ttk\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-Force\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run validation\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Test-AzTemplate\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-TemplatePath\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">infra/mainTemplate.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Test createUiDefinition in portal sandbox\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/SandboxBlade\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Install-Module -Name arm-ttk -ForceTest-AzTemplate -TemplatePath infra/mainTemplate.json\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"submission-checklist.md\">Submission Checklist\u003C/a> — live tracker of submission status\u003C/li>\n\u003Cli>\u003Ca href=\"marketplace.md\">Marketplace Guide\u003C/a> — listing content and pricing\u003C/li>\n\u003Cli>\u003Ca href=\"arm-template.md\">ARM Template\u003C/a> — template documentation\u003C/li>\n\u003Cli>\u003Ca href=\"authentication.md\">Authentication\u003C/a> — EasyAuth setup\u003C/li>\n\u003C/ul>", + { + "headings": 11533, + "localImagePaths": 11576, + "remoteImagePaths": 11577, + "frontmatter": 11578, + "imagePaths": 11579 + }, + [ + 11534, 11536, 11539, 11542, 11545, 11548, 11551, 11554, 11557, 11560, 11563, 11566, 11569, + 11572, 11575 + ], + { "depth": 30, "slug": 11535, "text": 11523 }, + "azure-marketplace-certification-guide", + { "depth": 33, "slug": 11537, "text": 11538 }, + "three-layers-of-review", + "Three Layers of Review", + { "depth": 79, "slug": 11540, "text": 11541 }, + "layer-1-publisher-business-eligibility", + "Layer 1: Publisher Business Eligibility", + { "depth": 79, "slug": 11543, "text": 11544 }, + "layer-2-content-validation-manual-25-days", + "Layer 2: Content Validation (Manual, ~2–5 days)", + { "depth": 79, "slug": 11546, "text": 11547 }, + "layer-3-technical-validation-automated--manual-310-days", + "Layer 3: Technical Validation (Automated + Manual, ~3–10 days)", + { "depth": 621, "slug": 11549, "text": 11550 }, + "arm-template-arm-ttk-automated-tests", + "ARM Template (arm-ttk automated tests)", + { "depth": 621, "slug": 11552, "text": 11553 }, + "createuidefinition-validation", + "createUiDefinition Validation", + { "depth": 621, "slug": 11555, "text": 11556 }, + "security-scan", + "Security Scan", + { "depth": 621, "slug": 11558, "text": 11559 }, + "functionality-test", + "Functionality Test", + { "depth": 621, "slug": 11561, "text": 11562 }, + "managed-application-specific", + "Managed Application Specific", + { "depth": 33, "slug": 11564, "text": 11565 }, + "variscout-specific-notes", + "VariScout-Specific Notes", + { "depth": 79, "slug": 11567, "text": 11568 }, + "why-cuid-is-automatic", + "Why CUID Is Automatic", + { "depth": 79, "slug": 11570, "text": 11571 }, + "security-posture", + "Security Posture", + { "depth": 79, "slug": 11573, "text": 11574 }, + "template-validation", + "Template Validation", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11523 }, + [], + "08-products/azure/how-it-works", + { + "id": 11580, + "data": 11582, + "body": 11586, + "filePath": 11587, + "digest": 11588, + "rendered": 11589 + }, + { + "title": 1174, + "editUrl": 16, + "head": 11583, + "template": 18, + "sidebar": 11584, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 11585 }, + {}, + "# How It Works\n\nEnd-to-end guide to VariScout's Azure architecture — what gets deployed, how users log in, where data lives, and why it's secure.\n\n---\n\n## What Gets Deployed\n\nThe ARM template deploys **3 resources** to the customer's Azure subscription:\n\n```\nCUSTOMER'S AZURE SUBSCRIPTION\n└── Managed Resource Group\n ├── 1. App Service Plan (Linux B1)\n │ Compute host for the web app\n │\n ├── 2. App Service\n │ Serves the VariScout build via WEBSITE_RUN_FROM_PACKAGE\n │ (static zip — no server-side code)\n │\n └── 3. EasyAuth Configuration (authsettingsV2)\n Platform-level Azure AD authentication\n Token store for Graph API access\n```\n\nThere is **no database, no backend API, no storage account**. The App Service serves a static build — all computation happens in the user's browser.\n\n---\n\n## Deployment Flow\n\n```\nCUSTOMER AZURE PORTAL ARM ENGINE\n │ │ │\n │ 1. Create App Registration (Azure AD) │\n │ - Client ID + Client Secret │\n │ - Permissions: User.Read (Standard) or │\n │ + Files.ReadWrite.All, Channel.ReadBasic.All (Team)│\n │ │ │\n │ 2. Find VariScout ───────▶│ │\n │ on Marketplace │ │\n │ │ │\n │ 3. Click \"Create\" ──────▶│ │\n │ Enter app name, │ │\n │ region, Client ID, │ │\n │ Client Secret │ │\n │ │── 4. Deploy ARM ──────────▶│\n │ │ template │\n │ │ │── Creates Plan\n │ │ │── Creates Site\n │ │ │── Configures EasyAuth\n │ │◀── 5. Done (~2 min) ──────│\n │ │ │\n │◀── 6. App URL ────────────│ │\n │ https://variscout-xyz.azurewebsites.net │\n```\n\n### Pre-requisite: App Registration\n\nBefore deploying, the customer creates an App Registration in Azure AD. This is needed because Managed Applications cannot create registrations in the customer's tenant. The customer provides two values during deployment:\n\n| Parameter | Type | Purpose |\n| -------------- | ------------ | --------------------------------- |\n| `clientId` | string | Identifies the app to Azure AD |\n| `clientSecret` | secureString | Authenticates the app to Azure AD |\n\nThe ARM template stores the secret as an app setting (`MICROSOFT_PROVIDER_AUTHENTICATION_SECRET`) — it never appears in logs or outputs.\n\n---\n\n## First Login\n\nEasyAuth runs as middleware in the App Service platform. The app never sees unauthenticated requests.\n\n```\nUSER APP SERVICE (EasyAuth) AZURE AD\n │ │ │\n │── Visit app URL ────────────▶│ │\n │ │── Not authenticated ───▶│\n │ │ Redirect to login │\n │ │ │\n │◀────────── Azure AD sign-in page ─────────────────────▶│\n │ User enters credentials │\n │ Consents to permissions (plan-dependent) │\n │ │ │\n │ │◀── Session cookie ──────│\n │ │ + tokens in store │\n │◀── Serve app ────────────────│ │\n```\n\nAfter login:\n\n- A session cookie is set (platform-managed, not application code)\n- Access tokens are stored server-side in the EasyAuth token store\n- The app reads user info and tokens from `/.auth/me`\n- Token refresh is handled automatically by the platform\n\n### EasyAuth Endpoints\n\n| Endpoint | Purpose |\n| ------------------ | ------------------------------------- |\n| `/.auth/login/aad` | Redirect to Azure AD sign-in |\n| `/.auth/logout` | Sign out and clear session |\n| `/.auth/me` | Get current user info + access tokens |\n| `/.auth/refresh` | Refresh the session token |\n\n---\n\n## Using the App\n\nAll data processing happens in the browser. Nothing is sent to a server.\n\n```\nCSV/EXCEL FILE BROWSER SCREEN\n │ │ │\n │── Upload/paste ───▶│ │\n │ │── Parse (parser.ts) ──────────▶│\n │ │ Detect columns, types │\n │ │ │\n │ │── Calculate stats ────────────▶│\n │ │ (stats.ts: mean, Cpk, etc.) │\n │ │ │\n │ │── Render charts ──────────────▶│\n │ │ (Visx: I-Chart, Boxplot, │\n │ │ Pareto, Capability) │\n │ │ │\n │ │── User drills down ───────────▶│\n │ │ Filter → recalculate → │\n │ │ re-render │\n```\n\nThe app supports:\n\n- **CSV and Excel upload** — parsed entirely in-browser\n- **Copy-paste** — paste from spreadsheets, auto-detected via `detectColumns()`, reviewed in ColumnMapping (same flow as PWA, with up to 6 factors)\n- **Manual entry** — type values directly\n- **Add data during analysis** — \"Add Data\" dropdown offers paste, upload, or manual entry. Auto-detects whether to append rows (same columns) or add columns (new columns). Replace confirmation when loading entirely new data.\n- **Performance Mode** — analyze hundreds of measurement channels simultaneously\n\n---\n\n## Data Persistence\n\nSave is explicit — the user clicks **Save** in the editor header. Unsaved work is lost if the browser tab closes. The storage model depends on the plan:\n\n### Standard Plan — Local Files\n\nData stays on the user's device. No cloud sync, no OneDrive.\n\n```\nBROWSER USER'S COMPUTER\n(IndexedDB) (File System Access API)\n │ │\n │── User clicks Save ───────────▶│\n │ IndexedDB + local file │\n │ │\n │◀── User opens project ─────────│\n │ Load from IndexedDB/file │\n```\n\n- Projects saved to IndexedDB with optional local file export via File System Access API\n- No internet required after initial deployment\n- Only `User.Read` permission needed\n\n### Team Plan — Local Files + Cloud Sync\n\nEverything in Standard, plus OneDrive personal sync and SharePoint channel storage.\n\n```\nBROWSER USER'S ONEDRIVE / CHANNEL SHAREPOINT\n(IndexedDB) (Graph API)\n │ │\n │◀── Load on startup ────────────│\n │ (if online) │\n │ │\n │── User saves changes ─────────▶│\n │ (debounced write) │\n │ │\n │── Offline? ────────────────────│\n │ Queue changes locally │\n │ │\n │── Back online ────────────────▶│\n │ Flush queued changes │\n```\n\n**Personal OneDrive** (personal tab or browser):\n\n```\nOneDrive/\n└── VariScout/\n └── Projects/\n ├── analysis-001.vrs\n └── ...\n```\n\n**Channel SharePoint** (channel tab):\n\n```\nChannel Files/VariScout/\n├── Projects/\n│ └── Feb-Fill-Line.vrs ← shared analysis\n└── Photos/\n └── {analysisId}/{findingId}/\n └── photo-001.jpg ← EXIF-stripped evidence\n```\n\nStorage location is automatic: channel tab → SharePoint, personal tab → OneDrive, browser → OneDrive.\n\n### Offline Behavior\n\n| State | Standard | Team |\n| --------- | ------------------------ | ----------------------------- |\n| Online | Save to IndexedDB + file | + sync to OneDrive/SharePoint |\n| Offline | Full local functionality | Full local functionality |\n| Reconnect | N/A | Flush queued changes to cloud |\n\n---\n\n## Teams Integration (Team Plan)\n\nThe Team plan adds Microsoft Teams as a collaboration layer. The same codebase detects its runtime context and adapts:\n\n```\nTeams SDK initialized?\n├── Yes → Channel tab? → shared channel SharePoint storage\n│ → Personal tab? → personal OneDrive\n│ → SSO via On-Behalf-Of token exchange\n└── No → Browser mode → local files (File System Access API)\n```\n\n### Authentication: OBO Token Exchange\n\nTeams SSO provides a client-side token that isn't directly usable for Graph API calls. An Azure Function (`token-exchange`) performs the On-Behalf-Of exchange:\n\n```\nTeams Client → SSO token → Azure Function (OBO) → Graph API token\n ↓\n Fallback: EasyAuth redirect\n```\n\nThe `graphToken.ts` module handles the chain: Teams SSO → OBO exchange → EasyAuth fallback. The Azure Function is deployed alongside the App Service via ARM template.\n\n### Channel Storage\n\nWhen running as a channel tab, analyses and photos are stored in the channel's SharePoint document library:\n\n- `channelDrive.ts` resolves the drive via Graph API: `/teams/{teamId}/channels/{channelId}/filesFolder`\n- Drive info is cached in IndexedDB to avoid repeated Graph calls\n- `StorageLocation` type (`'personal' | 'team'`) routes to the correct storage\n\n### Photo Pipeline\n\nPhoto evidence flows through a client-side pipeline:\n\n1. Camera capture — Teams SDK `media.selectMedia()` inside Teams (native camera, `devicePermissions: [\"media\"]` for IT audit trail), HTML5 file input fallback outside Teams\n2. EXIF/GPS metadata stripped (`exifStrip.ts` — byte-level removal, 23 verification tests) — both capture paths feed into the same pipeline\n3. Upload to OneDrive or SharePoint (`photoUpload.ts`)\n4. Thumbnail embedded in `.vrs` file for cross-user preview\n\n### Deep Links and Sharing\n\n- `deepLinks.ts` — builds and parses deep link URLs for specific charts or findings\n- `useTeamsShare.ts` — wraps Teams SDK `sharing.shareWebContent` and `pages.shareDeepLink`\n- `shareContent.ts` — builds share payloads for findings and charts\n\n### User Identity\n\n`getCurrentUser.ts` extracts user identity from the Teams JWT (UPN claim) with EasyAuth fallback. Author names appear on findings and comments for audit trails.\n\nSee [ADR-016](../../07-decisions/adr-016-teams-integration.md) for the full technical design.\n\n---\n\n## Data Ownership & Security\n\n### Data Stays with the Customer\n\n```\nCUSTOMER TENANT PUBLISHER (VariScout)\n┌────────────────────────┐ ┌────────────────────┐\n│ │ │ │\n│ App Service │ │ Marketplace │\n│ (hosts the app) │ ──── NO ───▶ │ listing │\n│ │ connection │ │\n│ Azure AD │ │ No access to: │\n│ (authenticates users) │ │ - Customer data │\n│ │ │ - App resources │\n│ OneDrive/SharePoint │ │ - User identities │\n│ (Team plan sync) │ │ - Usage telemetry │\n│ │ │ │\n└────────────────────────┘ └────────────────────┘\n```\n\n- **Publisher management is disabled** — we have zero access to the customer's deployment\n- **No telemetry** — the app makes no outbound calls to publisher systems\n- **Data survives cancellation** — analyses remain on the user's device (Standard) or in OneDrive/SharePoint (Team) even if the subscription ends\n- **Each deployment is tenant-isolated** — no cross-tenant data access\n\n### Least-Privilege Permissions\n\n| Permission | Type | Plan | Purpose |\n| ----------------------- | --------- | --------- | --------------------------------- |\n| `User.Read` | Delegated | Both | Display user name & email |\n| `Files.ReadWrite.All` | Delegated | Team only | OneDrive + SharePoint file sync |\n| `Channel.ReadBasic.All` | Delegated | Team only | Resolve channel SharePoint drives |\n\n**Standard plan**: Only `User.Read` — no admin consent required, users consent on first login.\n\n**Team plan**: Requires one-time tenant admin consent for `Files.ReadWrite.All` and `Channel.ReadBasic.All`. No mail access, no `Sites.ReadWrite.All`.\n\n### Secret Handling\n\n- The client secret is passed as ARM `secureString` — never logged or exposed in outputs\n- Stored as an App Service app setting (server-side, inaccessible to client code)\n- EasyAuth tokens are stored in the platform token store (not in browser storage)\n- HTTPS enforced, minimum TLS 1.2, FTP disabled\n\n---\n\n## See Also\n\n- [Azure App Overview](index.md) — product positioning and pricing\n- [ARM Template](arm-template.md) — resource definitions and deployment methods\n- [Authentication (EasyAuth)](authentication.md) — auth endpoints and client-side helper\n- [OneDrive Sync](onedrive-sync.md) — sync flow, conflict resolution, offline behavior\n- [Marketplace Guide](marketplace.md) — publishing, certification, listing content", + "src/content/docs/08-products/azure/how-it-works.md", + "3123a7dc34f201e7", + { "html": 11590, "metadata": 11591 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"how-it-works\">How It Works\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#how-it-works\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How It Works”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>End-to-end guide to VariScout’s Azure architecture — what gets deployed, how users log in, where data lives, and why it’s secure.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-gets-deployed\">What Gets Deployed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-gets-deployed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Gets Deployed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The ARM template deploys \u003Cstrong>3 resources\u003C/strong> to the customer’s Azure subscription:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CUSTOMER'S AZURE SUBSCRIPTION\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Managed Resource Group\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── 1. App Service Plan (Linux B1)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Compute host for the web app\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── 2. App Service\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Serves the VariScout build via WEBSITE_RUN_FROM_PACKAGE\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (static zip — no server-side code)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── 3. EasyAuth Configuration (authsettingsV2)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Platform-level Azure AD authentication\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Token store for Graph API access\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"CUSTOMER'S AZURE SUBSCRIPTION└── Managed Resource Group ├── 1. App Service Plan (Linux B1) │ Compute host for the web app │ ├── 2. App Service │ Serves the VariScout build via WEBSITE_RUN_FROM_PACKAGE │ (static zip — no server-side code) │ └── 3. EasyAuth Configuration (authsettingsV2) Platform-level Azure AD authentication Token store for Graph API access\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>There is \u003Cstrong>no database, no backend API, no storage account\u003C/strong>. The App Service serves a static build — all computation happens in the user’s browser.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"deployment-flow\">Deployment Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#deployment-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CUSTOMER AZURE PORTAL ARM ENGINE\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 1. Create App Registration (Azure AD) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Client ID + Client Secret │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ - Permissions: User.Read (Standard) or │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ + Files.ReadWrite.All, Channel.ReadBasic.All (Team)│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 2. Find VariScout ───────▶│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ on Marketplace │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ 3. Click \"Create\" ──────▶│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Enter app name, │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ region, Client ID, │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Client Secret │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │── 4. Deploy ARM ──────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ template │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │── Creates Plan\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │── Creates Site\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │── Configures EasyAuth\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │◀── 5. Done (~2 min) ──────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀── 6. App URL ────────────│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ https://variscout-xyz.azurewebsites.net │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"CUSTOMER AZURE PORTAL ARM ENGINE │ │ │ │ 1. Create App Registration (Azure AD) │ │ - Client ID + Client Secret │ │ - Permissions: User.Read (Standard) or │ │ + Files.ReadWrite.All, Channel.ReadBasic.All (Team)│ │ │ │ │ 2. Find VariScout ───────▶│ │ │ on Marketplace │ │ │ │ │ │ 3. Click "Create" ──────▶│ │ │ Enter app name, │ │ │ region, Client ID, │ │ │ Client Secret │ │ │ │── 4. Deploy ARM ──────────▶│ │ │ template │ │ │ │── Creates Plan │ │ │── Creates Site │ │ │── Configures EasyAuth │ │◀── 5. Done (~2 min) ──────│ │ │ │ │◀── 6. App URL ────────────│ │ │ https://variscout-xyz.azurewebsites.net │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pre-requisite-app-registration\">Pre-requisite: App Registration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pre-requisite-app-registration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pre-requisite: App Registration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Before deploying, the customer creates an App Registration in Azure AD. This is needed because Managed Applications cannot create registrations in the customer’s tenant. The customer provides two values during deployment:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Parameter\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">clientId\u003C/code>\u003C/td>\u003Ctd>string\u003C/td>\u003Ctd>Identifies the app to Azure AD\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">clientSecret\u003C/code>\u003C/td>\u003Ctd>secureString\u003C/td>\u003Ctd>Authenticates the app to Azure AD\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The ARM template stores the secret as an app setting (\u003Ccode dir=\"auto\">MICROSOFT_PROVIDER_AUTHENTICATION_SECRET\u003C/code>) — it never appears in logs or outputs.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"first-login\">First Login\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#first-login\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “First Login”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>EasyAuth runs as middleware in the App Service platform. The app never sees unauthenticated requests.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">USER APP SERVICE (EasyAuth) AZURE AD\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│── Visit app URL ────────────▶│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │── Not authenticated ───▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Redirect to login │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀────────── Azure AD sign-in page ─────────────────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ User enters credentials │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Consents to permissions (plan-dependent) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │◀── Session cookie ──────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ + tokens in store │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀── Serve app ────────────────│ │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"USER APP SERVICE (EasyAuth) AZURE AD │ │ │ │── Visit app URL ────────────▶│ │ │ │── Not authenticated ───▶│ │ │ Redirect to login │ │ │ │ │◀────────── Azure AD sign-in page ─────────────────────▶│ │ User enters credentials │ │ Consents to permissions (plan-dependent) │ │ │ │ │ │◀── Session cookie ──────│ │ │ + tokens in store │ │◀── Serve app ────────────────│ │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>After login:\u003C/p>\n\u003Cul>\n\u003Cli>A session cookie is set (platform-managed, not application code)\u003C/li>\n\u003Cli>Access tokens are stored server-side in the EasyAuth token store\u003C/li>\n\u003Cli>The app reads user info and tokens from \u003Ccode dir=\"auto\">/.auth/me\u003C/code>\u003C/li>\n\u003Cli>Token refresh is handled automatically by the platform\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"easyauth-endpoints\">EasyAuth Endpoints\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#easyauth-endpoints\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “EasyAuth Endpoints”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Endpoint\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">/.auth/login/aad\u003C/code>\u003C/td>\u003Ctd>Redirect to Azure AD sign-in\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">/.auth/logout\u003C/code>\u003C/td>\u003Ctd>Sign out and clear session\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">/.auth/me\u003C/code>\u003C/td>\u003Ctd>Get current user info + access tokens\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">/.auth/refresh\u003C/code>\u003C/td>\u003Ctd>Refresh the session token\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"using-the-app\">Using the App\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#using-the-app\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Using the App”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All data processing happens in the browser. Nothing is sent to a server.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CSV/EXCEL FILE BROWSER SCREEN\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│── Upload/paste ───▶│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │── Parse (parser.ts) ──────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Detect columns, types │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │── Calculate stats ────────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ (stats.ts: mean, Cpk, etc.) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │── Render charts ──────────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ (Visx: I-Chart, Boxplot, │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Pareto, Capability) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │── User drills down ───────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Filter → recalculate → │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ re-render │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"CSV/EXCEL FILE BROWSER SCREEN │ │ │ │── Upload/paste ───▶│ │ │ │── Parse (parser.ts) ──────────▶│ │ │ Detect columns, types │ │ │ │ │ │── Calculate stats ────────────▶│ │ │ (stats.ts: mean, Cpk, etc.) │ │ │ │ │ │── Render charts ──────────────▶│ │ │ (Visx: I-Chart, Boxplot, │ │ │ Pareto, Capability) │ │ │ │ │ │── User drills down ───────────▶│ │ │ Filter → recalculate → │ │ │ re-render │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The app supports:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>CSV and Excel upload\u003C/strong> — parsed entirely in-browser\u003C/li>\n\u003Cli>\u003Cstrong>Copy-paste\u003C/strong> — paste from spreadsheets, auto-detected via \u003Ccode dir=\"auto\">detectColumns()\u003C/code>, reviewed in ColumnMapping (same flow as PWA, with up to 6 factors)\u003C/li>\n\u003Cli>\u003Cstrong>Manual entry\u003C/strong> — type values directly\u003C/li>\n\u003Cli>\u003Cstrong>Add data during analysis\u003C/strong> — “Add Data” dropdown offers paste, upload, or manual entry. Auto-detects whether to append rows (same columns) or add columns (new columns). Replace confirmation when loading entirely new data.\u003C/li>\n\u003Cli>\u003Cstrong>Performance Mode\u003C/strong> — analyze hundreds of measurement channels simultaneously\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-persistence\">Data Persistence\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-persistence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Persistence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Save is explicit — the user clicks \u003Cstrong>Save\u003C/strong> in the editor header. Unsaved work is lost if the browser tab closes. The storage model depends on the plan:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-plan--local-files\">Standard Plan — Local Files\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-plan--local-files\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Plan — Local Files”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Data stays on the user’s device. No cloud sync, no OneDrive.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">BROWSER USER'S COMPUTER\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">(IndexedDB) (File System Access API)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│── User clicks Save ───────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ IndexedDB + local file │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀── User opens project ─────────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Load from IndexedDB/file │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"BROWSER USER'S COMPUTER(IndexedDB) (File System Access API) │ │ │── User clicks Save ───────────▶│ │ IndexedDB + local file │ │ │ │◀── User opens project ─────────│ │ Load from IndexedDB/file │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cul>\n\u003Cli>Projects saved to IndexedDB with optional local file export via File System Access API\u003C/li>\n\u003Cli>No internet required after initial deployment\u003C/li>\n\u003Cli>Only \u003Ccode dir=\"auto\">User.Read\u003C/code> permission needed\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"team-plan--local-files--cloud-sync\">Team Plan — Local Files + Cloud Sync\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#team-plan--local-files--cloud-sync\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Team Plan — Local Files + Cloud Sync”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Everything in Standard, plus OneDrive personal sync and SharePoint channel storage.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">BROWSER USER'S ONEDRIVE / CHANNEL SHAREPOINT\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">(IndexedDB) (Graph API)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀── Load on startup ────────────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (if online) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│── User saves changes ─────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (debounced write) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│── Offline? ────────────────────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Queue changes locally │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│── Back online ────────────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Flush queued changes │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"BROWSER USER'S ONEDRIVE / CHANNEL SHAREPOINT(IndexedDB) (Graph API) │ │ │◀── Load on startup ────────────│ │ (if online) │ │ │ │── User saves changes ─────────▶│ │ (debounced write) │ │ │ │── Offline? ────────────────────│ │ Queue changes locally │ │ │ │── Back online ────────────────▶│ │ Flush queued changes │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Personal OneDrive\u003C/strong> (personal tab or browser):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">OneDrive/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── VariScout/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Projects/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── analysis-001.vrs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── ...\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"OneDrive/└── VariScout/ └── Projects/ ├── analysis-001.vrs └── ...\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Channel SharePoint\u003C/strong> (channel tab):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Channel Files/VariScout/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Projects/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Feb-Fill-Line.vrs ← shared analysis\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Photos/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── {analysisId}/{findingId}/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── photo-001.jpg ← EXIF-stripped evidence\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Channel Files/VariScout/├── Projects/│ └── Feb-Fill-Line.vrs ← shared analysis└── Photos/ └── {analysisId}/{findingId}/ └── photo-001.jpg ← EXIF-stripped evidence\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Storage location is automatic: channel tab → SharePoint, personal tab → OneDrive, browser → OneDrive.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"offline-behavior\">Offline Behavior\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#offline-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Offline Behavior”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>State\u003C/th>\u003Cth>Standard\u003C/th>\u003Cth>Team\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Online\u003C/td>\u003Ctd>Save to IndexedDB + file\u003C/td>\u003Ctd>+ sync to OneDrive/SharePoint\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Offline\u003C/td>\u003Ctd>Full local functionality\u003C/td>\u003Ctd>Full local functionality\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Reconnect\u003C/td>\u003Ctd>N/A\u003C/td>\u003Ctd>Flush queued changes to cloud\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teams-integration-team-plan\">Teams Integration (Team Plan)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teams-integration-team-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teams Integration (Team Plan)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Team plan adds Microsoft Teams as a collaboration layer. The same codebase detects its runtime context and adapts:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Teams SDK initialized?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Yes → Channel tab? → shared channel SharePoint storage\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ → Personal tab? → personal OneDrive\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ → SSO via On-Behalf-Of token exchange\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── No → Browser mode → local files (File System Access API)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Teams SDK initialized?├── Yes → Channel tab? → shared channel SharePoint storage│ → Personal tab? → personal OneDrive│ → SSO via On-Behalf-Of token exchange└── No → Browser mode → local files (File System Access API)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"authentication-obo-token-exchange\">Authentication: OBO Token Exchange\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#authentication-obo-token-exchange\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Authentication: OBO Token Exchange”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Teams SSO provides a client-side token that isn’t directly usable for Graph API calls. An Azure Function (\u003Ccode dir=\"auto\">token-exchange\u003C/code>) performs the On-Behalf-Of exchange:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Teams Client → SSO token → Azure Function (OBO) → Graph API token\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Fallback: EasyAuth redirect\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Teams Client → SSO token → Azure Function (OBO) → Graph API token ↓ Fallback: EasyAuth redirect\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">graphToken.ts\u003C/code> module handles the chain: Teams SSO → OBO exchange → EasyAuth fallback. The Azure Function is deployed alongside the App Service via ARM template.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"channel-storage\">Channel Storage\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#channel-storage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Channel Storage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When running as a channel tab, analyses and photos are stored in the channel’s SharePoint document library:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">channelDrive.ts\u003C/code> resolves the drive via Graph API: \u003Ccode dir=\"auto\">/teams/{teamId}/channels/{channelId}/filesFolder\u003C/code>\u003C/li>\n\u003Cli>Drive info is cached in IndexedDB to avoid repeated Graph calls\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">StorageLocation\u003C/code> type (\u003Ccode dir=\"auto\">'personal' | 'team'\u003C/code>) routes to the correct storage\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"photo-pipeline\">Photo Pipeline\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#photo-pipeline\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Photo Pipeline”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Photo evidence flows through a client-side pipeline:\u003C/p>\n\u003Col>\n\u003Cli>Camera capture — Teams SDK \u003Ccode dir=\"auto\">media.selectMedia()\u003C/code> inside Teams (native camera, \u003Ccode dir=\"auto\">devicePermissions: [\"media\"]\u003C/code> for IT audit trail), HTML5 file input fallback outside Teams\u003C/li>\n\u003Cli>EXIF/GPS metadata stripped (\u003Ccode dir=\"auto\">exifStrip.ts\u003C/code> — byte-level removal, 23 verification tests) — both capture paths feed into the same pipeline\u003C/li>\n\u003Cli>Upload to OneDrive or SharePoint (\u003Ccode dir=\"auto\">photoUpload.ts\u003C/code>)\u003C/li>\n\u003Cli>Thumbnail embedded in \u003Ccode dir=\"auto\">.vrs\u003C/code> file for cross-user preview\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deep-links-and-sharing\">Deep Links and Sharing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deep-links-and-sharing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deep Links and Sharing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">deepLinks.ts\u003C/code> — builds and parses deep link URLs for specific charts or findings\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useTeamsShare.ts\u003C/code> — wraps Teams SDK \u003Ccode dir=\"auto\">sharing.shareWebContent\u003C/code> and \u003Ccode dir=\"auto\">pages.shareDeepLink\u003C/code>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">shareContent.ts\u003C/code> — builds share payloads for findings and charts\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"user-identity\">User Identity\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#user-identity\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Identity”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">getCurrentUser.ts\u003C/code> extracts user identity from the Teams JWT (UPN claim) with EasyAuth fallback. Author names appear on findings and comments for audit trails.\u003C/p>\n\u003Cp>See \u003Ca href=\"../../07-decisions/adr-016-teams-integration.md\">ADR-016\u003C/a> for the full technical design.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-ownership--security\">Data Ownership & Security\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-ownership--security\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Ownership & Security”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-stays-with-the-customer\">Data Stays with the Customer\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-stays-with-the-customer\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Stays with the Customer”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">CUSTOMER TENANT PUBLISHER (VariScout)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────────────┐ ┌────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ App Service │ │ Marketplace │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (hosts the app) │ ──── NO ───▶ │ listing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ connection │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Azure AD │ │ No access to: │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (authenticates users) │ │ - Customer data │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ - App resources │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ OneDrive/SharePoint │ │ - User identities │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (Team plan sync) │ │ - Usage telemetry │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────────────────┘ └────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"CUSTOMER TENANT PUBLISHER (VariScout)┌────────────────────────┐ ┌────────────────────┐│ │ │ ││ App Service │ │ Marketplace ││ (hosts the app) │ ──── NO ───▶ │ listing ││ │ connection │ ││ Azure AD │ │ No access to: ││ (authenticates users) │ │ - Customer data ││ │ │ - App resources ││ OneDrive/SharePoint │ │ - User identities ││ (Team plan sync) │ │ - Usage telemetry ││ │ │ │└────────────────────────┘ └────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Publisher management is disabled\u003C/strong> — we have zero access to the customer’s deployment\u003C/li>\n\u003Cli>\u003Cstrong>No telemetry\u003C/strong> — the app makes no outbound calls to publisher systems\u003C/li>\n\u003Cli>\u003Cstrong>Data survives cancellation\u003C/strong> — analyses remain on the user’s device (Standard) or in OneDrive/SharePoint (Team) even if the subscription ends\u003C/li>\n\u003Cli>\u003Cstrong>Each deployment is tenant-isolated\u003C/strong> — no cross-tenant data access\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"least-privilege-permissions\">Least-Privilege Permissions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#least-privilege-permissions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Least-Privilege Permissions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Permission\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Plan\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">User.Read\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Display user name & email\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Team only\u003C/td>\u003Ctd>OneDrive + SharePoint file sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>\u003C/td>\u003Ctd>Delegated\u003C/td>\u003Ctd>Team only\u003C/td>\u003Ctd>Resolve channel SharePoint drives\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Standard plan\u003C/strong>: Only \u003Ccode dir=\"auto\">User.Read\u003C/code> — no admin consent required, users consent on first login.\u003C/p>\n\u003Cp>\u003Cstrong>Team plan\u003C/strong>: Requires one-time tenant admin consent for \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> and \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>. No mail access, no \u003Ccode dir=\"auto\">Sites.ReadWrite.All\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"secret-handling\">Secret Handling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#secret-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Secret Handling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>The client secret is passed as ARM \u003Ccode dir=\"auto\">secureString\u003C/code> — never logged or exposed in outputs\u003C/li>\n\u003Cli>Stored as an App Service app setting (server-side, inaccessible to client code)\u003C/li>\n\u003Cli>EasyAuth tokens are stored in the platform token store (not in browser storage)\u003C/li>\n\u003Cli>HTTPS enforced, minimum TLS 1.2, FTP disabled\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"index.md\">Azure App Overview\u003C/a> — product positioning and pricing\u003C/li>\n\u003Cli>\u003Ca href=\"arm-template.md\">ARM Template\u003C/a> — resource definitions and deployment methods\u003C/li>\n\u003Cli>\u003Ca href=\"authentication.md\">Authentication (EasyAuth)\u003C/a> — auth endpoints and client-side helper\u003C/li>\n\u003Cli>\u003Ca href=\"onedrive-sync.md\">OneDrive Sync\u003C/a> — sync flow, conflict resolution, offline behavior\u003C/li>\n\u003Cli>\u003Ca href=\"marketplace.md\">Marketplace Guide\u003C/a> — publishing, certification, listing content\u003C/li>\n\u003C/ul>", + { + "headings": 11592, + "localImagePaths": 11645, + "remoteImagePaths": 11646, + "frontmatter": 11647, + "imagePaths": 11648 + }, + [ + 11593, 11594, 11597, 11600, 11603, 11606, 11609, 11612, 11613, 11616, 11619, 11622, 11625, + 11628, 11631, 11632, 11633, 11634, 11637, 11640, 11643, 11644 + ], + { "depth": 30, "slug": 1173, "text": 1174 }, + { "depth": 33, "slug": 11595, "text": 11596 }, + "what-gets-deployed", + "What Gets Deployed", + { "depth": 33, "slug": 11598, "text": 11599 }, + "deployment-flow", + "Deployment Flow", + { "depth": 79, "slug": 11601, "text": 11602 }, + "pre-requisite-app-registration", + "Pre-requisite: App Registration", + { "depth": 33, "slug": 11604, "text": 11605 }, + "first-login", + "First Login", + { "depth": 79, "slug": 11607, "text": 11608 }, + "easyauth-endpoints", + "EasyAuth Endpoints", + { "depth": 33, "slug": 11610, "text": 11611 }, + "using-the-app", + "Using the App", + { "depth": 33, "slug": 4455, "text": 4456 }, + { "depth": 79, "slug": 11614, "text": 11615 }, + "standard-plan--local-files", + "Standard Plan — Local Files", + { "depth": 79, "slug": 11617, "text": 11618 }, + "team-plan--local-files--cloud-sync", + "Team Plan — Local Files + Cloud Sync", + { "depth": 79, "slug": 11620, "text": 11621 }, + "offline-behavior", + "Offline Behavior", + { "depth": 33, "slug": 11623, "text": 11624 }, + "teams-integration-team-plan", + "Teams Integration (Team Plan)", + { "depth": 79, "slug": 11626, "text": 11627 }, + "authentication-obo-token-exchange", + "Authentication: OBO Token Exchange", + { "depth": 79, "slug": 11629, "text": 11630 }, + "channel-storage", + "Channel Storage", + { "depth": 79, "slug": 1589, "text": 1590 }, + { "depth": 79, "slug": 1592, "text": 1593 }, + { "depth": 79, "slug": 1595, "text": 1596 }, + { "depth": 33, "slug": 11635, "text": 11636 }, + "data-ownership--security", + "Data Ownership & Security", + { "depth": 79, "slug": 11638, "text": 11639 }, + "data-stays-with-the-customer", + "Data Stays with the Customer", + { "depth": 79, "slug": 11641, "text": 11642 }, + "least-privilege-permissions", + "Least-Privilege Permissions", + { "depth": 79, "slug": 11436, "text": 11437 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 1174 }, + [], + "08-products/azure", + { + "id": 11649, + "data": 11651, + "body": 11656, + "filePath": 11657, + "digest": 11658, + "rendered": 11659 + }, + { + "title": 11652, + "editUrl": 16, + "head": 11653, + "template": 18, + "sidebar": 11654, + "pagefind": 16, + "draft": 20 + }, + "Azure App (Primary Product)", + [], + { "hidden": 20, "attrs": 11655 }, + {}, + "# Azure App (Primary Product)\n\nVariScout for Microsoft 365 enterprises - the only paid product, distributed via Azure Marketplace as a Managed Application.\n\n---\n\n## Overview\n\nThe Azure App is the **only paid VariScout product**, available in two plans:\n\n- **Standard (€99/month)**: Full analysis features, local file storage, EasyAuth SSO\n- **Team (€299/month)**: Everything in Standard + OneDrive/SharePoint sync, Teams integration, channel storage, photo capture\n\nBoth plans include all chart types, Performance Mode, and customer-controlled data (stays in their Azure tenant).\n\n**No backend required** - deploys entirely to the customer's Azure tenant.\n\n---\n\n## Distribution\n\nVariScout Azure App is available on **Azure Marketplace** as a Managed Application:\n\n| Aspect | Value |\n| ---------------- | --------------------------------------------------------------------- |\n| Offer type | Managed Application |\n| Price | €99/month (Standard) or €299/month (Team) |\n| Plans | Standard (local files) or Team (+ OneDrive/SharePoint, Teams, photos) |\n| Billing | Monthly (Microsoft, 3% fee) |\n| Publisher access | Disabled (zero access to customer resources) |\n| Customer access | Full control |\n\nBoth plans include:\n\n- All chart types and analysis features\n- Performance Mode (multi-channel Cpk analysis)\n- Microsoft Entra ID SSO (EasyAuth)\n- Offline support (cached)\n- Data stays in customer's Azure tenant\n\nTeam plan adds:\n\n- Teams SDK integration (channel tabs, SSO)\n- OneDrive/SharePoint analysis sync\n- Channel storage for shared projects\n- Photo capture with EXIF stripping (Teams SDK native camera + HTML5 fallback)\n\n**Billing**: Handled by Microsoft (3% fee). Supports enterprise procurement with purchase orders and invoicing.\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│ CUSTOMER AZURE TENANT │\n├─────────────────────────────────────────────────────────────────┤\n│ │\n│ ┌───────────────────────────────────────────────────────────┐ │\n│ │ AZURE APP SERVICE │ │\n│ │ (Deployed via Managed Application) │ │\n│ │ (WEBSITE_RUN_FROM_PACKAGE — static zip) │ │\n│ │ │ │\n│ │ ┌─────────────────────────────────────────────────────┐ │ │\n│ │ │ VARISCOUT AZURE APP │ │ │\n│ │ │ React SPA + EasyAuth + OneDrive (Team plan) │ │ │\n│ │ └─────────────────────────────────────────────────────┘ │ │\n│ │ │ │\n│ │ ┌─────────────────────────────────────────────────────┐ │ │\n│ │ │ EASYAUTH (authsettingsV2) │ │ │\n│ │ │ Platform-level Azure AD authentication │ │ │\n│ │ │ Token store for Graph API access │ │ │\n│ │ └─────────────────────────────────────────────────────┘ │ │\n│ └───────────────────────────────────────────────────────────┘ │\n│ │ │\n│ ▼ │\n│ ┌───────────────────────────────────────────────────────────┐ │\n│ │ MICROSOFT ENTRA ID │ │\n│ │ (Customer-provided App Registration) │ │\n│ └───────────────────────────────────────────────────────────┘ │\n│ │ │\n│ ▼ │\n│ ┌───────────────────────────────────────────────────────────┐ │\n│ │ ONEDRIVE (Team plan only) │ │\n│ │ (Analysis sync via Graph API) │ │\n│ └───────────────────────────────────────────────────────────┘ │\n│ │\n└─────────────────────────────────────────────────────────────────┘\n\n ↑\n │ No data leaves customer tenant\n │ No external API calls\n │ No backend servers\n │ Publisher management DISABLED\n ↓\n\n┌─────────────────────────────────────────────────────────────────┐\n│ VARISCOUT (Publisher) │\n│ │\n│ • Azure Marketplace listing │\n│ • Managed Application package distribution │\n│ • Documentation & support │\n│ • No access to customer data or resources │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Key Benefits\n\n### No Backend Required\n\nUnlike traditional SaaS, VariScout Azure App:\n\n- Deploys entirely to customer's Azure tenant\n- Processes all data in-browser\n- Stores analyses locally (Standard) or in customer's OneDrive (Team)\n- Makes zero calls to external servers\n\nThis architecture ensures:\n\n- **Compliance**: Data never leaves the customer's environment\n- **Simplicity**: No backend infrastructure for us to maintain\n- **Security**: Customer controls all access and data\n\n### Microsoft-Integrated Billing\n\n| Feature | Benefit |\n| ----------------- | ----------------------------------------- |\n| Azure Marketplace | Enterprise buyers trust Microsoft |\n| Microsoft billing | Integrates with existing Azure agreements |\n| Purchase orders | Enterprise procurement support |\n| VAT handling | Microsoft handles international tax |\n\n### Tier Configuration\n\nAll Managed Application deployments get full analysis features. The plan determines collaboration capabilities:\n\n```typescript\n// Tier: always enterprise for Managed App deployments\nconst tier = import.meta.env.VITE_LICENSE_TIER; // Always 'enterprise'\n\n// Plan: determines storage and collaboration features\nconst plan = import.meta.env.VARISCOUT_PLAN; // 'standard' or 'team'\n```\n\n---\n\n## Features\n\n| Feature | Plan | Description |\n| ---------------- | ---- | ------------------------------------------------------------ |\n| SSO | Both | Microsoft Entra ID via EasyAuth |\n| Cloud Sync | Team | Analyses saved to OneDrive |\n| Sharing | Team | Share analyses with team members via OneDrive/SharePoint |\n| Offline | Both | Cached locally; Team plan syncs when online |\n| All Chart Types | Both | I-Chart, Boxplot, Pareto, Capability, etc. |\n| Performance Mode | Both | Multi-channel Cpk analysis |\n| Presentation | Both | Full-screen chart overview + focused single-chart navigation |\n| Drill-Down | Both | Interactive filter navigation |\n\n---\n\n## Teams Integration\n\nThe Team plan includes Microsoft Teams SDK integration, enabling VariScout to run as a Teams channel tab with silent SSO via the On-Behalf-Of (OBO) flow. Channel tabs store projects in the channel's SharePoint document library, and users can capture photos directly from the shop floor with automatic EXIF/GPS stripping. See [ADR-016: Teams Integration](../../07-decisions/adr-016-teams-integration.md) for the full technical design.\n\n---\n\n## Deployment\n\nOne-click deployment from Azure Marketplace:\n\n1. **Find** VariScout on Azure Marketplace\n2. **Click** \"Create\"\n3. **Configure** app name and region\n4. **Deploy** to your Azure subscription (managed resource group)\n5. **Access** at your custom Azure URL\n\n### Manual Deployment (ARM Template)\n\nFor development/testing, deploy directly with Azure CLI:\n\n```bash\naz deployment group create \\\n --resource-group rg-variscout \\\n --template-file infra/mainTemplate.json\n```\n\nSee [ARM Template Documentation](arm-template.md) for details.\n\n### Staging (CI/CD)\n\nFor development and validation, a staging environment is deployed automatically:\n\n- **URL**: `https://variscout-staging.azurewebsites.net`\n- **Trigger**: Push to `main` (path-filtered) or manual `workflow_dispatch`\n- **Auth**: GitHub OIDC → Azure (no stored credentials)\n\nSee [Deployment Guide](../../05-technical/implementation/deployment.md) for pipeline details.\n\n---\n\n## Data Location\n\nAll data stays in the customer's tenant:\n\n| Data Type | Standard | Team |\n| -------------- | ---------------------------- | ----------------------------------------- |\n| App hosting | Customer's Azure App Service | Customer's Azure App Service |\n| Analyses | Local files (browser) | OneDrive (personal) or channel SharePoint |\n| Photos | N/A | Channel SharePoint (`Photos/` folder) |\n| Settings | Browser localStorage | Browser localStorage |\n| Authentication | Customer's Entra ID | Customer's Entra ID (+ Teams SSO) |\n\n**No data sent to VariScout servers.**\n\n---\n\n## Development Tools\n\n### DevTierSwitcher\n\nThe Azure app includes a development-only tier switching component at `apps/azure/src/components/DevTierSwitcher.tsx`:\n\n- Fixed-position panel to quickly switch between tiers during development\n- Only renders when `import.meta.env.DEV === true`\n- Persists tier override in `localStorage`\n- Triggers page reload to reinitialize all tier-dependent state\n\n---\n\n## See Also\n\n- [How It Works](how-it-works.md) — end-to-end architecture guide\n- [Azure Marketplace Guide](marketplace.md)\n- [Pricing](pricing-tiers.md)\n- [ARM Template](arm-template.md)\n- [Authentication (EasyAuth)](authentication.md)\n- [OneDrive Sync](onedrive-sync.md)\n- [Storage](storage.md) — IndexedDB schema, sync queue, persistence model\n- [Submission Checklist](submission-checklist.md) — Marketplace submission preparation\n- [ADR-007: Azure Marketplace Distribution](../../07-decisions/adr-007-azure-marketplace-distribution.md)\n- [ADR-016: Teams Integration](../../07-decisions/adr-016-teams-integration.md)\n- [ADR-016: Security Evaluation](../../07-decisions/adr-016-security-evaluation.md)", + "src/content/docs/08-products/azure/index.md", + "c0f521e1400077ea", + { "html": 11660, "metadata": 11661 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"azure-app-primary-product\">Azure App (Primary Product)\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-primary-product\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App (Primary Product)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout for Microsoft 365 enterprises - the only paid product, distributed via Azure Marketplace as a Managed Application.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure App is the \u003Cstrong>only paid VariScout product\u003C/strong>, available in two plans:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Standard (€99/month)\u003C/strong>: Full analysis features, local file storage, EasyAuth SSO\u003C/li>\n\u003Cli>\u003Cstrong>Team (€299/month)\u003C/strong>: Everything in Standard + OneDrive/SharePoint sync, Teams integration, channel storage, photo capture\u003C/li>\n\u003C/ul>\n\u003Cp>Both plans include all chart types, Performance Mode, and customer-controlled data (stays in their Azure tenant).\u003C/p>\n\u003Cp>\u003Cstrong>No backend required\u003C/strong> - deploys entirely to the customer’s Azure tenant.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"distribution\">Distribution\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#distribution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Distribution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout Azure App is available on \u003Cstrong>Azure Marketplace\u003C/strong> as a Managed Application:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Aspect\u003C/th>\u003Cth>Value\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Offer type\u003C/td>\u003Ctd>Managed Application\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Price\u003C/td>\u003Ctd>€99/month (Standard) or €299/month (Team)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Plans\u003C/td>\u003Ctd>Standard (local files) or Team (+ OneDrive/SharePoint, Teams, photos)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Billing\u003C/td>\u003Ctd>Monthly (Microsoft, 3% fee)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Publisher access\u003C/td>\u003Ctd>Disabled (zero access to customer resources)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Customer access\u003C/td>\u003Ctd>Full control\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Both plans include:\u003C/p>\n\u003Cul>\n\u003Cli>All chart types and analysis features\u003C/li>\n\u003Cli>Performance Mode (multi-channel Cpk analysis)\u003C/li>\n\u003Cli>Microsoft Entra ID SSO (EasyAuth)\u003C/li>\n\u003Cli>Offline support (cached)\u003C/li>\n\u003Cli>Data stays in customer’s Azure tenant\u003C/li>\n\u003C/ul>\n\u003Cp>Team plan adds:\u003C/p>\n\u003Cul>\n\u003Cli>Teams SDK integration (channel tabs, SSO)\u003C/li>\n\u003Cli>OneDrive/SharePoint analysis sync\u003C/li>\n\u003Cli>Channel storage for shared projects\u003C/li>\n\u003Cli>Photo capture with EXIF stripping (Teams SDK native camera + HTML5 fallback)\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Billing\u003C/strong>: Handled by Microsoft (3% fee). Supports enterprise procurement with purchase orders and invoicing.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"architecture\">Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ CUSTOMER AZURE TENANT │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌───────────────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ AZURE APP SERVICE │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ (Deployed via Managed Application) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ (WEBSITE_RUN_FROM_PACKAGE — static zip) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ┌─────────────────────────────────────────────────────┐ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ VARISCOUT AZURE APP │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ React SPA + EasyAuth + OneDrive (Team plan) │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └─────────────────────────────────────────────────────┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ┌─────────────────────────────────────────────────────┐ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ EASYAUTH (authsettingsV2) │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ Platform-level Azure AD authentication │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ Token store for Graph API access │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ └─────────────────────────────────────────────────────┘ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────────────────────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▼ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌───────────────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ MICROSOFT ENTRA ID │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ (Customer-provided App Registration) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────────────────────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ▼ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌───────────────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ ONEDRIVE (Team plan only) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ (Analysis sync via Graph API) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └───────────────────────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↑\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ No data leaves customer tenant\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ No external API calls\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ No backend servers\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Publisher management DISABLED\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↓\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ VARISCOUT (Publisher) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • Azure Marketplace listing │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • Managed Application package distribution │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • Documentation & support │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ • No access to customer data or resources │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────┐│ CUSTOMER AZURE TENANT │├─────────────────────────────────────────────────────────────────┤│ ││ ┌───────────────────────────────────────────────────────────┐ ││ │ AZURE APP SERVICE │ ││ │ (Deployed via Managed Application) │ ││ │ (WEBSITE_RUN_FROM_PACKAGE — static zip) │ ││ │ │ ││ │ ┌─────────────────────────────────────────────────────┐ │ ││ │ │ VARISCOUT AZURE APP │ │ ││ │ │ React SPA + EasyAuth + OneDrive (Team plan) │ │ ││ │ └─────────────────────────────────────────────────────┘ │ ││ │ │ ││ │ ┌─────────────────────────────────────────────────────┐ │ ││ │ │ EASYAUTH (authsettingsV2) │ │ ││ │ │ Platform-level Azure AD authentication │ │ ││ │ │ Token store for Graph API access │ │ ││ │ └─────────────────────────────────────────────────────┘ │ ││ └───────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌───────────────────────────────────────────────────────────┐ ││ │ MICROSOFT ENTRA ID │ ││ │ (Customer-provided App Registration) │ ││ └───────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌───────────────────────────────────────────────────────────┐ ││ │ ONEDRIVE (Team plan only) │ ││ │ (Analysis sync via Graph API) │ ││ └───────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘ ↑ │ No data leaves customer tenant │ No external API calls │ No backend servers │ Publisher management DISABLED ↓┌─────────────────────────────────────────────────────────────────┐│ VARISCOUT (Publisher) ││ ││ • Azure Marketplace listing ││ • Managed Application package distribution ││ • Documentation & support ││ • No access to customer data or resources │└─────────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"key-benefits\">Key Benefits\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#key-benefits\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Key Benefits”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"no-backend-required\">No Backend Required\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#no-backend-required\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “No Backend Required”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Unlike traditional SaaS, VariScout Azure App:\u003C/p>\n\u003Cul>\n\u003Cli>Deploys entirely to customer’s Azure tenant\u003C/li>\n\u003Cli>Processes all data in-browser\u003C/li>\n\u003Cli>Stores analyses locally (Standard) or in customer’s OneDrive (Team)\u003C/li>\n\u003Cli>Makes zero calls to external servers\u003C/li>\n\u003C/ul>\n\u003Cp>This architecture ensures:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Compliance\u003C/strong>: Data never leaves the customer’s environment\u003C/li>\n\u003Cli>\u003Cstrong>Simplicity\u003C/strong>: No backend infrastructure for us to maintain\u003C/li>\n\u003Cli>\u003Cstrong>Security\u003C/strong>: Customer controls all access and data\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"microsoft-integrated-billing\">Microsoft-Integrated Billing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#microsoft-integrated-billing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Microsoft-Integrated Billing”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Benefit\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Azure Marketplace\u003C/td>\u003Ctd>Enterprise buyers trust Microsoft\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Microsoft billing\u003C/td>\u003Ctd>Integrates with existing Azure agreements\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Purchase orders\u003C/td>\u003Ctd>Enterprise procurement support\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>VAT handling\u003C/td>\u003Ctd>Microsoft handles international tax\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tier-configuration\">Tier Configuration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tier-configuration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tier Configuration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All Managed Application deployments get full analysis features. The plan determines collaboration capabilities:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Tier: always enterprise for Managed App deployments\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">tier\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = import.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">meta\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">env\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VITE_LICENSE_TIER\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Always 'enterprise'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Plan: determines storage and collaboration features\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">plan\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = import.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">meta\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">env\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">VARISCOUT_PLAN\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 'standard' or 'team'\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Tier: always enterprise for Managed App deploymentsconst tier = import.meta.env.VITE_LICENSE_TIER; // Always 'enterprise'// Plan: determines storage and collaboration featuresconst plan = import.meta.env.VARISCOUT_PLAN; // 'standard' or 'team'\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"features\">Features\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Features”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Plan\u003C/th>\u003Cth>Description\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>SSO\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Microsoft Entra ID via EasyAuth\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cloud Sync\u003C/td>\u003Ctd>Team\u003C/td>\u003Ctd>Analyses saved to OneDrive\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sharing\u003C/td>\u003Ctd>Team\u003C/td>\u003Ctd>Share analyses with team members via OneDrive/SharePoint\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Offline\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Cached locally; Team plan syncs when online\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>All Chart Types\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>I-Chart, Boxplot, Pareto, Capability, etc.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Multi-channel Cpk analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Presentation\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Full-screen chart overview + focused single-chart navigation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Drill-Down\u003C/td>\u003Ctd>Both\u003C/td>\u003Ctd>Interactive filter navigation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"teams-integration\">Teams Integration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#teams-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Teams Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Team plan includes Microsoft Teams SDK integration, enabling VariScout to run as a Teams channel tab with silent SSO via the On-Behalf-Of (OBO) flow. Channel tabs store projects in the channel’s SharePoint document library, and users can capture photos directly from the shop floor with automatic EXIF/GPS stripping. See \u003Ca href=\"../../07-decisions/adr-016-teams-integration.md\">ADR-016: Teams Integration\u003C/a> for the full technical design.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"deployment\">Deployment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#deployment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>One-click deployment from Azure Marketplace:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Find\u003C/strong> VariScout on Azure Marketplace\u003C/li>\n\u003Cli>\u003Cstrong>Click\u003C/strong> “Create”\u003C/li>\n\u003Cli>\u003Cstrong>Configure\u003C/strong> app name and region\u003C/li>\n\u003Cli>\u003Cstrong>Deploy\u003C/strong> to your Azure subscription (managed resource group)\u003C/li>\n\u003Cli>\u003Cstrong>Access\u003C/strong> at your custom Azure URL\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"manual-deployment-arm-template\">Manual Deployment (ARM Template)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#manual-deployment-arm-template\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Manual Deployment (ARM Template)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For development/testing, deploy directly with Azure CLI:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">az\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">deployment\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">create\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--resource-group\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">rg-variscout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">\\\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--template-file\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">infra/mainTemplate.json\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"az deployment group create \\ --resource-group rg-variscout \\ --template-file infra/mainTemplate.json\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>See \u003Ca href=\"arm-template.md\">ARM Template Documentation\u003C/a> for details.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"staging-cicd\">Staging (CI/CD)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#staging-cicd\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Staging (CI/CD)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For development and validation, a staging environment is deployed automatically:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>URL\u003C/strong>: \u003Ccode dir=\"auto\">https://variscout-staging.azurewebsites.net\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Trigger\u003C/strong>: Push to \u003Ccode dir=\"auto\">main\u003C/code> (path-filtered) or manual \u003Ccode dir=\"auto\">workflow_dispatch\u003C/code>\u003C/li>\n\u003Cli>\u003Cstrong>Auth\u003C/strong>: GitHub OIDC → Azure (no stored credentials)\u003C/li>\n\u003C/ul>\n\u003Cp>See \u003Ca href=\"../../05-technical/implementation/deployment.md\">Deployment Guide\u003C/a> for pipeline details.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-location\">Data Location\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-location\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Location”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All data stays in the customer’s tenant:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Data Type\u003C/th>\u003Cth>Standard\u003C/th>\u003Cth>Team\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>App hosting\u003C/td>\u003Ctd>Customer’s Azure App Service\u003C/td>\u003Ctd>Customer’s Azure App Service\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analyses\u003C/td>\u003Ctd>Local files (browser)\u003C/td>\u003Ctd>OneDrive (personal) or channel SharePoint\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Photos\u003C/td>\u003Ctd>N/A\u003C/td>\u003Ctd>Channel SharePoint (\u003Ccode dir=\"auto\">Photos/\u003C/code> folder)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Settings\u003C/td>\u003Ctd>Browser localStorage\u003C/td>\u003Ctd>Browser localStorage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Authentication\u003C/td>\u003Ctd>Customer’s Entra ID\u003C/td>\u003Ctd>Customer’s Entra ID (+ Teams SSO)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>No data sent to VariScout servers.\u003C/strong>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"development-tools\">Development Tools\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#development-tools\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Development Tools”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"devtierswitcher\">DevTierSwitcher\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#devtierswitcher\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “DevTierSwitcher”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Azure app includes a development-only tier switching component at \u003Ccode dir=\"auto\">apps/azure/src/components/DevTierSwitcher.tsx\u003C/code>:\u003C/p>\n\u003Cul>\n\u003Cli>Fixed-position panel to quickly switch between tiers during development\u003C/li>\n\u003Cli>Only renders when \u003Ccode dir=\"auto\">import.meta.env.DEV === true\u003C/code>\u003C/li>\n\u003Cli>Persists tier override in \u003Ccode dir=\"auto\">localStorage\u003C/code>\u003C/li>\n\u003Cli>Triggers page reload to reinitialize all tier-dependent state\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"how-it-works.md\">How It Works\u003C/a> — end-to-end architecture guide\u003C/li>\n\u003Cli>\u003Ca href=\"marketplace.md\">Azure Marketplace Guide\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"pricing-tiers.md\">Pricing\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"arm-template.md\">ARM Template\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"authentication.md\">Authentication (EasyAuth)\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"onedrive-sync.md\">OneDrive Sync\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"storage.md\">Storage\u003C/a> — IndexedDB schema, sync queue, persistence model\u003C/li>\n\u003Cli>\u003Ca href=\"submission-checklist.md\">Submission Checklist\u003C/a> — Marketplace submission preparation\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007: Azure Marketplace Distribution\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-016-teams-integration.md\">ADR-016: Teams Integration\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-016-security-evaluation.md\">ADR-016: Security Evaluation\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 11662, + "localImagePaths": 11703, + "remoteImagePaths": 11704, + "frontmatter": 11705, + "imagePaths": 11706 + }, + [ + 11663, 11665, 11666, 11669, 11670, 11673, 11676, 11679, 11682, 11683, 11684, 11687, 11690, + 11693, 11696, 11699, 11702 + ], + { "depth": 30, "slug": 11664, "text": 11652 }, + "azure-app-primary-product", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 11667, "text": 11668 }, + "distribution", + "Distribution", + { "depth": 33, "slug": 1819, "text": 1820 }, + { "depth": 33, "slug": 11671, "text": 11672 }, + "key-benefits", + "Key Benefits", + { "depth": 79, "slug": 11674, "text": 11675 }, + "no-backend-required", + "No Backend Required", + { "depth": 79, "slug": 11677, "text": 11678 }, + "microsoft-integrated-billing", + "Microsoft-Integrated Billing", + { "depth": 79, "slug": 11680, "text": 11681 }, + "tier-configuration", + "Tier Configuration", + { "depth": 33, "slug": 1082, "text": 1070 }, + { "depth": 33, "slug": 2055, "text": 2056 }, + { "depth": 33, "slug": 11685, "text": 11686 }, + "deployment", + "Deployment", + { "depth": 79, "slug": 11688, "text": 11689 }, + "manual-deployment-arm-template", + "Manual Deployment (ARM Template)", + { "depth": 79, "slug": 11691, "text": 11692 }, + "staging-cicd", + "Staging (CI/CD)", + { "depth": 33, "slug": 11694, "text": 11695 }, + "data-location", + "Data Location", + { "depth": 33, "slug": 11697, "text": 11698 }, + "development-tools", + "Development Tools", + { "depth": 79, "slug": 11700, "text": 11701 }, + "devtierswitcher", + "DevTierSwitcher", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11652 }, + [], + "08-products/azure/marketplace", + { + "id": 11707, + "data": 11709, + "body": 11714, + "filePath": 11715, + "digest": 11716, + "rendered": 11717 + }, + { + "title": 11710, + "editUrl": 16, + "head": 11711, + "template": 18, + "sidebar": 11712, + "pagefind": 16, + "draft": 20 + }, + "Azure Marketplace Guide", + [], + { "hidden": 20, "attrs": 11713 }, + {}, + "# Azure Marketplace Guide\n\nHow to publish and manage VariScout on Azure Marketplace.\n\n---\n\n## Overview\n\nAzure Marketplace is Microsoft's enterprise application store. Publishing VariScout here provides:\n\n- Access to millions of Azure customers\n- Microsoft-handled billing and invoicing\n- Enterprise procurement integration\n- Trust signal from Microsoft certification\n\n---\n\n## Prerequisites\n\n### Partner Center Account\n\n1. Register at [Partner Center](https://partner.microsoft.com/)\n2. Complete publisher profile\n3. Verify bank account for payouts\n4. Accept marketplace agreements\n\n### Technical Requirements\n\n| Requirement | Status |\n| ------------------------------------- | -------- |\n| Azure App Service | Required |\n| ARM template (mainTemplate.json) | Required |\n| EasyAuth (App Service Authentication) | Required |\n| Privacy policy URL | Required |\n| Terms of service URL | Required |\n| Support URL | Required |\n\n---\n\n## Offer Type\n\n### Managed Application (Required for Billing)\n\nVariScout uses the **Managed Application** offer type:\n\n```\nAzure Application > Managed Application\n├── Deploys ARM template to customer subscription (managed RG)\n├── Customer has full access to deployed resources\n├── Publisher management DISABLED (zero access)\n├── Microsoft handles billing (3% fee)\n└── Two plans: Standard €99/month, Team €299/month\n```\n\n**Why Managed Application (not Solution Template):**\n\n- **Solution Templates are not transactable** — Microsoft will not bill customers for them\n- Managed Applications support Microsoft-billed monthly subscriptions\n- Customer still controls their deployment (publisher access disabled)\n- Data stays in customer environment\n- No backend needed\n\n**Permission configuration:**\n\n| Setting | Value | Notes |\n| -------------------- | ------------ | ----------------------------------------- |\n| Publisher Management | **Disabled** | No publisher access to customer resources |\n| Customer Access | **Enabled** | Full customer control |\n\nThese settings are **immutable after publishing**.\n\n### Deployment Package\n\nPartner Center requires a `.zip` package for Managed Application offers:\n\n```\nvariscout-managed-app.zip\n├── mainTemplate.json # ARM template for resources\n└── createUiDefinition.json # Azure portal deployment wizard UI\n```\n\nSee [ARM Template Documentation](arm-template.md) for the full template.\n\n---\n\n## Pricing Configuration\n\n### Two Plans\n\n| Plan ID | Display Name | Price (EUR) | Billing |\n| ---------- | ------------------ | ----------- | ------- |\n| `standard` | VariScout Standard | €99 | Monthly |\n| `team` | VariScout Team | €299 | Monthly |\n\n### Price Breakdown\n\n```\nStandard: €99/month → Net €96.03/month (€1,152/year)\nTeam: €299/month → Net €290.03/month (€3,480/year)\nMicrosoft Fee: 3% on each plan\n```\n\n### Regional Pricing\n\nPartner Center supports per-region pricing. Recommended approach:\n\n- **EUR zone**: €99 / €299 per month\n- **USD zone**: $109 / $329 per month\n- **GBP zone**: £85 / £255 per month\n\nMicrosoft handles currency conversion and VAT.\n\n---\n\n## Listing Content\n\n### Offer Name\n\n```\nVariScout - Statistical Process Control for Quality Teams\n```\n\n### Short Description (100 chars)\n\n```\nOffline-first variation analysis with I-Charts, Boxplots, Pareto, and process capability analysis.\n```\n\n### Long Description (3000 chars)\n\n```markdown\n**VariScout** is a variation analysis tool designed for quality professionals\nwho need to understand process variation without complex setup or cloud dependencies.\n\n### Key Features\n\n**Four Lenses of Variation Analysis**\n\n- Change: I-Charts with Nelson Rules for process stability\n- Failure: Capability analysis (Cp/Cpk) against specifications\n- Flow: Pareto charts for prioritizing improvement efforts\n- Value: Boxplot comparisons across categories\n\n**Performance Mode**\nAnalyze hundreds of measurement channels simultaneously:\n\n- Multi-channel capability tracking (Cpk)\n- Worst-first Pareto ranking\n- Interactive drill-down to individual channels\n\n**No Backend Required**\n\n- Deploys entirely to your Azure tenant\n- Standard: Data stored locally in browser. Team: Syncs to your OneDrive\n- Zero external API calls\n- Full offline support after initial load\n\n### Who Is It For?\n\n- Quality engineers analyzing production data\n- Manufacturing teams tracking process capability\n- Consultants conducting capability assessments\n- Students learning statistical quality control\n\n### Pricing\n\n**Standard — €99/month** — Full analysis, unlimited users in your tenant.\n**Team — €299/month** — Everything in Standard, plus Teams, OneDrive, SharePoint, mobile, and photo evidence.\n\n### Integration\n\nTry the FREE VariScout Web App for training and learning SPC fundamentals\nbefore upgrading to the full Azure App for team use.\n```\n\n### Screenshots (Required: 5-10)\n\n1. Performance Dashboard - Multi-channel capability overview\n2. I-Chart - Control chart with Nelson Rules\n3. Capability Histogram - Cp/Cpk analysis\n4. Boxplot Comparison - Category comparison\n5. Pareto Chart - Improvement prioritization\n6. Drill-Down Navigation - Filter breadcrumbs\n7. OneDrive Sync - Analysis saving (Team plan)\n\n### Videos (Optional but Recommended)\n\n- Product overview (2-3 min)\n- Quick start tutorial\n- Feature highlights\n\n---\n\n## Technical Configuration\n\n### Plan Visibility\n\n| Plan | Visibility | Audience |\n| -------- | ---------- | ------------------- |\n| Standard | Public | All Azure customers |\n| Team | Public | All Azure customers |\n\n---\n\n## Certification Process\n\n### Pre-Submission Checklist\n\n- [ ] Deployment package (.zip) validates successfully\n- [ ] mainTemplate.json passes ARM TTK validation\n- [ ] createUiDefinition.json renders correctly in sandbox\n- [ ] App deploys without errors from marketplace flow\n- [ ] EasyAuth authentication works post-deployment\n- [ ] OneDrive sync works (save/load analyses) — Team plan only\n- [ ] Privacy policy URL accessible\n- [ ] Terms of service URL accessible\n- [ ] Support contact information complete\n- [ ] All screenshots meet requirements (1280x720 min)\n- [ ] Video links work (if included)\n\n### Microsoft Review (~5-10 business days)\n\n1. **Automated validation**: Template syntax, resource definitions, package structure\n2. **Manual review**: Listing content, pricing, policies\n3. **Security scan**: Vulnerability assessment\n4. **Functionality test**: Deployment verification via marketplace flow\n\n### Common Rejection Reasons\n\n| Issue | Fix |\n| -------------------------- | -------------------------------------- |\n| Invalid ARM template | Validate with ARM TTK and Azure CLI |\n| Invalid createUiDefinition | Test in sandbox portal |\n| Missing privacy policy | Add public URL to listing |\n| Screenshot quality | Minimum 1280x720, PNG format |\n| Description too short | Expand feature descriptions |\n| Support contact incomplete | Add email and response time commitment |\n\n---\n\n## Post-Publication\n\n### Monitoring\n\n- Partner Center Analytics for sales data\n- Customer deployment telemetry (anonymous)\n- Support ticket tracking\n\n### Updates\n\n1. Update deployment package (.zip)\n2. Submit for re-certification\n3. Typically 2-3 day review for updates\n\n### Customer Support\n\n| Response Time | Channel |\n| ------------- | ------- |\n| 24 hours | Email |\n\n---\n\n## See Also\n\n- [How It Works](how-it-works.md) — end-to-end architecture guide\n- [Pricing Tiers](pricing-tiers.md)\n- [ARM Template](arm-template.md)\n- [Authentication](authentication.md)\n- [Partner Center Documentation](https://docs.microsoft.com/partner-center/)", + "src/content/docs/08-products/azure/marketplace.md", + "263a40bed122878c", + { "html": 11718, "metadata": 11719 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"azure-marketplace-guide\">Azure Marketplace Guide\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#azure-marketplace-guide\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Marketplace Guide”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>How to publish and manage VariScout on Azure Marketplace.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Azure Marketplace is Microsoft’s enterprise application store. Publishing VariScout here provides:\u003C/p>\n\u003Cul>\n\u003Cli>Access to millions of Azure customers\u003C/li>\n\u003Cli>Microsoft-handled billing and invoicing\u003C/li>\n\u003Cli>Enterprise procurement integration\u003C/li>\n\u003Cli>Trust signal from Microsoft certification\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"prerequisites\">Prerequisites\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#prerequisites\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Prerequisites”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"partner-center-account\">Partner Center Account\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#partner-center-account\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Partner Center Account”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Register at \u003Ca href=\"https://partner.microsoft.com/\">Partner Center\u003C/a>\u003C/li>\n\u003Cli>Complete publisher profile\u003C/li>\n\u003Cli>Verify bank account for payouts\u003C/li>\n\u003Cli>Accept marketplace agreements\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"technical-requirements\">Technical Requirements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#technical-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Requirements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Requirement\u003C/th>\u003Cth>Status\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Azure App Service\u003C/td>\u003Ctd>Required\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ARM template (mainTemplate.json)\u003C/td>\u003Ctd>Required\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>EasyAuth (App Service Authentication)\u003C/td>\u003Ctd>Required\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Privacy policy URL\u003C/td>\u003Ctd>Required\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Terms of service URL\u003C/td>\u003Ctd>Required\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Support URL\u003C/td>\u003Ctd>Required\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"offer-type\">Offer Type\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#offer-type\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Offer Type”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"managed-application-required-for-billing\">Managed Application (Required for Billing)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#managed-application-required-for-billing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Managed Application (Required for Billing)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout uses the \u003Cstrong>Managed Application\u003C/strong> offer type:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Azure Application > Managed Application\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Deploys ARM template to customer subscription (managed RG)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Customer has full access to deployed resources\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Publisher management DISABLED (zero access)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Microsoft handles billing (3% fee)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Two plans: Standard €99/month, Team €299/month\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Azure Application > Managed Application├── Deploys ARM template to customer subscription (managed RG)├── Customer has full access to deployed resources├── Publisher management DISABLED (zero access)├── Microsoft handles billing (3% fee)└── Two plans: Standard €99/month, Team €299/month\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Why Managed Application (not Solution Template):\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Solution Templates are not transactable\u003C/strong> — Microsoft will not bill customers for them\u003C/li>\n\u003Cli>Managed Applications support Microsoft-billed monthly subscriptions\u003C/li>\n\u003Cli>Customer still controls their deployment (publisher access disabled)\u003C/li>\n\u003Cli>Data stays in customer environment\u003C/li>\n\u003Cli>No backend needed\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Permission configuration:\u003C/strong>\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Setting\u003C/th>\u003Cth>Value\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Publisher Management\u003C/td>\u003Ctd>\u003Cstrong>Disabled\u003C/strong>\u003C/td>\u003Ctd>No publisher access to customer resources\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Customer Access\u003C/td>\u003Ctd>\u003Cstrong>Enabled\u003C/strong>\u003C/td>\u003Ctd>Full customer control\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>These settings are \u003Cstrong>immutable after publishing\u003C/strong>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"deployment-package\">Deployment Package\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#deployment-package\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment Package”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Partner Center requires a \u003Ccode dir=\"auto\">.zip\u003C/code> package for Managed Application offers:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">variscout-managed-app.zip\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── mainTemplate.json # ARM template for resources\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── createUiDefinition.json # Azure portal deployment wizard UI\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"variscout-managed-app.zip├── mainTemplate.json # ARM template for resources└── createUiDefinition.json # Azure portal deployment wizard UI\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>See \u003Ca href=\"arm-template.md\">ARM Template Documentation\u003C/a> for the full template.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pricing-configuration\">Pricing Configuration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pricing-configuration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pricing Configuration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"two-plans\">Two Plans\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#two-plans\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two Plans”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Plan ID\u003C/th>\u003Cth>Display Name\u003C/th>\u003Cth>Price (EUR)\u003C/th>\u003Cth>Billing\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">standard\u003C/code>\u003C/td>\u003Ctd>VariScout Standard\u003C/td>\u003Ctd>€99\u003C/td>\u003Ctd>Monthly\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">team\u003C/code>\u003C/td>\u003Ctd>VariScout Team\u003C/td>\u003Ctd>€299\u003C/td>\u003Ctd>Monthly\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"price-breakdown\">Price Breakdown\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#price-breakdown\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Price Breakdown”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Standard: €99/month → Net €96.03/month (€1,152/year)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Team: €299/month → Net €290.03/month (€3,480/year)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Microsoft Fee: 3% on each plan\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Standard: €99/month → Net €96.03/month (€1,152/year)Team: €299/month → Net €290.03/month (€3,480/year)Microsoft Fee: 3% on each plan\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"regional-pricing\">Regional Pricing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#regional-pricing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Regional Pricing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Partner Center supports per-region pricing. Recommended approach:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>EUR zone\u003C/strong>: €99 / €299 per month\u003C/li>\n\u003Cli>\u003Cstrong>USD zone\u003C/strong>: $109 / $329 per month\u003C/li>\n\u003Cli>\u003Cstrong>GBP zone\u003C/strong>: £85 / £255 per month\u003C/li>\n\u003C/ul>\n\u003Cp>Microsoft handles currency conversion and VAT.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"listing-content\">Listing Content\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#listing-content\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Listing Content”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"offer-name\">Offer Name\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#offer-name\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Offer Name”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">VariScout - Statistical Process Control for Quality Teams\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"VariScout - Statistical Process Control for Quality Teams\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"short-description-100-chars\">Short Description (100 chars)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#short-description-100-chars\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Short Description (100 chars)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Offline-first variation analysis with I-Charts, Boxplots, Pareto, and process capability analysis.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Offline-first variation analysis with I-Charts, Boxplots, Pareto, and process capability analysis.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"long-description-3000-chars\">Long Description (3000 chars)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#long-description-3000-chars\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Long Description (3000 chars)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"markdown\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#C5E478;--0fw:bold;--1:#3B61B0;--1fw:bold\">VariScout\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> is a variation analysis tool designed for quality professionals\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">who need to understand process variation without complex setup or cloud dependencies.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82B1FF;--1:#3B61B0\">### Key Features\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#C5E478;--0fw:bold;--1:#3B61B0;--1fw:bold\">Four Lenses of Variation Analysis\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Change: I-Charts with Nelson Rules for process stability\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Failure: Capability analysis (Cp/Cpk) against specifications\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Flow: Pareto charts for prioritizing improvement efforts\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Value: Boxplot comparisons across categories\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#C5E478;--0fw:bold;--1:#3B61B0;--1fw:bold\">Performance Mode\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Analyze hundreds of measurement channels simultaneously:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Multi-channel capability tracking (Cpk)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Worst-first Pareto ranking\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Interactive drill-down to individual channels\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#C5E478;--0fw:bold;--1:#3B61B0;--1fw:bold\">No Backend Required\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Deploys entirely to your Azure tenant\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Standard: Data stored locally in browser. Team: Syncs to your OneDrive\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Zero external API calls\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Full offline support after initial load\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82B1FF;--1:#3B61B0\">### Who Is It For?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Quality engineers analyzing production data\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Manufacturing teams tracking process capability\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Consultants conducting capability assessments\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">-\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> Students learning statistical quality control\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82B1FF;--1:#3B61B0\">### Pricing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#C5E478;--0fw:bold;--1:#3B61B0;--1fw:bold\">Standard — €99/month\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> — Full analysis, unlimited users in your tenant.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#C5E478;--0fw:bold;--1:#3B61B0;--1fw:bold\">Team — €299/month\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">**\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> — Everything in Standard, plus Teams, OneDrive, SharePoint, mobile, and photo evidence.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82B1FF;--1:#3B61B0\">### Integration\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Try the FREE VariScout Web App for training and learning SPC fundamentals\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">before upgrading to the full Azure App for team use.\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"**VariScout** is a variation analysis tool designed for quality professionalswho need to understand process variation without complex setup or cloud dependencies.### Key Features**Four Lenses of Variation Analysis**- Change: I-Charts with Nelson Rules for process stability- Failure: Capability analysis (Cp/Cpk) against specifications- Flow: Pareto charts for prioritizing improvement efforts- Value: Boxplot comparisons across categories**Performance Mode**Analyze hundreds of measurement channels simultaneously:- Multi-channel capability tracking (Cpk)- Worst-first Pareto ranking- Interactive drill-down to individual channels**No Backend Required**- Deploys entirely to your Azure tenant- Standard: Data stored locally in browser. Team: Syncs to your OneDrive- Zero external API calls- Full offline support after initial load### Who Is It For?- Quality engineers analyzing production data- Manufacturing teams tracking process capability- Consultants conducting capability assessments- Students learning statistical quality control### Pricing**Standard — €99/month** — Full analysis, unlimited users in your tenant.**Team — €299/month** — Everything in Standard, plus Teams, OneDrive, SharePoint, mobile, and photo evidence.### IntegrationTry the FREE VariScout Web App for training and learning SPC fundamentalsbefore upgrading to the full Azure App for team use.\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"screenshots-required-5-10\">Screenshots (Required: 5-10)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#screenshots-required-5-10\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Screenshots (Required: 5-10)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Performance Dashboard - Multi-channel capability overview\u003C/li>\n\u003Cli>I-Chart - Control chart with Nelson Rules\u003C/li>\n\u003Cli>Capability Histogram - Cp/Cpk analysis\u003C/li>\n\u003Cli>Boxplot Comparison - Category comparison\u003C/li>\n\u003Cli>Pareto Chart - Improvement prioritization\u003C/li>\n\u003Cli>Drill-Down Navigation - Filter breadcrumbs\u003C/li>\n\u003Cli>OneDrive Sync - Analysis saving (Team plan)\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"videos-optional-but-recommended\">Videos (Optional but Recommended)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#videos-optional-but-recommended\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Videos (Optional but Recommended)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Product overview (2-3 min)\u003C/li>\n\u003Cli>Quick start tutorial\u003C/li>\n\u003Cli>Feature highlights\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-configuration\">Technical Configuration\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-configuration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Configuration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"plan-visibility\">Plan Visibility\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#plan-visibility\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Plan Visibility”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Plan\u003C/th>\u003Cth>Visibility\u003C/th>\u003Cth>Audience\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Standard\u003C/td>\u003Ctd>Public\u003C/td>\u003Ctd>All Azure customers\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Team\u003C/td>\u003Ctd>Public\u003C/td>\u003Ctd>All Azure customers\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"certification-process\">Certification Process\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#certification-process\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Certification Process”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pre-submission-checklist\">Pre-Submission Checklist\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pre-submission-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pre-Submission Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul class=\"contains-task-list\">\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Deployment package (.zip) validates successfully\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> mainTemplate.json passes ARM TTK validation\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> createUiDefinition.json renders correctly in sandbox\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> App deploys without errors from marketplace flow\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> EasyAuth authentication works post-deployment\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> OneDrive sync works (save/load analyses) — Team plan only\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Privacy policy URL accessible\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Terms of service URL accessible\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Support contact information complete\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> All screenshots meet requirements (1280x720 min)\u003C/li>\n\u003Cli class=\"task-list-item\">\u003Cinput type=\"checkbox\" disabled> Video links work (if included)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"microsoft-review-5-10-business-days\">Microsoft Review (~5-10 business days)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#microsoft-review-5-10-business-days\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Microsoft Review (~5-10 business days)”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Automated validation\u003C/strong>: Template syntax, resource definitions, package structure\u003C/li>\n\u003Cli>\u003Cstrong>Manual review\u003C/strong>: Listing content, pricing, policies\u003C/li>\n\u003Cli>\u003Cstrong>Security scan\u003C/strong>: Vulnerability assessment\u003C/li>\n\u003Cli>\u003Cstrong>Functionality test\u003C/strong>: Deployment verification via marketplace flow\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"common-rejection-reasons\">Common Rejection Reasons\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#common-rejection-reasons\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Rejection Reasons”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Issue\u003C/th>\u003Cth>Fix\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Invalid ARM template\u003C/td>\u003Ctd>Validate with ARM TTK and Azure CLI\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Invalid createUiDefinition\u003C/td>\u003Ctd>Test in sandbox portal\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Missing privacy policy\u003C/td>\u003Ctd>Add public URL to listing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Screenshot quality\u003C/td>\u003Ctd>Minimum 1280x720, PNG format\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Description too short\u003C/td>\u003Ctd>Expand feature descriptions\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Support contact incomplete\u003C/td>\u003Ctd>Add email and response time commitment\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"post-publication\">Post-Publication\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#post-publication\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Post-Publication”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"monitoring\">Monitoring\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#monitoring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Monitoring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Partner Center Analytics for sales data\u003C/li>\n\u003Cli>Customer deployment telemetry (anonymous)\u003C/li>\n\u003Cli>Support ticket tracking\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"updates\">Updates\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#updates\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Updates”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Update deployment package (.zip)\u003C/li>\n\u003Cli>Submit for re-certification\u003C/li>\n\u003Cli>Typically 2-3 day review for updates\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"customer-support\">Customer Support\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#customer-support\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Customer Support”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Response Time\u003C/th>\u003Cth>Channel\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>24 hours\u003C/td>\u003Ctd>Email\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"how-it-works.md\">How It Works\u003C/a> — end-to-end architecture guide\u003C/li>\n\u003Cli>\u003Ca href=\"pricing-tiers.md\">Pricing Tiers\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"arm-template.md\">ARM Template\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"authentication.md\">Authentication\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://docs.microsoft.com/partner-center/\">Partner Center Documentation\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 11720, + "localImagePaths": 11799, + "remoteImagePaths": 11800, + "frontmatter": 11801, + "imagePaths": 11802 + }, + [ + 11721, 11723, 11724, 11725, 11728, 11731, 11734, 11737, 11740, 11743, 11746, 11749, 11752, + 11755, 11758, 11761, 11764, 11767, 11770, 11773, 11776, 11779, 11782, 11785, 11788, 11791, + 11792, 11795, 11798 + ], + { "depth": 30, "slug": 11722, "text": 11710 }, + "azure-marketplace-guide", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 6401, "text": 6402 }, + { "depth": 79, "slug": 11726, "text": 11727 }, + "partner-center-account", + "Partner Center Account", + { "depth": 79, "slug": 11729, "text": 11730 }, + "technical-requirements", + "Technical Requirements", + { "depth": 33, "slug": 11732, "text": 11733 }, + "offer-type", + "Offer Type", + { "depth": 79, "slug": 11735, "text": 11736 }, + "managed-application-required-for-billing", + "Managed Application (Required for Billing)", + { "depth": 79, "slug": 11738, "text": 11739 }, + "deployment-package", + "Deployment Package", + { "depth": 33, "slug": 11741, "text": 11742 }, + "pricing-configuration", + "Pricing Configuration", + { "depth": 79, "slug": 11744, "text": 11745 }, + "two-plans", + "Two Plans", + { "depth": 79, "slug": 11747, "text": 11748 }, + "price-breakdown", + "Price Breakdown", + { "depth": 79, "slug": 11750, "text": 11751 }, + "regional-pricing", + "Regional Pricing", + { "depth": 33, "slug": 11753, "text": 11754 }, + "listing-content", + "Listing Content", + { "depth": 79, "slug": 11756, "text": 11757 }, + "offer-name", + "Offer Name", + { "depth": 79, "slug": 11759, "text": 11760 }, + "short-description-100-chars", + "Short Description (100 chars)", + { "depth": 79, "slug": 11762, "text": 11763 }, + "long-description-3000-chars", + "Long Description (3000 chars)", + { "depth": 79, "slug": 11765, "text": 11766 }, + "screenshots-required-5-10", + "Screenshots (Required: 5-10)", + { "depth": 79, "slug": 11768, "text": 11769 }, + "videos-optional-but-recommended", + "Videos (Optional but Recommended)", + { "depth": 33, "slug": 11771, "text": 11772 }, + "technical-configuration", + "Technical Configuration", + { "depth": 79, "slug": 11774, "text": 11775 }, + "plan-visibility", + "Plan Visibility", + { "depth": 33, "slug": 11777, "text": 11778 }, + "certification-process", + "Certification Process", + { "depth": 79, "slug": 11780, "text": 11781 }, + "pre-submission-checklist", + "Pre-Submission Checklist", + { "depth": 79, "slug": 11783, "text": 11784 }, + "microsoft-review-5-10-business-days", + "Microsoft Review (~5-10 business days)", + { "depth": 79, "slug": 11786, "text": 11787 }, + "common-rejection-reasons", + "Common Rejection Reasons", + { "depth": 33, "slug": 11789, "text": 11790 }, + "post-publication", + "Post-Publication", + { "depth": 79, "slug": 8602, "text": 8603 }, + { "depth": 79, "slug": 11793, "text": 11794 }, + "updates", + "Updates", + { "depth": 79, "slug": 11796, "text": 11797 }, + "customer-support", + "Customer Support", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11710 }, + [], + "08-products/azure/onedrive-sync", + { + "id": 11803, + "data": 11805, + "body": 11810, + "filePath": 11811, + "digest": 11812, + "rendered": 11813 + }, + { + "title": 11806, + "editUrl": 16, + "head": 11807, + "template": 18, + "sidebar": 11808, + "pagefind": 16, + "draft": 20 + }, + "OneDrive & SharePoint Sync", + [], + { "hidden": 20, "attrs": 11809 }, + {}, + "# OneDrive & SharePoint Sync\n\nAnalysis synchronization with Microsoft OneDrive and SharePoint.\n\n> **Team plan only.** OneDrive and SharePoint sync requires the Azure Team plan (€299/month). The Azure Standard plan (€99/month) uses local files via File System Access API — no cloud sync.\n\n---\n\n## Overview\n\nThe Team plan syncs analyses to cloud storage:\n\n- **Personal OneDrive** — for personal tabs and browser access\n- **Channel SharePoint** — for channel tabs (shared with team)\n- Automatic sync when online\n- Offline-first with local cache\n- Conflict resolution\n\n---\n\n## Storage Structure\n\n```\nOneDrive/\n└── VariScout/\n └── Projects/\n ├── analysis-001.vrs\n ├── analysis-002.vrs\n └── ...\n```\n\nThe folder structure is auto-created on first use. When the app first lists\nprojects and the folder doesn't exist, it creates `/VariScout/Projects/`\nautomatically via the Graph API.\n\n### Channel SharePoint Storage (Team Plan)\n\nWhen the app runs as a Teams channel tab, analyses are stored in the channel's SharePoint document library:\n\n```\nChannel Files/VariScout/\n├── Projects/\n│ └── Feb-Fill-Line.vrs ← shared analysis (JSON)\n└── Photos/\n └── {analysisId}/{findingId}/\n ├── photo-001.jpg ← EXIF-stripped evidence\n └── photo-002.jpg\n```\n\n**Drive resolution**: `getChannelDriveInfo()` in `channelDrive.ts` calls Graph API `/teams/{teamId}/channels/{channelId}/filesFolder` to resolve the SharePoint drive. The result is cached in IndexedDB.\n\n**Storage routing**: The `StorageLocation` type (`'personal' | 'team'`) determines the storage target:\n\n- Channel tab → `'team'` → channel SharePoint drive\n- Personal tab → `'personal'` → user's OneDrive\n- Browser → `'personal'` → user's OneDrive\n\nSee [ADR-016](../../07-decisions/adr-016-teams-integration.md) for the full channel storage design.\n\n---\n\n## Sync Flow\n\n```\nLOCAL (IndexedDB) ONEDRIVE\n │ │\n │◀── Load on startup ────────│\n │ (if online) │\n │ │\n │── User makes changes ─────▶│\n │ (debounced save) │\n │ │\n │◀── Sync on reconnect ──────│\n │ (on `online` event) │\n │ │\n │── Offline mode ────────────│\n │ (queue changes) │\n │ │\n │── Back online ────────────▶│\n │ (flush queue) │\n```\n\n---\n\n## Graph API Calls\n\nThe app uses raw `fetch()` with EasyAuth bearer tokens (no Graph SDK).\n\n### List Analyses\n\n```typescript\nconst token = await getAccessToken(); // from EasyAuth /.auth/me\nconst response = await fetch(\n `${GRAPH_BASE}/me/drive/root:/VariScout/Projects:/children?$filter=file ne null&$select=id,name,lastModifiedDateTime,lastModifiedBy,size`,\n { headers: { Authorization: `Bearer ${token}` } }\n);\n```\n\n### Save Analysis\n\n```typescript\nconst token = await getAccessToken();\nawait fetch(`${GRAPH_BASE}/me/drive/root:/VariScout/Projects/${name}.vrs:/content`, {\n method: 'PUT',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(project),\n});\n```\n\n### Load Analysis\n\n```typescript\nconst token = await getAccessToken();\nconst response = await fetch(\n `${GRAPH_BASE}/me/drive/root:/VariScout/Projects/${name}.vrs:/content`,\n { headers: { Authorization: `Bearer ${token}` } }\n);\n```\n\n---\n\n## Folder Auto-Creation\n\nOn first use (before any project has been saved), the `/VariScout/Projects/` folder\ndoes not exist in the user's OneDrive. The `listFromCloud()` function detects\nthe 404 response and automatically creates the folder structure:\n\n1. `POST /me/drive/root/children` — creates `/VariScout/` (no-op if exists)\n2. `POST /me/drive/root:/VariScout:/children` — creates `/Projects/` subfolder\n\nThis is idempotent (`conflictBehavior: \"replace\"`) and only runs once per user.\nSubsequent list calls succeed normally.\n\nSource: `ensureFolderExists()` in `apps/azure/src/services/storage.ts`\n\n---\n\n## Error Classification\n\nAll sync errors are classified by `classifySyncError()`:\n\n| Category | Examples | Retryable | Action |\n| ----------- | --------------------------------- | --------- | -------------------------------- |\n| `auth` | 401, 403, AuthError | No | Stop retry, prompt re-auth |\n| `not_found` | 404 (folder/file missing) | No | Auto-create folder, return empty |\n| `network` | TypeError (fetch failed), offline | Yes | Queue for retry |\n| `throttle` | 429 Too Many Requests | Yes | Retry with backoff |\n| `server` | 500, 502, 503 | Yes | Retry with backoff |\n| `unknown` | Unexpected errors | Yes | Log, notify user |\n\nSource: `classifySyncError()` in `apps/azure/src/services/storage.ts`\n\n---\n\n## Retry with Exponential Backoff\n\nFailed retryable operations are retried with increasing delays:\n\n- Delays: 2s → 4s → 8s → 16s → 32s (max 5 attempts)\n- Auth errors stop retry immediately\n- Timers cleaned up on component unmount\n- On final failure: notification shown, item remains in sync queue\n\n---\n\n## Sync Notifications\n\nUsers receive real-time feedback via toast notifications (`SyncToastContainer`):\n\n| Event | Type | Auto-dismiss | Action button |\n| ------------------ | ------- | ------------ | ------------- |\n| Cloud save success | success | 3s | - |\n| Queued for offline | info | 3s | - |\n| Back-online sync | success | 3s | - |\n| Network error | warning | 5s | - |\n| Auth expired | error | No | \"Sign in\" |\n| Retry succeeded | success | 3s | - |\n\nNotifications are accessible: `role=\"status\"` + `aria-live=\"polite\"`.\n\nSource: `apps/azure/src/components/SyncToast.tsx`\n\n---\n\n## Conflict Detection\n\nOn `loadProject`, the system checks for divergence:\n\n1. Read local record from IndexedDB (`synced` flag + `modified` date)\n2. Fetch cloud `lastModifiedDateTime` via Graph API metadata\n3. If local has unsynced changes AND cloud is newer:\n - Set status to `conflict`\n - Show warning toast\n - Load cloud version (last-write-wins)\n\nThe Editor toolbar shows amber status for conflicts, with clickable re-auth for auth errors.\n\n---\n\n## Offline Behavior\n\n| State | Behavior |\n| --------- | --------------------- |\n| Online | Sync on save |\n| Offline | Work with local cache |\n| Reconnect | Flush queued changes |\n\n---\n\n## See Also\n\n- [Authentication (EasyAuth)](authentication.md)\n- [Offline-First Architecture](../../05-technical/architecture/offline-first.md)", + "src/content/docs/08-products/azure/onedrive-sync.md", + "4d93511ca4c6813c", + { "html": 11814, "metadata": 11815 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"onedrive--sharepoint-sync\">OneDrive & SharePoint Sync\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#onedrive--sharepoint-sync\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “OneDrive & SharePoint Sync”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Analysis synchronization with Microsoft OneDrive and SharePoint.\u003C/p>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Team plan only.\u003C/strong> OneDrive and SharePoint sync requires the Azure Team plan (€299/month). The Azure Standard plan (€99/month) uses local files via File System Access API — no cloud sync.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Team plan syncs analyses to cloud storage:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Personal OneDrive\u003C/strong> — for personal tabs and browser access\u003C/li>\n\u003Cli>\u003Cstrong>Channel SharePoint\u003C/strong> — for channel tabs (shared with team)\u003C/li>\n\u003Cli>Automatic sync when online\u003C/li>\n\u003Cli>Offline-first with local cache\u003C/li>\n\u003Cli>Conflict resolution\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"storage-structure\">Storage Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#storage-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Storage Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">OneDrive/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── VariScout/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Projects/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── analysis-001.vrs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── analysis-002.vrs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── ...\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"OneDrive/└── VariScout/ └── Projects/ ├── analysis-001.vrs ├── analysis-002.vrs └── ...\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>The folder structure is auto-created on first use. When the app first lists\nprojects and the folder doesn’t exist, it creates \u003Ccode dir=\"auto\">/VariScout/Projects/\u003C/code>\nautomatically via the Graph API.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"channel-sharepoint-storage-team-plan\">Channel SharePoint Storage (Team Plan)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#channel-sharepoint-storage-team-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Channel SharePoint Storage (Team Plan)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When the app runs as a Teams channel tab, analyses are stored in the channel’s SharePoint document library:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Channel Files/VariScout/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Projects/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Feb-Fill-Line.vrs ← shared analysis (JSON)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Photos/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── {analysisId}/{findingId}/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── photo-001.jpg ← EXIF-stripped evidence\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── photo-002.jpg\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Channel Files/VariScout/├── Projects/│ └── Feb-Fill-Line.vrs ← shared analysis (JSON)└── Photos/ └── {analysisId}/{findingId}/ ├── photo-001.jpg ← EXIF-stripped evidence └── photo-002.jpg\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Drive resolution\u003C/strong>: \u003Ccode dir=\"auto\">getChannelDriveInfo()\u003C/code> in \u003Ccode dir=\"auto\">channelDrive.ts\u003C/code> calls Graph API \u003Ccode dir=\"auto\">/teams/{teamId}/channels/{channelId}/filesFolder\u003C/code> to resolve the SharePoint drive. The result is cached in IndexedDB.\u003C/p>\n\u003Cp>\u003Cstrong>Storage routing\u003C/strong>: The \u003Ccode dir=\"auto\">StorageLocation\u003C/code> type (\u003Ccode dir=\"auto\">'personal' | 'team'\u003C/code>) determines the storage target:\u003C/p>\n\u003Cul>\n\u003Cli>Channel tab → \u003Ccode dir=\"auto\">'team'\u003C/code> → channel SharePoint drive\u003C/li>\n\u003Cli>Personal tab → \u003Ccode dir=\"auto\">'personal'\u003C/code> → user’s OneDrive\u003C/li>\n\u003Cli>Browser → \u003Ccode dir=\"auto\">'personal'\u003C/code> → user’s OneDrive\u003C/li>\n\u003C/ul>\n\u003Cp>See \u003Ca href=\"../../07-decisions/adr-016-teams-integration.md\">ADR-016\u003C/a> for the full channel storage design.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sync-flow\">Sync Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sync-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sync Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">LOCAL (IndexedDB) ONEDRIVE\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀── Load on startup ────────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (if online) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│── User makes changes ─────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (debounced save) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│◀── Sync on reconnect ──────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (on `online` event) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│── Offline mode ────────────│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (queue changes) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│── Back online ────────────▶│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (flush queue) │\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"LOCAL (IndexedDB) ONEDRIVE │ │ │◀── Load on startup ────────│ │ (if online) │ │ │ │── User makes changes ─────▶│ │ (debounced save) │ │ │ │◀── Sync on reconnect ──────│ │ (on `online` event) │ │ │ │── Offline mode ────────────│ │ (queue changes) │ │ │ │── Back online ────────────▶│ │ (flush queue) │\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"graph-api-calls\">Graph API Calls\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#graph-api-calls\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Graph API Calls”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The app uses raw \u003Ccode dir=\"auto\">fetch()\u003C/code> with EasyAuth bearer tokens (no Graph SDK).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"list-analyses\">List Analyses\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#list-analyses\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “List Analyses”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">token\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getAccessToken\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(); \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// from EasyAuth /.auth/me\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fetch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">GRAPH_BASE\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/me/drive/root:/VariScout/Projects:/children?$filter=file ne null&$select=id,name,lastModifiedDateTime,lastModifiedBy,size\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ headers: { Authorization: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Bearer \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">token\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const token = await getAccessToken(); // from EasyAuth /.auth/meconst response = await fetch( `${GRAPH_BASE}/me/drive/root:/VariScout/Projects:/children?$filter=file ne null&$select=id,name,lastModifiedDateTime,lastModifiedBy,size`, { headers: { Authorization: `Bearer ${token}` } });\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"save-analysis\">Save Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#save-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Save Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">token\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getAccessToken\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">await\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fetch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">GRAPH_BASE\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/me/drive/root:/VariScout/Projects/\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">.vrs:/content\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">, {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">method: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">PUT\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">headers: {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Authorization: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Bearer \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">token\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Content-Type\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">application/json\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">},\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">body: \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">JSON\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">stringify\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(project),\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">});\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const token = await getAccessToken();await fetch(`${GRAPH_BASE}/me/drive/root:/VariScout/Projects/${name}.vrs:/content`, { method: 'PUT', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', }, body: JSON.stringify(project),});\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"load-analysis\">Load Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#load-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Load Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">token\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getAccessToken\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">();\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">response\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = await \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">fetch\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">GRAPH_BASE\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">/me/drive/root:/VariScout/Projects/\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">name\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">.vrs:/content\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">{ headers: { Authorization: \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">Bearer \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">${\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">token\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">`\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const token = await getAccessToken();const response = await fetch( `${GRAPH_BASE}/me/drive/root:/VariScout/Projects/${name}.vrs:/content`, { headers: { Authorization: `Bearer ${token}` } });\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"folder-auto-creation\">Folder Auto-Creation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#folder-auto-creation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Folder Auto-Creation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>On first use (before any project has been saved), the \u003Ccode dir=\"auto\">/VariScout/Projects/\u003C/code> folder\ndoes not exist in the user’s OneDrive. The \u003Ccode dir=\"auto\">listFromCloud()\u003C/code> function detects\nthe 404 response and automatically creates the folder structure:\u003C/p>\n\u003Col>\n\u003Cli>\u003Ccode dir=\"auto\">POST /me/drive/root/children\u003C/code> — creates \u003Ccode dir=\"auto\">/VariScout/\u003C/code> (no-op if exists)\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">POST /me/drive/root:/VariScout:/children\u003C/code> — creates \u003Ccode dir=\"auto\">/Projects/\u003C/code> subfolder\u003C/li>\n\u003C/ol>\n\u003Cp>This is idempotent (\u003Ccode dir=\"auto\">conflictBehavior: \"replace\"\u003C/code>) and only runs once per user.\nSubsequent list calls succeed normally.\u003C/p>\n\u003Cp>Source: \u003Ccode dir=\"auto\">ensureFolderExists()\u003C/code> in \u003Ccode dir=\"auto\">apps/azure/src/services/storage.ts\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"error-classification\">Error Classification\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#error-classification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Error Classification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All sync errors are classified by \u003Ccode dir=\"auto\">classifySyncError()\u003C/code>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Category\u003C/th>\u003Cth>Examples\u003C/th>\u003Cth>Retryable\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">auth\u003C/code>\u003C/td>\u003Ctd>401, 403, AuthError\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Stop retry, prompt re-auth\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">not_found\u003C/code>\u003C/td>\u003Ctd>404 (folder/file missing)\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Auto-create folder, return empty\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">network\u003C/code>\u003C/td>\u003Ctd>TypeError (fetch failed), offline\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Queue for retry\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">throttle\u003C/code>\u003C/td>\u003Ctd>429 Too Many Requests\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Retry with backoff\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">server\u003C/code>\u003C/td>\u003Ctd>500, 502, 503\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Retry with backoff\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">unknown\u003C/code>\u003C/td>\u003Ctd>Unexpected errors\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Log, notify user\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Source: \u003Ccode dir=\"auto\">classifySyncError()\u003C/code> in \u003Ccode dir=\"auto\">apps/azure/src/services/storage.ts\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"retry-with-exponential-backoff\">Retry with Exponential Backoff\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#retry-with-exponential-backoff\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Retry with Exponential Backoff”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Failed retryable operations are retried with increasing delays:\u003C/p>\n\u003Cul>\n\u003Cli>Delays: 2s → 4s → 8s → 16s → 32s (max 5 attempts)\u003C/li>\n\u003Cli>Auth errors stop retry immediately\u003C/li>\n\u003Cli>Timers cleaned up on component unmount\u003C/li>\n\u003Cli>On final failure: notification shown, item remains in sync queue\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sync-notifications\">Sync Notifications\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sync-notifications\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sync Notifications”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Users receive real-time feedback via toast notifications (\u003Ccode dir=\"auto\">SyncToastContainer\u003C/code>):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Event\u003C/th>\u003Cth>Type\u003C/th>\u003Cth>Auto-dismiss\u003C/th>\u003Cth>Action button\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Cloud save success\u003C/td>\u003Ctd>success\u003C/td>\u003Ctd>3s\u003C/td>\u003Ctd>-\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Queued for offline\u003C/td>\u003Ctd>info\u003C/td>\u003Ctd>3s\u003C/td>\u003Ctd>-\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Back-online sync\u003C/td>\u003Ctd>success\u003C/td>\u003Ctd>3s\u003C/td>\u003Ctd>-\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Network error\u003C/td>\u003Ctd>warning\u003C/td>\u003Ctd>5s\u003C/td>\u003Ctd>-\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Auth expired\u003C/td>\u003Ctd>error\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>”Sign in”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Retry succeeded\u003C/td>\u003Ctd>success\u003C/td>\u003Ctd>3s\u003C/td>\u003Ctd>-\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Notifications are accessible: \u003Ccode dir=\"auto\">role=\"status\"\u003C/code> + \u003Ccode dir=\"auto\">aria-live=\"polite\"\u003C/code>.\u003C/p>\n\u003Cp>Source: \u003Ccode dir=\"auto\">apps/azure/src/components/SyncToast.tsx\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"conflict-detection\">Conflict Detection\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#conflict-detection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Conflict Detection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>On \u003Ccode dir=\"auto\">loadProject\u003C/code>, the system checks for divergence:\u003C/p>\n\u003Col>\n\u003Cli>Read local record from IndexedDB (\u003Ccode dir=\"auto\">synced\u003C/code> flag + \u003Ccode dir=\"auto\">modified\u003C/code> date)\u003C/li>\n\u003Cli>Fetch cloud \u003Ccode dir=\"auto\">lastModifiedDateTime\u003C/code> via Graph API metadata\u003C/li>\n\u003Cli>If local has unsynced changes AND cloud is newer:\n\u003Cul>\n\u003Cli>Set status to \u003Ccode dir=\"auto\">conflict\u003C/code>\u003C/li>\n\u003Cli>Show warning toast\u003C/li>\n\u003Cli>Load cloud version (last-write-wins)\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003C/ol>\n\u003Cp>The Editor toolbar shows amber status for conflicts, with clickable re-auth for auth errors.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"offline-behavior\">Offline Behavior\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#offline-behavior\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Offline Behavior”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>State\u003C/th>\u003Cth>Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Online\u003C/td>\u003Ctd>Sync on save\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Offline\u003C/td>\u003Ctd>Work with local cache\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Reconnect\u003C/td>\u003Ctd>Flush queued changes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"authentication.md\">Authentication (EasyAuth)\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../05-technical/architecture/offline-first.md\">Offline-First Architecture\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 11816, + "localImagePaths": 11858, + "remoteImagePaths": 11859, + "frontmatter": 11860, + "imagePaths": 11861 + }, + [ + 11817, 11819, 11820, 11823, 11826, 11829, 11832, 11835, 11838, 11841, 11844, 11847, 11850, + 11853, 11856, 11857 + ], + { "depth": 30, "slug": 11818, "text": 11806 }, + "onedrive--sharepoint-sync", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 11821, "text": 11822 }, + "storage-structure", + "Storage Structure", + { "depth": 79, "slug": 11824, "text": 11825 }, + "channel-sharepoint-storage-team-plan", + "Channel SharePoint Storage (Team Plan)", + { "depth": 33, "slug": 11827, "text": 11828 }, + "sync-flow", + "Sync Flow", + { "depth": 33, "slug": 11830, "text": 11831 }, + "graph-api-calls", + "Graph API Calls", + { "depth": 79, "slug": 11833, "text": 11834 }, + "list-analyses", + "List Analyses", + { "depth": 79, "slug": 11836, "text": 11837 }, + "save-analysis", + "Save Analysis", + { "depth": 79, "slug": 11839, "text": 11840 }, + "load-analysis", + "Load Analysis", + { "depth": 33, "slug": 11842, "text": 11843 }, + "folder-auto-creation", + "Folder Auto-Creation", + { "depth": 33, "slug": 11845, "text": 11846 }, + "error-classification", + "Error Classification", + { "depth": 33, "slug": 11848, "text": 11849 }, + "retry-with-exponential-backoff", + "Retry with Exponential Backoff", + { "depth": 33, "slug": 11851, "text": 11852 }, + "sync-notifications", + "Sync Notifications", + { "depth": 33, "slug": 11854, "text": 11855 }, + "conflict-detection", + "Conflict Detection", + { "depth": 33, "slug": 11620, "text": 11621 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11806 }, + [], + "08-products/azure/pricing-tiers", + { + "id": 11862, + "data": 11864, + "body": 11869, + "filePath": 11870, + "digest": 11871, + "rendered": 11872 + }, + { + "title": 11865, + "editUrl": 16, + "head": 11866, + "template": 18, + "sidebar": 11867, + "pagefind": 16, + "draft": 20 + }, + "Pricing", + [], + { "hidden": 20, "attrs": 11868 }, + {}, + "# Pricing\n\nVariScout Azure App pricing structure — two plans differentiated by storage, collaboration, and mobile capabilities.\n\n---\n\n## Plan Overview\n\n| Plan | Price | Storage | Auth Scopes | Mobile | Users | Billing |\n| ------------ | ---------- | ------------------------------------ | ------------------------------------------------ | -------------------- | --------- | ------- |\n| **Standard** | €99/month | Local files (File System Access API) | `User.Read` only | Desktop browser only | Unlimited | Monthly |\n| **Team** | €299/month | + OneDrive + SharePoint channels | + `Files.ReadWrite.All`, `Channel.ReadBasic.All` | Teams mobile app | Unlimited | Monthly |\n\n**Model**: Per-deployment (one subscription per Azure tenant). All users in the tenant have access. Plans differentiate by capability, not user count.\n\n---\n\n## Feature Comparison\n\n| Feature | Standard | Team |\n| ------------------------------ | :------: | :---: |\n| **Core Analysis** | | |\n| I-Chart | ✓ | ✓ |\n| Boxplot | ✓ | ✓ |\n| Pareto | ✓ | ✓ |\n| Capability (Cp/Cpk) | ✓ | ✓ |\n| Probability Plot | ✓ | ✓ |\n| ANOVA | ✓ | ✓ |\n| **Performance Mode** | | |\n| Multi-channel analysis | ✓ | ✓ |\n| Channel limit | 1,500 | 1,500 |\n| **Data Input** | | |\n| CSV / Excel upload | ✓ | ✓ |\n| Copy-paste from spreadsheets | ✓ | ✓ |\n| Manual data entry | ✓ | ✓ |\n| **Storage** | | |\n| Local file save/load (.vrs) | ✓ | ✓ |\n| IndexedDB fallback | ✓ | ✓ |\n| OneDrive personal sync | — | ✓ |\n| SharePoint channel storage | — | ✓ |\n| **Authentication** | | |\n| EasyAuth SSO (Microsoft Entra) | ✓ | ✓ |\n| Admin consent required | No | Yes |\n| **Investigation Workflow** | | |\n| Findings log | ✓ | ✓ |\n| What-If simulation | ✓ | ✓ |\n| Photo evidence in findings | — | ✓ |\n| **Collaboration** | | |\n| Teams channel tabs | — | ✓ |\n| Teams SSO | — | ✓ |\n| Adaptive Cards | — | ✓ |\n| **Mobile** | | |\n| Mobile gemba companion (Teams) | — | ✓ |\n| **Support** | | |\n| Email support | ✓ | ✓ |\n| Response time | 24h | 24h |\n\n---\n\n## Why Two Plans\n\n### Standard — Full Analysis, Zero Admin\n\nStandard is the complete SPC analysis tool for individuals and small teams who work from a desktop browser. Local file storage via the File System Access API means projects live on the user's machine — no cloud permissions, no admin consent, no IT involvement. At €99/month for unlimited users, it undercuts per-seat competitors at any team size above one.\n\n### Team — Collaboration via Teams\n\nTeam adds everything needed for shared quality workflows: OneDrive and SharePoint channel storage so projects live where the team works, Teams integration for embedding analysis in channels, and mobile access through the Teams app for gemba investigations with photo evidence. The `Files.ReadWrite.All` and `Channel.ReadBasic.All` permissions require one-time admin consent, justified by the collaborative storage and Teams features they unlock.\n\n### Why Not One Plan\n\nThe original single plan at €150/month forced a compromise: too expensive for individuals who only need local analysis, not enough revenue from teams who need collaboration features. Two plans let each segment pay for what they use:\n\n- Standard at €99 removes the \"do I really need OneDrive?\" hesitation\n- Team at €299 captures the collaboration value that teams are willing to pay for\n- Standard requires no admin consent — faster purchase cycle\n\n---\n\n## Revenue\n\n### Standard Plan\n\n```\nGross Price: €99/month\nMicrosoft Fee: -€2.97/month (3%)\nNet Revenue: €96.03/month\nAnnual Net: €1,152.36/year\n```\n\n### Team Plan\n\n```\nGross Price: €299/month\nMicrosoft Fee: -€8.97/month (3%)\nNet Revenue: €290.03/month\nAnnual Net: €3,480.36/year\n```\n\n### Currency Table\n\n| Region | Currency | Standard/Month | Team/Month |\n| ------ | -------- | -------------- | ---------- |\n| EU | EUR | €99 | €299 |\n| US | USD | ~$109 | ~$329 |\n| UK | GBP | ~£85 | ~£256 |\n\nMicrosoft handles currency conversion automatically. Prices are set excluding tax; Microsoft adds VAT/GST at checkout based on the customer's billing country.\n\n---\n\n## Billing\n\n### Payment Processing\n\n- **Processor**: Microsoft Commerce\n- **Fee**: 3% of transaction\n- **Payout**: Monthly, net 30\n- **Billing cycle**: Monthly with automatic renewal\n\n### Tax Handling\n\n- VAT calculated and collected by Microsoft\n- B2B reverse charge applies where applicable\n- VAT receipts available in Azure portal\n\n### Enterprise Procurement\n\nEnterprise customers can use:\n\n- Purchase orders\n- Microsoft Enterprise Agreements\n- Volume licensing credits\n\n---\n\n## Free Tier (PWA)\n\nThe PWA provides free value as a training and education tool:\n\n| Product | Price | Features |\n| ------- | ----- | ---------------------------------------------------------- |\n| **PWA** | Free | Core analysis: I-Chart, Boxplot, Pareto, Capability, ANOVA |\n\nThe PWA serves as a marketing funnel — users who need Performance Mode, file upload, data persistence, or team collaboration upgrade to the Azure App.\n\n---\n\n## Upgrade Path\n\n### PWA to Standard\n\nUsers outgrow the PWA when they need file upload, project save/load, Performance Mode, or more than 3 factors. Standard provides all analysis features with local storage and no admin consent.\n\n### Standard to Team\n\nTeams outgrow Standard when they need shared project storage, mobile gemba access, or Teams channel integration. Upgrading from Standard to Team is a plan change in the Azure portal — same deployment, same data, new capabilities.\n\nThe ARM template uses a `VARISCOUT_PLAN` environment variable (`standard` or `team`) to control which features are available. Both plans deploy as `enterprise` tier.\n\n---\n\n## Cancellation\n\n- Cancel any time in Azure portal\n- Service continues until end of billing period\n- No prorated refunds for partial months\n- Data remains in customer's tenant after cancellation\n\n---\n\n## Competitor Comparison\n\n| Product | Entry Price | Team of 10 | Collaboration | Deployment |\n| ------------------ | ----------- | -------------- | -------------- | --------------- |\n| VariScout Standard | €99/month | €99/month | Local files | Customer Azure |\n| VariScout Team | €299/month | €299/month | OneDrive/Teams | Customer Azure |\n| Minitab | ~€150/month | ~€1,500/month | Minitab Cloud | Minitab Cloud |\n| JMP | ~€200/month | ~€2,000/month | SAS Cloud | Local/SAS Cloud |\n| SigmaXL | ~€21/month | ~€83/month | None | Excel Add-in |\n| InfinityQS | Custom | ~$4,000+/month | SaaS | SaaS |\n\n### VariScout Advantages\n\n- **Flat pricing** regardless of team size\n- **Customer-controlled data** (no vendor lock-in)\n- **No backend costs** for publisher\n- **Microsoft billing integration** (familiar for enterprises)\n- **Two entry points** — Standard for individuals, Team for departments\n\n---\n\n## See Also\n\n- [Azure Marketplace Guide](marketplace.md)\n- [Products Overview](../index.md)\n- [ADR-007: Distribution Strategy](../../07-decisions/adr-007-azure-marketplace-distribution.md)\n- [ADR-016: Teams Integration](../../07-decisions/adr-016-teams-integration.md)", + "src/content/docs/08-products/azure/pricing-tiers.md", + "cb39c74a82e3f6c7", + { "html": 11873, "metadata": 11874 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"pricing\">Pricing\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#pricing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pricing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout Azure App pricing structure — two plans differentiated by storage, collaboration, and mobile capabilities.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"plan-overview\">Plan Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#plan-overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Plan Overview”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Plan\u003C/th>\u003Cth>Price\u003C/th>\u003Cth>Storage\u003C/th>\u003Cth>Auth Scopes\u003C/th>\u003Cth>Mobile\u003C/th>\u003Cth>Users\u003C/th>\u003Cth>Billing\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Standard\u003C/strong>\u003C/td>\u003Ctd>€99/month\u003C/td>\u003Ctd>Local files (File System Access API)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">User.Read\u003C/code> only\u003C/td>\u003Ctd>Desktop browser only\u003C/td>\u003Ctd>Unlimited\u003C/td>\u003Ctd>Monthly\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Team\u003C/strong>\u003C/td>\u003Ctd>€299/month\u003C/td>\u003Ctd>+ OneDrive + SharePoint channels\u003C/td>\u003Ctd>+ \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code>, \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code>\u003C/td>\u003Ctd>Teams mobile app\u003C/td>\u003Ctd>Unlimited\u003C/td>\u003Ctd>Monthly\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Model\u003C/strong>: Per-deployment (one subscription per Azure tenant). All users in the tenant have access. Plans differentiate by capability, not user count.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-comparison\">Feature Comparison\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth align=\"center\">Standard\u003C/th>\u003Cth align=\"center\">Team\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Core Analysis\u003C/strong>\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>I-Chart\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability (Cp/Cpk)\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Probability Plot\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ANOVA\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Performance Mode\u003C/strong>\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multi-channel analysis\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Channel limit\u003C/td>\u003Ctd align=\"center\">1,500\u003C/td>\u003Ctd align=\"center\">1,500\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Data Input\u003C/strong>\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CSV / Excel upload\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Copy-paste from spreadsheets\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Manual data entry\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Storage\u003C/strong>\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Local file save/load (.vrs)\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>IndexedDB fallback\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OneDrive personal sync\u003C/td>\u003Ctd align=\"center\">—\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SharePoint channel storage\u003C/td>\u003Ctd align=\"center\">—\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Authentication\u003C/strong>\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>EasyAuth SSO (Microsoft Entra)\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Admin consent required\u003C/td>\u003Ctd align=\"center\">No\u003C/td>\u003Ctd align=\"center\">Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Investigation Workflow\u003C/strong>\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Findings log\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>What-If simulation\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Photo evidence in findings\u003C/td>\u003Ctd align=\"center\">—\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Collaboration\u003C/strong>\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Teams channel tabs\u003C/td>\u003Ctd align=\"center\">—\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Teams SSO\u003C/td>\u003Ctd align=\"center\">—\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Adaptive Cards\u003C/td>\u003Ctd align=\"center\">—\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mobile\u003C/strong>\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mobile gemba companion (Teams)\u003C/td>\u003Ctd align=\"center\">—\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Support\u003C/strong>\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003Ctd align=\"center\">\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Email support\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Response time\u003C/td>\u003Ctd align=\"center\">24h\u003C/td>\u003Ctd align=\"center\">24h\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-two-plans\">Why Two Plans\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-two-plans\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Two Plans”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard--full-analysis-zero-admin\">Standard — Full Analysis, Zero Admin\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard--full-analysis-zero-admin\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard — Full Analysis, Zero Admin”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Standard is the complete SPC analysis tool for individuals and small teams who work from a desktop browser. Local file storage via the File System Access API means projects live on the user’s machine — no cloud permissions, no admin consent, no IT involvement. At €99/month for unlimited users, it undercuts per-seat competitors at any team size above one.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"team--collaboration-via-teams\">Team — Collaboration via Teams\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#team--collaboration-via-teams\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Team — Collaboration via Teams”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Team adds everything needed for shared quality workflows: OneDrive and SharePoint channel storage so projects live where the team works, Teams integration for embedding analysis in channels, and mobile access through the Teams app for gemba investigations with photo evidence. The \u003Ccode dir=\"auto\">Files.ReadWrite.All\u003C/code> and \u003Ccode dir=\"auto\">Channel.ReadBasic.All\u003C/code> permissions require one-time admin consent, justified by the collaborative storage and Teams features they unlock.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"why-not-one-plan\">Why Not One Plan\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#why-not-one-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Not One Plan”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The original single plan at €150/month forced a compromise: too expensive for individuals who only need local analysis, not enough revenue from teams who need collaboration features. Two plans let each segment pay for what they use:\u003C/p>\n\u003Cul>\n\u003Cli>Standard at €99 removes the “do I really need OneDrive?” hesitation\u003C/li>\n\u003Cli>Team at €299 captures the collaboration value that teams are willing to pay for\u003C/li>\n\u003Cli>Standard requires no admin consent — faster purchase cycle\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"revenue\">Revenue\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#revenue\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Revenue”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-plan\">Standard Plan\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard Plan”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Gross Price: €99/month\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Microsoft Fee: -€2.97/month (3%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Net Revenue: €96.03/month\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Annual Net: €1,152.36/year\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Gross Price: €99/monthMicrosoft Fee: -€2.97/month (3%)Net Revenue: €96.03/monthAnnual Net: €1,152.36/year\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"team-plan\">Team Plan\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#team-plan\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Team Plan”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Gross Price: €299/month\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Microsoft Fee: -€8.97/month (3%)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Net Revenue: €290.03/month\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Annual Net: €3,480.36/year\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Gross Price: €299/monthMicrosoft Fee: -€8.97/month (3%)Net Revenue: €290.03/monthAnnual Net: €3,480.36/year\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"currency-table\">Currency Table\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#currency-table\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Currency Table”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Region\u003C/th>\u003Cth>Currency\u003C/th>\u003Cth>Standard/Month\u003C/th>\u003Cth>Team/Month\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>EU\u003C/td>\u003Ctd>EUR\u003C/td>\u003Ctd>€99\u003C/td>\u003Ctd>€299\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>US\u003C/td>\u003Ctd>USD\u003C/td>\u003Ctd>~$109\u003C/td>\u003Ctd>~$329\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>UK\u003C/td>\u003Ctd>GBP\u003C/td>\u003Ctd>~£85\u003C/td>\u003Ctd>~£256\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Microsoft handles currency conversion automatically. Prices are set excluding tax; Microsoft adds VAT/GST at checkout based on the customer’s billing country.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"billing\">Billing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#billing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Billing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"payment-processing\">Payment Processing\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#payment-processing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Payment Processing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Processor\u003C/strong>: Microsoft Commerce\u003C/li>\n\u003Cli>\u003Cstrong>Fee\u003C/strong>: 3% of transaction\u003C/li>\n\u003Cli>\u003Cstrong>Payout\u003C/strong>: Monthly, net 30\u003C/li>\n\u003Cli>\u003Cstrong>Billing cycle\u003C/strong>: Monthly with automatic renewal\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tax-handling\">Tax Handling\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tax-handling\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tax Handling”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>VAT calculated and collected by Microsoft\u003C/li>\n\u003Cli>B2B reverse charge applies where applicable\u003C/li>\n\u003Cli>VAT receipts available in Azure portal\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"enterprise-procurement\">Enterprise Procurement\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#enterprise-procurement\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Enterprise Procurement”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Enterprise customers can use:\u003C/p>\n\u003Cul>\n\u003Cli>Purchase orders\u003C/li>\n\u003Cli>Microsoft Enterprise Agreements\u003C/li>\n\u003Cli>Volume licensing credits\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"free-tier-pwa\">Free Tier (PWA)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#free-tier-pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Free Tier (PWA)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA provides free value as a training and education tool:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth>Price\u003C/th>\u003Cth>Features\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>PWA\u003C/strong>\u003C/td>\u003Ctd>Free\u003C/td>\u003Ctd>Core analysis: I-Chart, Boxplot, Pareto, Capability, ANOVA\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The PWA serves as a marketing funnel — users who need Performance Mode, file upload, data persistence, or team collaboration upgrade to the Azure App.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"upgrade-path\">Upgrade Path\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#upgrade-path\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Upgrade Path”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa-to-standard\">PWA to Standard\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-to-standard\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA to Standard”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Users outgrow the PWA when they need file upload, project save/load, Performance Mode, or more than 3 factors. Standard provides all analysis features with local storage and no admin consent.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"standard-to-team\">Standard to Team\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#standard-to-team\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Standard to Team”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Teams outgrow Standard when they need shared project storage, mobile gemba access, or Teams channel integration. Upgrading from Standard to Team is a plan change in the Azure portal — same deployment, same data, new capabilities.\u003C/p>\n\u003Cp>The ARM template uses a \u003Ccode dir=\"auto\">VARISCOUT_PLAN\u003C/code> environment variable (\u003Ccode dir=\"auto\">standard\u003C/code> or \u003Ccode dir=\"auto\">team\u003C/code>) to control which features are available. Both plans deploy as \u003Ccode dir=\"auto\">enterprise\u003C/code> tier.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cancellation\">Cancellation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cancellation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cancellation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Cancel any time in Azure portal\u003C/li>\n\u003Cli>Service continues until end of billing period\u003C/li>\n\u003Cli>No prorated refunds for partial months\u003C/li>\n\u003Cli>Data remains in customer’s tenant after cancellation\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitor-comparison\">Competitor Comparison\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitor-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitor Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Product\u003C/th>\u003Cth>Entry Price\u003C/th>\u003Cth>Team of 10\u003C/th>\u003Cth>Collaboration\u003C/th>\u003Cth>Deployment\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>VariScout Standard\u003C/td>\u003Ctd>€99/month\u003C/td>\u003Ctd>€99/month\u003C/td>\u003Ctd>Local files\u003C/td>\u003Ctd>Customer Azure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>VariScout Team\u003C/td>\u003Ctd>€299/month\u003C/td>\u003Ctd>€299/month\u003C/td>\u003Ctd>OneDrive/Teams\u003C/td>\u003Ctd>Customer Azure\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Minitab\u003C/td>\u003Ctd>~€150/month\u003C/td>\u003Ctd>~€1,500/month\u003C/td>\u003Ctd>Minitab Cloud\u003C/td>\u003Ctd>Minitab Cloud\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>JMP\u003C/td>\u003Ctd>~€200/month\u003C/td>\u003Ctd>~€2,000/month\u003C/td>\u003Ctd>SAS Cloud\u003C/td>\u003Ctd>Local/SAS Cloud\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SigmaXL\u003C/td>\u003Ctd>~€21/month\u003C/td>\u003Ctd>~€83/month\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>Excel Add-in\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>InfinityQS\u003C/td>\u003Ctd>Custom\u003C/td>\u003Ctd>~$4,000+/month\u003C/td>\u003Ctd>SaaS\u003C/td>\u003Ctd>SaaS\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"variscout-advantages\">VariScout Advantages\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#variscout-advantages\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “VariScout Advantages”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Flat pricing\u003C/strong> regardless of team size\u003C/li>\n\u003Cli>\u003Cstrong>Customer-controlled data\u003C/strong> (no vendor lock-in)\u003C/li>\n\u003Cli>\u003Cstrong>No backend costs\u003C/strong> for publisher\u003C/li>\n\u003Cli>\u003Cstrong>Microsoft billing integration\u003C/strong> (familiar for enterprises)\u003C/li>\n\u003Cli>\u003Cstrong>Two entry points\u003C/strong> — Standard for individuals, Team for departments\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"marketplace.md\">Azure Marketplace Guide\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../index.md\">Products Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007: Distribution Strategy\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-016-teams-integration.md\">ADR-016: Teams Integration\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 11875, + "localImagePaths": 11938, + "remoteImagePaths": 11939, + "frontmatter": 11940, + "imagePaths": 11941 + }, + [ + 11876, 11878, 11881, 11882, 11885, 11888, 11891, 11894, 11897, 11900, 11903, 11906, 11909, + 11912, 11915, 11918, 11921, 11922, 11925, 11928, 11931, 11934, 11937 + ], + { "depth": 30, "slug": 11877, "text": 11865 }, + "pricing", + { "depth": 33, "slug": 11879, "text": 11880 }, + "plan-overview", + "Plan Overview", + { "depth": 33, "slug": 2115, "text": 2116 }, + { "depth": 33, "slug": 11883, "text": 11884 }, + "why-two-plans", + "Why Two Plans", + { "depth": 79, "slug": 11886, "text": 11887 }, + "standard--full-analysis-zero-admin", + "Standard — Full Analysis, Zero Admin", + { "depth": 79, "slug": 11889, "text": 11890 }, + "team--collaboration-via-teams", + "Team — Collaboration via Teams", + { "depth": 79, "slug": 11892, "text": 11893 }, + "why-not-one-plan", + "Why Not One Plan", + { "depth": 33, "slug": 11895, "text": 11896 }, + "revenue", + "Revenue", + { "depth": 79, "slug": 11898, "text": 11899 }, + "standard-plan", + "Standard Plan", + { "depth": 79, "slug": 11901, "text": 11902 }, + "team-plan", + "Team Plan", + { "depth": 79, "slug": 11904, "text": 11905 }, + "currency-table", + "Currency Table", + { "depth": 33, "slug": 11907, "text": 11908 }, + "billing", + "Billing", + { "depth": 79, "slug": 11910, "text": 11911 }, + "payment-processing", + "Payment Processing", + { "depth": 79, "slug": 11913, "text": 11914 }, + "tax-handling", + "Tax Handling", + { "depth": 79, "slug": 11916, "text": 11917 }, + "enterprise-procurement", + "Enterprise Procurement", + { "depth": 33, "slug": 11919, "text": 11920 }, + "free-tier-pwa", + "Free Tier (PWA)", + { "depth": 33, "slug": 4477, "text": 4478 }, + { "depth": 79, "slug": 11923, "text": 11924 }, + "pwa-to-standard", + "PWA to Standard", + { "depth": 79, "slug": 11926, "text": 11927 }, + "standard-to-team", + "Standard to Team", + { "depth": 33, "slug": 11929, "text": 11930 }, + "cancellation", + "Cancellation", + { "depth": 33, "slug": 11932, "text": 11933 }, + "competitor-comparison", + "Competitor Comparison", + { "depth": 79, "slug": 11935, "text": 11936 }, + "variscout-advantages", + "VariScout Advantages", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11865 }, + [], + "08-products/azure/storage", + { + "id": 11942, + "data": 11944, + "body": 11949, + "filePath": 11950, + "digest": 11951, + "rendered": 11952 + }, + { + "title": 11945, + "editUrl": 16, + "head": 11946, + "template": 18, + "sidebar": 11947, + "pagefind": 16, + "draft": 20 + }, + "Azure App Storage", + [], + { "hidden": 20, "attrs": 11948 }, + {}, + "# Azure App Storage\n\nOffline-first persistence with optional OneDrive cloud sync (Team plan).\n\n---\n\n## Overview\n\nStorage behavior depends on the plan:\n\n- **Standard plan (€99/month)**: Local-only storage via **IndexedDB** (Dexie.js). All projects are saved and loaded from the browser. No cloud sync.\n- **Team plan (€299/month)**: Two-tier storage — **IndexedDB** (local, instant) + **OneDrive** (cloud, async) via Microsoft Graph API. Every save writes to IndexedDB first, then syncs to OneDrive when online. Loads prefer the cloud version (fresher) and fall back to local when offline.\n\nBoth plans use IndexedDB as the primary persistence layer. The Team plan adds OneDrive sync on top.\n\n---\n\n## IndexedDB Schema\n\nDatabase name: `VaRiScoutAzure` (Dexie.js)\n\n| Table | Key | Columns | Purpose |\n| ----------- | ------ | ----------------------------------------- | -------------------- |\n| `projects` | `name` | `location`, `modified`, `synced`, `data` | Local project cache |\n| `syncQueue` | `++id` | `name`, `location`, `project`, `queuedAt` | Offline change queue |\n| `syncState` | `name` | `cloudId`, `lastSynced`, `etag` | Cloud sync tracking |\n\nSource: `apps/azure/src/db/schema.ts`\n\n---\n\n## Save Flow\n\n> The cloud sync steps below apply to the **Team plan only**. Standard plan saves to IndexedDB and stops.\n\n```\nUser clicks Save\n │\n ▼\nsaveToIndexedDB() ← instant, always succeeds (both plans)\n │\n ├── Online? ──Yes──▶ saveToCloud() via Graph API PUT (Team plan only)\n │ │\n │ ├── Success → markAsSynced() → status: 'synced'\n │ └── Failure → addToSyncQueue() → status: 'offline'\n │\n └── Offline ──────▶ addToSyncQueue() → status: 'offline' (Team plan only)\n```\n\n---\n\n## Load Flow\n\n> The cloud load steps below apply to the **Team plan only**. Standard plan loads from IndexedDB directly.\n\n```\nloadProject(name)\n │\n ├── Online? ──Yes──▶ loadFromCloud() via Graph API GET (Team plan only)\n │ │\n │ ├── Found → cache to IndexedDB → return\n │ └── Error → fall through to local\n │\n └── Fallback ──────▶ loadFromIndexedDB() → return (both plans)\n```\n\n---\n\n## Sync Triggers (Team Plan Only)\n\nSync to OneDrive happens on:\n\n| Trigger | Behavior |\n| -------------- | ------------------------------------------------------- |\n| User save | Immediate cloud save (if online) |\n| `online` event | Flush entire sync queue |\n| App mount | Prune stale queue items (>30 days), then sync if online |\n\nThere is **no periodic polling** — sync is event-driven only.\n\n---\n\n## StorageProvider (Singleton Context)\n\nAll storage operations are centralized in a single `StorageProvider` React context mounted in `App.tsx`. This replaced the previous pattern where multiple `useStorage()` hook instances created independent sync loops.\n\n```\nApp.tsx\n └── StorageProvider ← single instance\n ├── syncStatus ← shared sync state\n ├── notifications[] ← toast queue\n ├── retryQueue ← exponential backoff\n ├── saveProject() ← IndexedDB + cloud\n ├── loadProject() ← cloud-first + conflict detection\n └── listProjects() ← merged local + cloud\n```\n\nAll consumers access via `useStorage()` hook and receive the same sync state, notification queue, and retry management.\n\nSource: `apps/azure/src/services/storage.ts`\n\n---\n\n## Sync Status States (Team Plan Only)\n\n| Status | Meaning |\n| ---------- | ----------------------------------------------------------------- |\n| `saved` | Written to IndexedDB (initial state) |\n| `syncing` | Cloud save or queue flush in progress |\n| `synced` | Cloud and local are in agreement |\n| `offline` | Saved locally, pending cloud sync |\n| `conflict` | Local and cloud diverged — cloud version loaded (last-write-wins) |\n| `error` | Cloud operation failed (e.g. auth expired) |\n\n---\n\n## OneDrive File Structure (Team Plan Only)\n\n```\nOneDrive/\n└── VariScout/\n └── Projects/\n ├── analysis-001.vrs (JSON, AnalysisState)\n ├── analysis-002.vrs\n └── ...\n```\n\nFiles are `.vrs` extension, containing JSON-serialized `AnalysisState` (see `docs/03-features/data/storage.md`).\n\n---\n\n## What Is Preserved\n\n| Data | Storage | Synced to Cloud (Team) |\n| -------------------- | ------------ | ---------------------- |\n| Project data + state | IndexedDB | Yes |\n| Filter stack | In project | Yes |\n| Regression state | In project | Yes |\n| View state | In project | Yes |\n| Chart titles | In project | Yes |\n| Display options | localStorage | No |\n| Theme preference | localStorage | No |\n| Company accent | localStorage | No |\n\n> Standard plan stores all project data in IndexedDB only. The \"Synced to Cloud\" column applies to the Team plan.\n\n---\n\n## Queue Pruning (Team Plan Only)\n\nStale sync queue items (older than 30 days) are pruned on app mount via `pruneSyncQueue()`. This prevents unbounded queue growth if the user is offline for extended periods.\n\n---\n\n## See Also\n\n- [OneDrive Sync](onedrive-sync.md) — Graph API calls, conflict resolution\n- [Authentication (EasyAuth)](authentication.md) — Token acquisition\n- [Project Persistence](../../03-features/data/storage.md) — AnalysisState format\n- [PWA Session Model](../pwa/storage.md) — PWA has no persistence (by design)", + "src/content/docs/08-products/azure/storage.md", + "9950337f6b7d4210", + { "html": 11953, "metadata": 11954 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"azure-app-storage\">Azure App Storage\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#azure-app-storage\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure App Storage”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Offline-first persistence with optional OneDrive cloud sync (Team plan).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Storage behavior depends on the plan:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Standard plan (€99/month)\u003C/strong>: Local-only storage via \u003Cstrong>IndexedDB\u003C/strong> (Dexie.js). All projects are saved and loaded from the browser. No cloud sync.\u003C/li>\n\u003Cli>\u003Cstrong>Team plan (€299/month)\u003C/strong>: Two-tier storage — \u003Cstrong>IndexedDB\u003C/strong> (local, instant) + \u003Cstrong>OneDrive\u003C/strong> (cloud, async) via Microsoft Graph API. Every save writes to IndexedDB first, then syncs to OneDrive when online. Loads prefer the cloud version (fresher) and fall back to local when offline.\u003C/li>\n\u003C/ul>\n\u003Cp>Both plans use IndexedDB as the primary persistence layer. The Team plan adds OneDrive sync on top.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"indexeddb-schema\">IndexedDB Schema\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#indexeddb-schema\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “IndexedDB Schema”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Database name: \u003Ccode dir=\"auto\">VaRiScoutAzure\u003C/code> (Dexie.js)\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Table\u003C/th>\u003Cth>Key\u003C/th>\u003Cth>Columns\u003C/th>\u003Cth>Purpose\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">projects\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">name\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">location\u003C/code>, \u003Ccode dir=\"auto\">modified\u003C/code>, \u003Ccode dir=\"auto\">synced\u003C/code>, \u003Ccode dir=\"auto\">data\u003C/code>\u003C/td>\u003Ctd>Local project cache\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">syncQueue\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">++id\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">name\u003C/code>, \u003Ccode dir=\"auto\">location\u003C/code>, \u003Ccode dir=\"auto\">project\u003C/code>, \u003Ccode dir=\"auto\">queuedAt\u003C/code>\u003C/td>\u003Ctd>Offline change queue\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">syncState\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">name\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">cloudId\u003C/code>, \u003Ccode dir=\"auto\">lastSynced\u003C/code>, \u003Ccode dir=\"auto\">etag\u003C/code>\u003C/td>\u003Ctd>Cloud sync tracking\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Source: \u003Ccode dir=\"auto\">apps/azure/src/db/schema.ts\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"save-flow\">Save Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#save-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Save Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>The cloud sync steps below apply to the \u003Cstrong>Team plan only\u003C/strong>. Standard plan saves to IndexedDB and stops.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">User clicks Save\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">saveToIndexedDB() ← instant, always succeeds (both plans)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Online? ──Yes──▶ saveToCloud() via Graph API PUT (Team plan only)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Success → markAsSynced() → status: 'synced'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Failure → addToSyncQueue() → status: 'offline'\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Offline ──────▶ addToSyncQueue() → status: 'offline' (Team plan only)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"User clicks Save │ ▼saveToIndexedDB() ← instant, always succeeds (both plans) │ ├── Online? ──Yes──▶ saveToCloud() via Graph API PUT (Team plan only) │ │ │ ├── Success → markAsSynced() → status: 'synced' │ └── Failure → addToSyncQueue() → status: 'offline' │ └── Offline ──────▶ addToSyncQueue() → status: 'offline' (Team plan only)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"load-flow\">Load Flow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#load-flow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Load Flow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>The cloud load steps below apply to the \u003Cstrong>Team plan only\u003C/strong>. Standard plan loads from IndexedDB directly.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">loadProject(name)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Online? ──Yes──▶ loadFromCloud() via Graph API GET (Team plan only)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ├── Found → cache to IndexedDB → return\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── Error → fall through to local\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Fallback ──────▶ loadFromIndexedDB() → return (both plans)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"loadProject(name) │ ├── Online? ──Yes──▶ loadFromCloud() via Graph API GET (Team plan only) │ │ │ ├── Found → cache to IndexedDB → return │ └── Error → fall through to local │ └── Fallback ──────▶ loadFromIndexedDB() → return (both plans)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sync-triggers-team-plan-only\">Sync Triggers (Team Plan Only)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sync-triggers-team-plan-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sync Triggers (Team Plan Only)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Sync to OneDrive happens on:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Trigger\u003C/th>\u003Cth>Behavior\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>User save\u003C/td>\u003Ctd>Immediate cloud save (if online)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">online\u003C/code> event\u003C/td>\u003Ctd>Flush entire sync queue\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>App mount\u003C/td>\u003Ctd>Prune stale queue items (>30 days), then sync if online\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>There is \u003Cstrong>no periodic polling\u003C/strong> — sync is event-driven only.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"storageprovider-singleton-context\">StorageProvider (Singleton Context)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#storageprovider-singleton-context\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “StorageProvider (Singleton Context)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All storage operations are centralized in a single \u003Ccode dir=\"auto\">StorageProvider\u003C/code> React context mounted in \u003Ccode dir=\"auto\">App.tsx\u003C/code>. This replaced the previous pattern where multiple \u003Ccode dir=\"auto\">useStorage()\u003C/code> hook instances created independent sync loops.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">App.tsx\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── StorageProvider ← single instance\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── syncStatus ← shared sync state\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── notifications[] ← toast queue\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── retryQueue ← exponential backoff\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── saveProject() ← IndexedDB + cloud\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── loadProject() ← cloud-first + conflict detection\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── listProjects() ← merged local + cloud\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"App.tsx └── StorageProvider ← single instance ├── syncStatus ← shared sync state ├── notifications[] ← toast queue ├── retryQueue ← exponential backoff ├── saveProject() ← IndexedDB + cloud ├── loadProject() ← cloud-first + conflict detection └── listProjects() ← merged local + cloud\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>All consumers access via \u003Ccode dir=\"auto\">useStorage()\u003C/code> hook and receive the same sync state, notification queue, and retry management.\u003C/p>\n\u003Cp>Source: \u003Ccode dir=\"auto\">apps/azure/src/services/storage.ts\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sync-status-states-team-plan-only\">Sync Status States (Team Plan Only)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sync-status-states-team-plan-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sync Status States (Team Plan Only)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Status\u003C/th>\u003Cth>Meaning\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">saved\u003C/code>\u003C/td>\u003Ctd>Written to IndexedDB (initial state)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">syncing\u003C/code>\u003C/td>\u003Ctd>Cloud save or queue flush in progress\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">synced\u003C/code>\u003C/td>\u003Ctd>Cloud and local are in agreement\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">offline\u003C/code>\u003C/td>\u003Ctd>Saved locally, pending cloud sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">conflict\u003C/code>\u003C/td>\u003Ctd>Local and cloud diverged — cloud version loaded (last-write-wins)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">error\u003C/code>\u003C/td>\u003Ctd>Cloud operation failed (e.g. auth expired)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"onedrive-file-structure-team-plan-only\">OneDrive File Structure (Team Plan Only)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#onedrive-file-structure-team-plan-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “OneDrive File Structure (Team Plan Only)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">OneDrive/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── VariScout/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Projects/\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── analysis-001.vrs (JSON, AnalysisState)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── analysis-002.vrs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── ...\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"OneDrive/└── VariScout/ └── Projects/ ├── analysis-001.vrs (JSON, AnalysisState) ├── analysis-002.vrs └── ...\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Files are \u003Ccode dir=\"auto\">.vrs\u003C/code> extension, containing JSON-serialized \u003Ccode dir=\"auto\">AnalysisState\u003C/code> (see \u003Ccode dir=\"auto\">docs/03-features/data/storage.md\u003C/code>).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-is-preserved\">What Is Preserved\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-is-preserved\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What Is Preserved”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Data\u003C/th>\u003Cth>Storage\u003C/th>\u003Cth>Synced to Cloud (Team)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Project data + state\u003C/td>\u003Ctd>IndexedDB\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filter stack\u003C/td>\u003Ctd>In project\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regression state\u003C/td>\u003Ctd>In project\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>View state\u003C/td>\u003Ctd>In project\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Chart titles\u003C/td>\u003Ctd>In project\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Display options\u003C/td>\u003Ctd>localStorage\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Theme preference\u003C/td>\u003Ctd>localStorage\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Company accent\u003C/td>\u003Ctd>localStorage\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cblockquote>\n\u003Cp>Standard plan stores all project data in IndexedDB only. The “Synced to Cloud” column applies to the Team plan.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"queue-pruning-team-plan-only\">Queue Pruning (Team Plan Only)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#queue-pruning-team-plan-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Queue Pruning (Team Plan Only)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Stale sync queue items (older than 30 days) are pruned on app mount via \u003Ccode dir=\"auto\">pruneSyncQueue()\u003C/code>. This prevents unbounded queue growth if the user is offline for extended periods.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"onedrive-sync.md\">OneDrive Sync\u003C/a> — Graph API calls, conflict resolution\u003C/li>\n\u003Cli>\u003Ca href=\"authentication.md\">Authentication (EasyAuth)\u003C/a> — Token acquisition\u003C/li>\n\u003Cli>\u003Ca href=\"../../03-features/data/storage.md\">Project Persistence\u003C/a> — AnalysisState format\u003C/li>\n\u003Cli>\u003Ca href=\"../pwa/storage.md\">PWA Session Model\u003C/a> — PWA has no persistence (by design)\u003C/li>\n\u003C/ul>", + { + "headings": 11955, + "localImagePaths": 11987, + "remoteImagePaths": 11988, + "frontmatter": 11989, + "imagePaths": 11990 + }, + [11956, 11958, 11959, 11962, 11965, 11968, 11971, 11974, 11977, 11980, 11983, 11986], + { "depth": 30, "slug": 11957, "text": 11945 }, + "azure-app-storage", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 11960, "text": 11961 }, + "indexeddb-schema", + "IndexedDB Schema", + { "depth": 33, "slug": 11963, "text": 11964 }, + "save-flow", + "Save Flow", + { "depth": 33, "slug": 11966, "text": 11967 }, + "load-flow", + "Load Flow", + { "depth": 33, "slug": 11969, "text": 11970 }, + "sync-triggers-team-plan-only", + "Sync Triggers (Team Plan Only)", + { "depth": 33, "slug": 11972, "text": 11973 }, + "storageprovider-singleton-context", + "StorageProvider (Singleton Context)", + { "depth": 33, "slug": 11975, "text": 11976 }, + "sync-status-states-team-plan-only", + "Sync Status States (Team Plan Only)", + { "depth": 33, "slug": 11978, "text": 11979 }, + "onedrive-file-structure-team-plan-only", + "OneDrive File Structure (Team Plan Only)", + { "depth": 33, "slug": 11981, "text": 11982 }, + "what-is-preserved", + "What Is Preserved", + { "depth": 33, "slug": 11984, "text": 11985 }, + "queue-pruning-team-plan-only", + "Queue Pruning (Team Plan Only)", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11945 }, + [], + "08-products/azure/submission-checklist", + { + "id": 11991, + "data": 11993, + "body": 11998, + "filePath": 11999, + "digest": 12000, + "rendered": 12001 + }, + { + "title": 11994, + "editUrl": 16, + "head": 11995, + "template": 18, + "sidebar": 11996, + "pagefind": 16, + "draft": 20 + }, + "Azure Marketplace Submission Checklist", + [], + { "hidden": 20, "attrs": 11997 }, + {}, + "# Azure Marketplace Submission Checklist\n\nLiving tracker for Azure Marketplace Managed Application submission. Single source of truth for what's done, what's pending, and what's blocking.\n\n**Target offer type:** Azure Application → Managed Application\n**Pricing:** Two plans: Standard €99/month, Team €299/month\n\n---\n\n## 1. Partner Center Account\n\n| Item | Status | Notes |\n| ------------------------------------------------------------ | -------------- | ---------------------------------------- |\n| Register at [Partner Center](https://partner.microsoft.com/) | ⬜ Not started | Need Microsoft account for RDMAIC Oy |\n| Complete publisher profile | ⬜ Not started | Company name, logo, description |\n| Verify bank account for payouts | ⬜ Not started | Finnish IBAN, may take 2–5 business days |\n| Accept Marketplace Publisher Agreement | ⬜ Not started | Legal review before accepting |\n| Accept Microsoft App Certification Policies | ⬜ Not started | |\n\n---\n\n## 2. Technical Package\n\n| Item | Status | Notes |\n| --------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------- |\n| `mainTemplate.json` written | ✅ Done | `infra/mainTemplate.json` — App Service + EasyAuth, customer-provided App Registration |\n| `createUiDefinition.json` written | ✅ Done | `infra/createUiDefinition.json` — portal wizard with Authentication step (clientId + clientSecret) |\n| ARM TTK validation passes | ⚠️ Manual review passed | `apiVersion` updated to `2025-01-01` (valid until Jan 2028); automated `Test-AzTemplate` needs PowerShell |\n| CUID tracking | ✅ Auto-injected | Partner Center auto-injects tracking ID at publish time (no nested deployments) |\n| Package URL parameterized | ✅ Done | `packageUrl` parameter with default — satisfies arm-ttk no-hardcoded-URI rule |\n| createUiDefinition sandbox test | ⬜ Not tested | Test at `https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/SandboxBlade` |\n| Package `.zip` created | ⬜ Not done | Zip `mainTemplate.json` + `createUiDefinition.json` → `variscout-managed-app.zip` |\n| Publisher management disabled | ✅ Done | ARM template sets no publisher access to managed RG |\n| Customer access enabled | ✅ Done | Full customer control over deployed resources |\n\n---\n\n## 3. Build Hosting\n\nThe ARM template uses `WEBSITE_RUN_FROM_PACKAGE` to deploy the app as a static zip. The zip URL must be publicly accessible at deployment time.\n\n| Item | Status | Notes |\n| --------------------------------------- | ----------- | ----------------------------------------------------------------- |\n| Azure Storage account created | ⬜ Not done | For hosting the app build `.zip` |\n| Blob container with public read access | ⬜ Not done | Or use SAS token URL |\n| Production build uploaded | ⬜ Not done | `pnpm --filter @variscout/azure-app build` → zip `dist/` → upload |\n| `WEBSITE_RUN_FROM_PACKAGE` URL verified | ⬜ Not done | Confirm URL downloads correctly |\n| URL referenced in ARM template | ⬜ Not done | Update `packageUrl` in `mainTemplate.json` |\n\n---\n\n## 4. Legal\n\n| Item | Status | Notes |\n| ------------------------------------- | --------------------- | -------------------------------------------------------------------------- |\n| Privacy policy page live | ✅ Done | `apps/website/src/pages/legal/privacy.astro` → variscout.com/legal/privacy |\n| Terms of use page live | ✅ Done | `apps/website/src/pages/legal/terms.astro` → variscout.com/legal/terms |\n| Support contact defined | ✅ Done | hello@variscout.com |\n| RDMAIC Oy company details on pages | ✅ Done | Helsinki, Finland on both pages |\n| Privacy policy URL accessible (HTTPS) | ⬜ Needs verification | Confirm live URL returns 200 |\n| Terms URL accessible (HTTPS) | ⬜ Needs verification | Confirm live URL returns 200 |\n\n---\n\n## 5. Listing Content\n\n| Item | Status | Notes |\n| ------------------------------------ | -------------- | --------------------------------------------------------------------------------- |\n| Offer name | ✅ Draft ready | \"VariScout - Statistical Process Control for Quality Teams\" |\n| Short description (≤100 chars) | ✅ Draft ready | See `marketplace.md` |\n| Long description (≤3000 chars) | ✅ Draft ready | See `marketplace.md` — review before submission |\n| Logo (216×216 PNG) | ⬜ Not done | Required for Partner Center listing |\n| Logo (48×48 PNG) | ⬜ Not done | Small icon for search results |\n| Screenshots (5–10, min 1280×720 PNG) | ⬜ Not done | Performance Dashboard, I-Chart, Capability, Boxplot, Pareto, Drill-Down, OneDrive |\n| Video (optional) | ⬜ Not started | 2–3 min product overview recommended |\n| Categories selected | ⬜ Not done | Analytics, Business Intelligence, or IT & Management Tools |\n| Search keywords | ⬜ Not done | SPC, quality control, statistical process control, Cpk, variation |\n\n---\n\n## 6. App Readiness\n\n| Item | Status | Notes |\n| ------------------------------------- | --------------------- | ------------------------------------------------------------------- |\n| EasyAuth login works | ✅ Done | `apps/azure/src/auth/easyAuth.ts` — tested locally with mock |\n| OneDrive save/load works | ✅ Done | `apps/azure/src/services/storage.ts` — Graph API via EasyAuth token |\n| All chart types render | ✅ Done | I-Chart, Boxplot, Pareto, Capability, Performance charts |\n| Performance Mode works | ✅ Done | Multi-channel Cpk analysis |\n| CSV/Excel file upload works | ✅ Done | Parser in `@variscout/core` |\n| CSV export works | ✅ Done | `downloadCSV` in `@variscout/core` |\n| Theme switching works | ✅ Done | Light/dark/system via ThemeContext |\n| Sample datasets load | ✅ Done | Via `@variscout/data` package |\n| Manual data entry works | ✅ Done | ManualEntryBase from `@variscout/ui` |\n| Production build succeeds | ✅ Done | `pnpm --filter @variscout/azure-app build` |\n| No console errors in production build | ⬜ Needs verification | Run build and check browser console |\n| `npm audit` clean | ⬜ Needs verification | No high/critical vulnerabilities in production dependencies |\n| CSP headers verified | ⬜ Needs verification | Content Security Policy appropriate for SPA + Graph API calls |\n\n---\n\n## 7. Deployment Validation\n\n| Item | Status | Notes |\n| ----------------------------------------- | ----------- | -------------------------------------------------- |\n| Deploy ARM template to fresh subscription | ⬜ Not done | End-to-end test in clean Azure environment |\n| App loads after deployment | ⬜ Not done | Verify `WEBSITE_RUN_FROM_PACKAGE` serves the app |\n| EasyAuth redirects to Azure AD login | ⬜ Not done | Verify unauthenticated → login flow |\n| Post-login app is fully functional | ⬜ Not done | Upload data, view charts, save to OneDrive |\n| OneDrive sync works post-deployment | ⬜ Not done | Save analysis, close, reopen, verify data persists |\n| createUiDefinition renders in portal | ⬜ Not done | Test via sandbox blade |\n| Deployment completes in \u003C10 minutes | ⬜ Not done | Microsoft may flag slow deployments |\n\n---\n\n## 8. Post-Submission\n\n| Item | Timeline | Notes |\n| --------------------- | --------- | ------------------------------------------------------------------ |\n| Automated validation | Day 1–2 | arm-ttk, CUID injection, package structure, JSON schema |\n| Content review | Day 2–5 | Listing text, pricing, policies, screenshots (manual) |\n| Security scan | Day 3–7 | Malware scan, network monitoring, dependency vulnerabilities |\n| Functionality test | Day 5–10 | Microsoft deploys via marketplace flow, verifies app loads + works |\n| Go-live (if approved) | Day 10–14 | Offer visible in Azure Marketplace |\n\n### Common Rejection Fixes\n\n| Issue | Fix |\n| --------------------------------- | ------------------------------------------------------- |\n| Invalid ARM template | Run `arm-ttk` validation, fix all warnings |\n| `apiVersion` too old | Must be ≤24 months old; currently `2025-01-01` |\n| Hardcoded URIs in template | Use parameters with defaults (done for `packageUrl`) |\n| CUID tracking missing | Auto-injected by Partner Center — no manual action |\n| Invalid createUiDefinition | Test in sandbox, ensure all controls render |\n| Missing/broken privacy policy URL | Verify HTTPS URL returns 200 |\n| Screenshot quality too low | Minimum 1280×720, PNG format, no browser chrome |\n| Description too short or vague | Expand feature descriptions, add use cases |\n| Support contact incomplete | Add email and response-time commitment (24h) |\n| npm vulnerabilities | Run `npm audit` and resolve high/critical before submit |\n\n---\n\n## Quick Reference\n\n```bash\n# Validate ARM template (requires arm-ttk)\nTest-AzTemplate -TemplatePath infra/mainTemplate.json\n\n# Test createUiDefinition in Azure portal sandbox\n# https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/SandboxBlade\n\n# Build Azure app for production\npnpm --filter @variscout/azure-app build\n\n# Create deployment package\ncd infra && zip variscout-managed-app.zip mainTemplate.json createUiDefinition.json\n\n# Run all tests before submission\npnpm test\n```\n\n---\n\n## See Also\n\n- [Certification Guide](certification-guide.md) — what Microsoft evaluates during review (3-layer breakdown)\n- [Marketplace Guide](marketplace.md) — offer type, pricing, listing content\n- [ARM Template](arm-template.md) — full template documentation\n- [Authentication](authentication.md) — EasyAuth setup and configuration\n- [OneDrive Sync](onedrive-sync.md) — storage integration details\n- [ADR-007](../../07-decisions/adr-007-azure-marketplace-distribution.md) — distribution strategy decision", + "src/content/docs/08-products/azure/submission-checklist.md", + "eb9d0b7941cd68ee", + { "html": 12002, "metadata": 12003 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"azure-marketplace-submission-checklist\">Azure Marketplace Submission Checklist\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#azure-marketplace-submission-checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Azure Marketplace Submission Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Living tracker for Azure Marketplace Managed Application submission. Single source of truth for what’s done, what’s pending, and what’s blocking.\u003C/p>\n\u003Cp>\u003Cstrong>Target offer type:\u003C/strong> Azure Application → Managed Application\n\u003Cstrong>Pricing:\u003C/strong> Two plans: Standard €99/month, Team €299/month\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"1-partner-center-account\">1. Partner Center Account\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#1-partner-center-account\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Partner Center Account”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Item\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Register at \u003Ca href=\"https://partner.microsoft.com/\">Partner Center\u003C/a>\u003C/td>\u003Ctd>⬜ Not started\u003C/td>\u003Ctd>Need Microsoft account for RDMAIC Oy\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Complete publisher profile\u003C/td>\u003Ctd>⬜ Not started\u003C/td>\u003Ctd>Company name, logo, description\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Verify bank account for payouts\u003C/td>\u003Ctd>⬜ Not started\u003C/td>\u003Ctd>Finnish IBAN, may take 2–5 business days\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Accept Marketplace Publisher Agreement\u003C/td>\u003Ctd>⬜ Not started\u003C/td>\u003Ctd>Legal review before accepting\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Accept Microsoft App Certification Policies\u003C/td>\u003Ctd>⬜ Not started\u003C/td>\u003Ctd>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"2-technical-package\">2. Technical Package\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#2-technical-package\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Technical Package”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Item\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">mainTemplate.json\u003C/code> written\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/mainTemplate.json\u003C/code> — App Service + EasyAuth, customer-provided App Registration\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">createUiDefinition.json\u003C/code> written\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">infra/createUiDefinition.json\u003C/code> — portal wizard with Authentication step (clientId + clientSecret)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ARM TTK validation passes\u003C/td>\u003Ctd>⚠️ Manual review passed\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apiVersion\u003C/code> updated to \u003Ccode dir=\"auto\">2025-01-01\u003C/code> (valid until Jan 2028); automated \u003Ccode dir=\"auto\">Test-AzTemplate\u003C/code> needs PowerShell\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CUID tracking\u003C/td>\u003Ctd>✅ Auto-injected\u003C/td>\u003Ctd>Partner Center auto-injects tracking ID at publish time (no nested deployments)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Package URL parameterized\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packageUrl\u003C/code> parameter with default — satisfies arm-ttk no-hardcoded-URI rule\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>createUiDefinition sandbox test\u003C/td>\u003Ctd>⬜ Not tested\u003C/td>\u003Ctd>Test at \u003Ccode dir=\"auto\">https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/SandboxBlade\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Package \u003Ccode dir=\"auto\">.zip\u003C/code> created\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Zip \u003Ccode dir=\"auto\">mainTemplate.json\u003C/code> + \u003Ccode dir=\"auto\">createUiDefinition.json\u003C/code> → \u003Ccode dir=\"auto\">variscout-managed-app.zip\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Publisher management disabled\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>ARM template sets no publisher access to managed RG\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Customer access enabled\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>Full customer control over deployed resources\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"3-build-hosting\">3. Build Hosting\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#3-build-hosting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Build Hosting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The ARM template uses \u003Ccode dir=\"auto\">WEBSITE_RUN_FROM_PACKAGE\u003C/code> to deploy the app as a static zip. The zip URL must be publicly accessible at deployment time.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Item\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Azure Storage account created\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>For hosting the app build \u003Ccode dir=\"auto\">.zip\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Blob container with public read access\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Or use SAS token URL\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Production build uploaded\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">pnpm --filter @variscout/azure-app build\u003C/code> → zip \u003Ccode dir=\"auto\">dist/\u003C/code> → upload\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">WEBSITE_RUN_FROM_PACKAGE\u003C/code> URL verified\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Confirm URL downloads correctly\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>URL referenced in ARM template\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Update \u003Ccode dir=\"auto\">packageUrl\u003C/code> in \u003Ccode dir=\"auto\">mainTemplate.json\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-legal\">4. Legal\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-legal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Legal”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Item\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Privacy policy page live\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/website/src/pages/legal/privacy.astro\u003C/code> → variscout.com/legal/privacy\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Terms of use page live\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/website/src/pages/legal/terms.astro\u003C/code> → variscout.com/legal/terms\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Support contact defined\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>\u003Ca href=\"mailto:hello@variscout.com\">hello@variscout.com\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>RDMAIC Oy company details on pages\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>Helsinki, Finland on both pages\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Privacy policy URL accessible (HTTPS)\u003C/td>\u003Ctd>⬜ Needs verification\u003C/td>\u003Ctd>Confirm live URL returns 200\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Terms URL accessible (HTTPS)\u003C/td>\u003Ctd>⬜ Needs verification\u003C/td>\u003Ctd>Confirm live URL returns 200\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"5-listing-content\">5. Listing Content\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#5-listing-content\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Listing Content”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Item\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Offer name\u003C/td>\u003Ctd>✅ Draft ready\u003C/td>\u003Ctd>”VariScout - Statistical Process Control for Quality Teams”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Short description (≤100 chars)\u003C/td>\u003Ctd>✅ Draft ready\u003C/td>\u003Ctd>See \u003Ccode dir=\"auto\">marketplace.md\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Long description (≤3000 chars)\u003C/td>\u003Ctd>✅ Draft ready\u003C/td>\u003Ctd>See \u003Ccode dir=\"auto\">marketplace.md\u003C/code> — review before submission\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Logo (216×216 PNG)\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Required for Partner Center listing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Logo (48×48 PNG)\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Small icon for search results\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Screenshots (5–10, min 1280×720 PNG)\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Performance Dashboard, I-Chart, Capability, Boxplot, Pareto, Drill-Down, OneDrive\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Video (optional)\u003C/td>\u003Ctd>⬜ Not started\u003C/td>\u003Ctd>2–3 min product overview recommended\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Categories selected\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Analytics, Business Intelligence, or IT & Management Tools\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Search keywords\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>SPC, quality control, statistical process control, Cpk, variation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"6-app-readiness\">6. App Readiness\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#6-app-readiness\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. App Readiness”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Item\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>EasyAuth login works\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/azure/src/auth/easyAuth.ts\u003C/code> — tested locally with mock\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OneDrive save/load works\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/azure/src/services/storage.ts\u003C/code> — Graph API via EasyAuth token\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>All chart types render\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>I-Chart, Boxplot, Pareto, Capability, Performance charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Mode works\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>Multi-channel Cpk analysis\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CSV/Excel file upload works\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>Parser in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CSV export works\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">downloadCSV\u003C/code> in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Theme switching works\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>Light/dark/system via ThemeContext\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sample datasets load\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>Via \u003Ccode dir=\"auto\">@variscout/data\u003C/code> package\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Manual data entry works\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>ManualEntryBase from \u003Ccode dir=\"auto\">@variscout/ui\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Production build succeeds\u003C/td>\u003Ctd>✅ Done\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">pnpm --filter @variscout/azure-app build\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No console errors in production build\u003C/td>\u003Ctd>⬜ Needs verification\u003C/td>\u003Ctd>Run build and check browser console\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">npm audit\u003C/code> clean\u003C/td>\u003Ctd>⬜ Needs verification\u003C/td>\u003Ctd>No high/critical vulnerabilities in production dependencies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CSP headers verified\u003C/td>\u003Ctd>⬜ Needs verification\u003C/td>\u003Ctd>Content Security Policy appropriate for SPA + Graph API calls\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"7-deployment-validation\">7. Deployment Validation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#7-deployment-validation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “7. Deployment Validation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Item\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Deploy ARM template to fresh subscription\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>End-to-end test in clean Azure environment\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>App loads after deployment\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Verify \u003Ccode dir=\"auto\">WEBSITE_RUN_FROM_PACKAGE\u003C/code> serves the app\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>EasyAuth redirects to Azure AD login\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Verify unauthenticated → login flow\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Post-login app is fully functional\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Upload data, view charts, save to OneDrive\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OneDrive sync works post-deployment\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Save analysis, close, reopen, verify data persists\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>createUiDefinition renders in portal\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Test via sandbox blade\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Deployment completes in <10 minutes\u003C/td>\u003Ctd>⬜ Not done\u003C/td>\u003Ctd>Microsoft may flag slow deployments\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"8-post-submission\">8. Post-Submission\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#8-post-submission\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “8. Post-Submission”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Item\u003C/th>\u003Cth>Timeline\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Automated validation\u003C/td>\u003Ctd>Day 1–2\u003C/td>\u003Ctd>arm-ttk, CUID injection, package structure, JSON schema\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Content review\u003C/td>\u003Ctd>Day 2–5\u003C/td>\u003Ctd>Listing text, pricing, policies, screenshots (manual)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Security scan\u003C/td>\u003Ctd>Day 3–7\u003C/td>\u003Ctd>Malware scan, network monitoring, dependency vulnerabilities\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Functionality test\u003C/td>\u003Ctd>Day 5–10\u003C/td>\u003Ctd>Microsoft deploys via marketplace flow, verifies app loads + works\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Go-live (if approved)\u003C/td>\u003Ctd>Day 10–14\u003C/td>\u003Ctd>Offer visible in Azure Marketplace\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"common-rejection-fixes\">Common Rejection Fixes\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#common-rejection-fixes\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Common Rejection Fixes”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Issue\u003C/th>\u003Cth>Fix\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Invalid ARM template\u003C/td>\u003Ctd>Run \u003Ccode dir=\"auto\">arm-ttk\u003C/code> validation, fix all warnings\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">apiVersion\u003C/code> too old\u003C/td>\u003Ctd>Must be ≤24 months old; currently \u003Ccode dir=\"auto\">2025-01-01\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hardcoded URIs in template\u003C/td>\u003Ctd>Use parameters with defaults (done for \u003Ccode dir=\"auto\">packageUrl\u003C/code>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CUID tracking missing\u003C/td>\u003Ctd>Auto-injected by Partner Center — no manual action\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Invalid createUiDefinition\u003C/td>\u003Ctd>Test in sandbox, ensure all controls render\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Missing/broken privacy policy URL\u003C/td>\u003Ctd>Verify HTTPS URL returns 200\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Screenshot quality too low\u003C/td>\u003Ctd>Minimum 1280×720, PNG format, no browser chrome\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Description too short or vague\u003C/td>\u003Ctd>Expand feature descriptions, add use cases\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Support contact incomplete\u003C/td>\u003Ctd>Add email and response-time commitment (24h)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>npm vulnerabilities\u003C/td>\u003Ctd>Run \u003Ccode dir=\"auto\">npm audit\u003C/code> and resolve high/critical before submit\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"quick-reference\">Quick Reference\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#quick-reference\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Quick Reference”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Validate ARM template (requires arm-ttk)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">Test-AzTemplate\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">-TemplatePath\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">infra/mainTemplate.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Test createUiDefinition in Azure portal sandbox\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/SandboxBlade\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build Azure app for production\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/azure-app\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Create deployment package\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">cd\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">infra\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> && \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">zip\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">variscout-managed-app.zip\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">mainTemplate.json\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">createUiDefinition.json\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run all tests before submission\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Test-AzTemplate -TemplatePath infra/mainTemplate.jsonpnpm --filter @variscout/azure-app buildcd infra && zip variscout-managed-app.zip mainTemplate.json createUiDefinition.jsonpnpm test\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"certification-guide.md\">Certification Guide\u003C/a> — what Microsoft evaluates during review (3-layer breakdown)\u003C/li>\n\u003Cli>\u003Ca href=\"marketplace.md\">Marketplace Guide\u003C/a> — offer type, pricing, listing content\u003C/li>\n\u003Cli>\u003Ca href=\"arm-template.md\">ARM Template\u003C/a> — full template documentation\u003C/li>\n\u003Cli>\u003Ca href=\"authentication.md\">Authentication\u003C/a> — EasyAuth setup and configuration\u003C/li>\n\u003Cli>\u003Ca href=\"onedrive-sync.md\">OneDrive Sync\u003C/a> — storage integration details\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a> — distribution strategy decision\u003C/li>\n\u003C/ul>", + { + "headings": 12004, + "localImagePaths": 12036, + "remoteImagePaths": 12037, + "frontmatter": 12038, + "imagePaths": 12039 + }, + [12005, 12007, 12010, 12013, 12016, 12019, 12022, 12025, 12028, 12031, 12034, 12035], + { "depth": 30, "slug": 12006, "text": 11994 }, + "azure-marketplace-submission-checklist", + { "depth": 33, "slug": 12008, "text": 12009 }, + "1-partner-center-account", + "1. Partner Center Account", + { "depth": 33, "slug": 12011, "text": 12012 }, + "2-technical-package", + "2. Technical Package", + { "depth": 33, "slug": 12014, "text": 12015 }, + "3-build-hosting", + "3. Build Hosting", + { "depth": 33, "slug": 12017, "text": 12018 }, + "4-legal", + "4. Legal", + { "depth": 33, "slug": 12020, "text": 12021 }, + "5-listing-content", + "5. Listing Content", + { "depth": 33, "slug": 12023, "text": 12024 }, + "6-app-readiness", + "6. App Readiness", + { "depth": 33, "slug": 12026, "text": 12027 }, + "7-deployment-validation", + "7. Deployment Validation", + { "depth": 33, "slug": 12029, "text": 12030 }, + "8-post-submission", + "8. Post-Submission", + { "depth": 79, "slug": 12032, "text": 12033 }, + "common-rejection-fixes", + "Common Rejection Fixes", + { "depth": 33, "slug": 1897, "text": 1898 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11994 }, + [], + "06-design-system/patterns/feedback", + { + "id": 12040, + "data": 12042, + "body": 12047, + "filePath": 12048, + "digest": 12049, + "rendered": 12050 + }, + { + "title": 12043, + "editUrl": 16, + "head": 12044, + "template": 18, + "sidebar": 12045, + "pagefind": 16, + "draft": 20 + }, + "Feedback Patterns", + [], + { "hidden": 20, "attrs": 12046 }, + {}, + "# Feedback Patterns\n\nStatus, loading, and error state patterns.\n\n## Loading States\n\n### Button Loading\n\n```jsx\n\u003Cbutton disabled className=\"flex items-center gap-2\">\n \u003CLoader2 className=\"animate-spin\" size={16} />\n Saving...\n\u003C/button>\n```\n\n### Full Page Loading\n\n```jsx\n\u003Cdiv className=\"flex items-center justify-center h-full\">\n \u003Cdiv className=\"flex flex-col items-center gap-4\">\n \u003CLoader2 className=\"animate-spin text-blue-500\" size={32} />\n \u003Cspan className=\"text-slate-400\">Loading data...\u003C/span>\n \u003C/div>\n\u003C/div>\n```\n\n### Skeleton Placeholder\n\n```jsx\n\u003Cdiv className=\"animate-pulse\">\n \u003Cdiv className=\"h-4 bg-slate-700 rounded w-3/4 mb-2\" />\n \u003Cdiv className=\"h-4 bg-slate-700 rounded w-1/2\" />\n\u003C/div>\n```\n\n## Empty States\n\n### No Data\n\n```jsx\n\u003Cdiv className=\"flex flex-col items-center justify-center h-full text-center p-8\">\n \u003CFileX className=\"text-slate-600 mb-4\" size={48} />\n \u003Ch3 className=\"text-lg font-semibold text-slate-300 mb-2\">No data loaded\u003C/h3>\n \u003Cp className=\"text-sm text-slate-500 mb-4\">Import a CSV or Excel file to get started\u003C/p>\n \u003Cbutton className=\"bg-blue-600 text-white px-4 py-2 rounded-lg\">Import Data\u003C/button>\n\u003C/div>\n```\n\n### No Results\n\n```jsx\n\u003Cdiv className=\"flex items-center justify-center h-full text-slate-500 text-sm\">\n No matching data found\n\u003C/div>\n```\n\n### No Selection\n\n```jsx\n\u003Cdiv className=\"flex items-center justify-center h-full text-slate-500\">\n Select an outcome variable to view analysis\n\u003C/div>\n```\n\n### Actionable Empty State\n\nFor chart panels that can be configured or hidden:\n\n```jsx\n\u003Cdiv className=\"flex flex-col items-center justify-center h-full text-slate-400\">\n \u003CBarChart3 className=\"opacity-50 mb-2\" size={32} />\n \u003Cp className=\"text-sm mb-3\">No Pareto data\u003C/p>\n \u003Cdiv className=\"flex gap-2\">\n \u003Cbutton className=\"text-xs px-3 py-1 bg-slate-700 rounded hover:bg-slate-600\">\n Select Factor\n \u003C/button>\n \u003Cbutton className=\"text-xs px-3 py-1 bg-slate-700 rounded hover:bg-slate-600\">Upload\u003C/button>\n \u003Cbutton className=\"text-xs px-3 py-1 bg-slate-700 rounded hover:bg-slate-600\">Hide\u003C/button>\n \u003C/div>\n\u003C/div>\n```\n\nUse when:\n\n- Chart requires data/configuration that isn't present\n- User should have options to configure, upload, or dismiss the panel\n- Hiding is temporary (resets on new data)\n\n## Success States\n\n### Inline Success\n\n```jsx\n\u003Cspan className=\"flex items-center gap-1 text-green-500 text-sm\">\n \u003CCheck size={14} />\n Saved successfully\n\u003C/span>\n```\n\n### Success Badge\n\n```jsx\n\u003Cspan className=\"inline-flex items-center gap-1 px-2 py-0.5 bg-green-500/20 text-green-400 rounded text-xs\">\n \u003CCheck size={12} />\n Pass\n\u003C/span>\n```\n\n## Error States\n\n### Inline Error\n\n```jsx\n\u003Cspan className=\"text-xs text-red-400 mt-1\">Invalid value entered\u003C/span>\n```\n\n### Error Card\n\n```jsx\n\u003Cdiv className=\"bg-red-500/10 border border-red-500/30 rounded-lg p-4\">\n \u003Cdiv className=\"flex items-start gap-3\">\n \u003CAlertCircle className=\"text-red-400 flex-shrink-0\" size={20} />\n \u003Cdiv>\n \u003Ch4 className=\"text-sm font-medium text-red-400\">Error loading data\u003C/h4>\n \u003Cp className=\"text-xs text-red-300/80 mt-1\">Please check the file format and try again.\u003C/p>\n \u003C/div>\n \u003C/div>\n\u003C/div>\n```\n\n### Error Boundary Fallback\n\n```jsx\n\u003Cdiv className=\"flex flex-col items-center justify-center h-full p-6 text-center\">\n \u003CAlertCircle className=\"text-red-400 mb-4\" size={32} />\n \u003Ch3 className=\"text-white font-medium mb-2\">Something went wrong\u003C/h3>\n \u003Cp className=\"text-sm text-slate-400 mb-4\">{componentName} failed to render\u003C/p>\n \u003Cbutton onClick={reset} className=\"text-blue-400 hover:underline\">\n Try again\n \u003C/button>\n\u003C/div>\n```\n\n## Warning States\n\n### Warning Banner\n\n```jsx\n\u003Cdiv className=\"bg-amber-500/10 border border-amber-500/30 rounded-lg p-3 flex items-center gap-3\">\n \u003CAlertTriangle className=\"text-amber-400 flex-shrink-0\" size={18} />\n \u003Cspan className=\"text-sm text-amber-200\">Large dataset may affect performance\u003C/span>\n\u003C/div>\n```\n\n## Status Badges\n\n```jsx\n// Pass (green)\n\u003Cspan className=\"px-2 py-0.5 bg-green-500/20 text-green-400 rounded text-xs font-medium\">\n Pass\n\u003C/span>\n\n// Fail (red)\n\u003Cspan className=\"px-2 py-0.5 bg-red-500/20 text-red-400 rounded text-xs font-medium\">\n Fail\n\u003C/span>\n\n// Warning (amber)\n\u003Cspan className=\"px-2 py-0.5 bg-amber-500/20 text-amber-400 rounded text-xs font-medium\">\n Warning\n\u003C/span>\n```\n\n## Copy Feedback\n\n```jsx\nconst [copied, setCopied] = useState(false);\n\nconst handleCopy = async () => {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n};\n\n\u003Cbutton className={copied ? 'text-green-400' : 'text-slate-400'}>\n {copied ? \u003CCheck size={16} /> : \u003CCopy size={16} />}\n\u003C/button>;\n```\n\n## Saving Indicator\n\n```jsx\n\u003Cspan className=\"flex items-center gap-2 text-xs text-slate-500\">\n {isSaving ? (\n \u003C>\n \u003CLoader2 className=\"animate-spin\" size={12} />\n Saving...\n \u003C/>\n ) : hasUnsavedChanges ? (\n \u003C>\n \u003Cspan className=\"w-2 h-2 bg-amber-500 rounded-full\" />\n Unsaved changes\n \u003C/>\n ) : (\n \u003C>\n \u003CCheck size={12} />\n Saved\n \u003C/>\n )}\n\u003C/span>\n```\n\n## Unsaved Changes Indicator\n\nShow asterisk after project name:\n\n```jsx\n\u003Cspan className=\"text-slate-500\">\n {projectName}\n {hasUnsavedChanges && ' *'}\n\u003C/span>\n```", + "src/content/docs/06-design-system/patterns/feedback.md", + "6b0c181e4aff5ce6", + { "html": 12051, "metadata": 12052 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"feedback-patterns\">Feedback Patterns\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#feedback-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feedback Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Status, loading, and error state patterns.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"loading-states\">Loading States\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#loading-states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Loading States”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"button-loading\">Button Loading\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#button-loading\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Button Loading”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">disabled\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center gap-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Loader2\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">animate-spin\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">16\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Saving...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cbutton disabled className="flex items-center gap-2"> \u003CLoader2 className="animate-spin" size={16} /> Saving...\u003C/button>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"full-page-loading\">Full Page Loading\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#full-page-loading\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Full Page Loading”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center justify-center h-full\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col items-center gap-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Loader2\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">animate-spin text-blue-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">32\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-slate-400\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Loading data...\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex items-center justify-center h-full"> \u003Cdiv className="flex flex-col items-center gap-4"> \u003CLoader2 className="animate-spin text-blue-500" size={32} /> \u003Cspan className="text-slate-400">Loading data...\u003C/span> \u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"skeleton-placeholder\">Skeleton Placeholder\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#skeleton-placeholder\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Skeleton Placeholder”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">animate-pulse\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-4 bg-slate-700 rounded w-3/4 mb-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-4 bg-slate-700 rounded w-1/2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="animate-pulse"> \u003Cdiv className="h-4 bg-slate-700 rounded w-3/4 mb-2" /> \u003Cdiv className="h-4 bg-slate-700 rounded w-1/2" />\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"empty-states\">Empty States\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#empty-states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Empty States”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"no-data\">No Data\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#no-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “No Data”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col items-center justify-center h-full text-center p-8\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">FileX\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-slate-600 mb-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">48\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h3\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-lg font-semibold text-slate-300 mb-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">No data loaded\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h3\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm text-slate-500 mb-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Import a CSV or Excel file to get started\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-blue-600 text-white px-4 py-2 rounded-lg\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Import Data\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex flex-col items-center justify-center h-full text-center p-8"> \u003CFileX className="text-slate-600 mb-4" size={48} /> \u003Ch3 className="text-lg font-semibold text-slate-300 mb-2">No data loaded\u003C/h3> \u003Cp className="text-sm text-slate-500 mb-4">Import a CSV or Excel file to get started\u003C/p> \u003Cbutton className="bg-blue-600 text-white px-4 py-2 rounded-lg">Import Data\u003C/button>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"no-results\">No Results\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#no-results\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “No Results”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center justify-center h-full text-slate-500 text-sm\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">No matching data found\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex items-center justify-center h-full text-slate-500 text-sm"> No matching data found\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"no-selection\">No Selection\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#no-selection\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “No Selection”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center justify-center h-full text-slate-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Select an outcome variable to view analysis\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex items-center justify-center h-full text-slate-500"> Select an outcome variable to view analysis\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"actionable-empty-state\">Actionable Empty State\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#actionable-empty-state\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Actionable Empty State”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For chart panels that can be configured or hidden:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col items-center justify-center h-full text-slate-400\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">BarChart3\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">opacity-50 mb-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">32\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm mb-3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">No Pareto data\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex gap-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs px-3 py-1 bg-slate-700 rounded hover:bg-slate-600\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Select Factor\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs px-3 py-1 bg-slate-700 rounded hover:bg-slate-600\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Upload\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs px-3 py-1 bg-slate-700 rounded hover:bg-slate-600\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Hide\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex flex-col items-center justify-center h-full text-slate-400"> \u003CBarChart3 className="opacity-50 mb-2" size={32} /> \u003Cp className="text-sm mb-3">No Pareto data\u003C/p> \u003Cdiv className="flex gap-2"> \u003Cbutton className="text-xs px-3 py-1 bg-slate-700 rounded hover:bg-slate-600"> Select Factor \u003C/button> \u003Cbutton className="text-xs px-3 py-1 bg-slate-700 rounded hover:bg-slate-600">Upload\u003C/button> \u003Cbutton className="text-xs px-3 py-1 bg-slate-700 rounded hover:bg-slate-600">Hide\u003C/button> \u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Use when:\u003C/p>\n\u003Cul>\n\u003Cli>Chart requires data/configuration that isn’t present\u003C/li>\n\u003Cli>User should have options to configure, upload, or dismiss the panel\u003C/li>\n\u003Cli>Hiding is temporary (resets on new data)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"success-states\">Success States\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#success-states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success States”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"inline-success\">Inline Success\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#inline-success\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Inline Success”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center gap-1 text-green-500 text-sm\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Check\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">14\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Saved successfully\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cspan className="flex items-center gap-1 text-green-500 text-sm"> \u003CCheck size={14} /> Saved successfully\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"success-badge\">Success Badge\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#success-badge\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Success Badge”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">inline-flex items-center gap-1 px-2 py-0.5 bg-green-500/20 text-green-400 rounded text-xs\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Check\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">12\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Pass\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cspan className="inline-flex items-center gap-1 px-2 py-0.5 bg-green-500/20 text-green-400 rounded text-xs"> \u003CCheck size={12} /> Pass\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"error-states\">Error States\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#error-states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Error States”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"inline-error\">Inline Error\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#inline-error\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Inline Error”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs text-red-400 mt-1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Invalid value entered\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cspan className="text-xs text-red-400 mt-1">Invalid value entered\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"error-card\">Error Card\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#error-card\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Error Card”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-red-500/10 border border-red-500/30 rounded-lg p-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-start gap-3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">AlertCircle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-red-400 flex-shrink-0\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h4\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm font-medium text-red-400\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Error loading data\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h4\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-xs text-red-300/80 mt-1\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Please check the file format and try again.\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="bg-red-500/10 border border-red-500/30 rounded-lg p-4"> \u003Cdiv className="flex items-start gap-3"> \u003CAlertCircle className="text-red-400 flex-shrink-0" size={20} /> \u003Cdiv> \u003Ch4 className="text-sm font-medium text-red-400">Error loading data\u003C/h4> \u003Cp className="text-xs text-red-300/80 mt-1">Please check the file format and try again.\u003C/p> \u003C/div> \u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"error-boundary-fallback\">Error Boundary Fallback\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#error-boundary-fallback\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Error Boundary Fallback”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col items-center justify-center h-full p-6 text-center\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">AlertCircle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-red-400 mb-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">32\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h3\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-white font-medium mb-2\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Something went wrong\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h3\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm text-slate-400 mb-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">componentName\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> failed to render\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">p\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">reset\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-blue-400 hover:underline\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Try again\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex flex-col items-center justify-center h-full p-6 text-center"> \u003CAlertCircle className="text-red-400 mb-4" size={32} /> \u003Ch3 className="text-white font-medium mb-2">Something went wrong\u003C/h3> \u003Cp className="text-sm text-slate-400 mb-4">{componentName} failed to render\u003C/p> \u003Cbutton onClick={reset} className="text-blue-400 hover:underline"> Try again \u003C/button>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"warning-states\">Warning States\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#warning-states\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Warning States”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"warning-banner\">Warning Banner\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#warning-banner\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Warning Banner”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">bg-amber-500/10 border border-amber-500/30 rounded-lg p-3 flex items-center gap-3\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">AlertTriangle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-amber-400 flex-shrink-0\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">18\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm text-amber-200\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Large dataset may affect performance\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="bg-amber-500/10 border border-amber-500/30 rounded-lg p-3 flex items-center gap-3"> \u003CAlertTriangle className="text-amber-400 flex-shrink-0" size={18} /> \u003Cspan className="text-sm text-amber-200">Large dataset may affect performance\u003C/span>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"status-badges\">Status Badges\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#status-badges\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Status Badges”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Pass (green)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-2 py-0.5 bg-green-500/20 text-green-400 rounded text-xs font-medium\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Pass\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Fail (red)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-2 py-0.5 bg-red-500/20 text-red-400 rounded text-xs font-medium\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Fail\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Warning (amber)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">px-2 py-0.5 bg-amber-500/20 text-amber-400 rounded text-xs font-medium\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Warning\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Pass (green)\u003Cspan className="px-2 py-0.5 bg-green-500/20 text-green-400 rounded text-xs font-medium"> Pass\u003C/span>// Fail (red)\u003Cspan className="px-2 py-0.5 bg-red-500/20 text-red-400 rounded text-xs font-medium"> Fail\u003C/span>// Warning (amber)\u003Cspan className="px-2 py-0.5 bg-amber-500/20 text-amber-400 rounded text-xs font-medium"> Warning\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"copy-feedback\">Copy Feedback\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#copy-feedback\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Copy Feedback”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const [\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">copied\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setCopied\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">] = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useState\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleCopy\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = async \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">await \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">navigator\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#FAF39F;--1:#111111\">clipboard\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">writeText\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">text\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setCopied\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">true\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setTimeout\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">setCopied\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#FF6A83;--1:#A24848\">false\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">2000\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">copied\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">?\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-green-400\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">:\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-slate-400\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">copied\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Check\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">16\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Copy\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">16\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"const [copied, setCopied] = useState(false);const handleCopy = async () => { await navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000);};\u003Cbutton className={copied ? 'text-green-400' : 'text-slate-400'}> {copied ? \u003CCheck size={16} /> : \u003CCopy size={16} />}\u003C/button>;\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"saving-indicator\">Saving Indicator\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#saving-indicator\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Saving Indicator”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center gap-2 text-xs text-slate-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">isSaving\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Loader2\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">animate-spin\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">12\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Saving...\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">hasUnsavedChanges\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">w-2 h-2 bg-amber-500 rounded-full\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Unsaved changes\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Check\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">12\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Saved\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cspan className="flex items-center gap-2 text-xs text-slate-500"> {isSaving ? ( \u003C> \u003CLoader2 className="animate-spin" size={12} /> Saving... \u003C/> ) : hasUnsavedChanges ? ( \u003C> \u003Cspan className="w-2 h-2 bg-amber-500 rounded-full" /> Unsaved changes \u003C/> ) : ( \u003C> \u003CCheck size={12} /> Saved \u003C/> )}\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"unsaved-changes-indicator\">Unsaved Changes Indicator\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#unsaved-changes-indicator\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Unsaved Changes Indicator”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Show asterisk after project name:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-slate-500\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">projectName\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">hasUnsavedChanges\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> *\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cspan className="text-slate-500"> {projectName} {hasUnsavedChanges && ' *'}\u003C/span>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>", + { + "headings": 12053, + "localImagePaths": 12120, + "remoteImagePaths": 12121, + "frontmatter": 12122, + "imagePaths": 12123 + }, + [ + 12054, 12056, 12059, 12062, 12065, 12068, 12071, 12074, 12077, 12080, 12083, 12086, 12089, + 12092, 12093, 12096, 12099, 12102, 12105, 12108, 12111, 12114, 12117 + ], + { "depth": 30, "slug": 12055, "text": 12043 }, + "feedback-patterns", + { "depth": 33, "slug": 12057, "text": 12058 }, + "loading-states", + "Loading States", + { "depth": 79, "slug": 12060, "text": 12061 }, + "button-loading", + "Button Loading", + { "depth": 79, "slug": 12063, "text": 12064 }, + "full-page-loading", + "Full Page Loading", + { "depth": 79, "slug": 12066, "text": 12067 }, + "skeleton-placeholder", + "Skeleton Placeholder", + { "depth": 33, "slug": 12069, "text": 12070 }, + "empty-states", + "Empty States", + { "depth": 79, "slug": 12072, "text": 12073 }, + "no-data", + "No Data", + { "depth": 79, "slug": 12075, "text": 12076 }, + "no-results", + "No Results", + { "depth": 79, "slug": 12078, "text": 12079 }, + "no-selection", + "No Selection", + { "depth": 79, "slug": 12081, "text": 12082 }, + "actionable-empty-state", + "Actionable Empty State", + { "depth": 33, "slug": 12084, "text": 12085 }, + "success-states", + "Success States", + { "depth": 79, "slug": 12087, "text": 12088 }, + "inline-success", + "Inline Success", + { "depth": 79, "slug": 12090, "text": 12091 }, + "success-badge", + "Success Badge", + { "depth": 33, "slug": 11119, "text": 11120 }, + { "depth": 79, "slug": 12094, "text": 12095 }, + "inline-error", + "Inline Error", + { "depth": 79, "slug": 12097, "text": 12098 }, + "error-card", + "Error Card", + { "depth": 79, "slug": 12100, "text": 12101 }, + "error-boundary-fallback", + "Error Boundary Fallback", + { "depth": 33, "slug": 12103, "text": 12104 }, + "warning-states", + "Warning States", + { "depth": 79, "slug": 12106, "text": 12107 }, + "warning-banner", + "Warning Banner", + { "depth": 33, "slug": 12109, "text": 12110 }, + "status-badges", + "Status Badges", + { "depth": 33, "slug": 12112, "text": 12113 }, + "copy-feedback", + "Copy Feedback", + { "depth": 33, "slug": 12115, "text": 12116 }, + "saving-indicator", + "Saving Indicator", + { "depth": 33, "slug": 12118, "text": 12119 }, + "unsaved-changes-indicator", + "Unsaved Changes Indicator", + [], + [], + { "title": 12043 }, + [], + "06-design-system/patterns/interactions", + { + "id": 12124, + "data": 12126, + "body": 12130, + "filePath": 12131, + "digest": 12132, + "rendered": 12133 + }, + { + "title": 3529, + "editUrl": 16, + "head": 12127, + "template": 18, + "sidebar": 12128, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 12129 }, + {}, + "# Interaction Patterns\n\nDesign system reference for interactive component behaviors across VariScout.\n\n## 1. Inline Editing\n\nComponents that enter edit mode in-place, save on blur/Enter, cancel on Escape.\n\n| Component | Trigger | Save | Cancel | Keyboard |\n| ---------------------- | ------------------ | ------------- | ---------------- | --------------------------------------------------------- |\n| `ColumnCard` rename | Click pencil icon | Blur or Enter | Escape (reverts) | Enter commits, Escape reverts |\n| `DataTableBase` cells | Click cell | Blur or Enter | Escape (reverts) | Arrow Up/Down move between rows, Tab moves to next column |\n| `EditableChartTitle` | Click title text | Blur or Enter | Escape (reverts) | — |\n| `StepAnnotation` notes | Click \"+ Add note\" | Enter | Escape | — |\n\n**Convention:** Blur always saves (never discards). Escape always reverts to the pre-edit value.\n\n### Styling Tokens\n\n| State | Token |\n| -------------------- | ------------------------------ |\n| Input background | `bg-surface` |\n| Input border (rest) | `border-edge` |\n| Input border (focus) | `focus:border-blue-500` |\n| Input text | `text-content` or `text-white` |\n| Monospace numbers | `font-mono text-right` |\n\n---\n\n## 2. Grid / Spreadsheet Entry\n\nMulti-cell data entry with keyboard-driven navigation.\n\n| Component | Arrow Keys | Tab | Enter | Paste |\n| ---------------------- | ---------------------------------- | ------------------------- | ---------------- | --------------------------------- |\n| `DataTableBase` | Up/Down between rows (save + move) | Next column (save + move) | Save + exit edit | Multi-cell paste (rows × columns) |\n| `StandardEntryGrid` | — | Next cell | Save row | — |\n| `PerformanceEntryGrid` | — | Next measure column | Save row | Paste button for bulk fill |\n\n**Convention:** Arrow/Tab navigation always saves the current cell before moving. Paste detects rows (newlines) and columns (tabs) automatically.\n\n### Styling Tokens\n\n| Element | Token |\n| ----------------- | ------------------------ |\n| Table background | `bg-surface` |\n| Cell border | `border-edge` |\n| Header background | `bg-surface-secondary` |\n| Header text | `text-content-secondary` |\n| Active cell ring | `ring-2 ring-blue-500` |\n| Numeric cells | `font-mono text-right` |\n\n---\n\n## 3. Selection Cards\n\nCards that toggle selection state on click, used in column mapping and setup flows.\n\n| Component | Click | Keyboard | Visual Feedback |\n| ----------------------- | --------------- | ------------------ | ----------------------------------- |\n| `ColumnCard` (outcome) | Radio select | Enter/Space toggle | Blue glow border + filled radio dot |\n| `ColumnCard` (factor) | Checkbox toggle | Enter/Space toggle | Emerald glow border + check icon |\n| `MeasureColumnSelector` | Checkbox toggle | — | Emerald highlight |\n\n**Convention:** Outcome = radio (single select, blue). Factor = checkbox (multi-select, emerald). Cards use `role=\"button\"` with `tabIndex={0}` for keyboard access. Selected state uses colored border + background glow (`shadow-[0_0_10px_...]`).\n\n### Styling Tokens\n\n| State | Token |\n| --------------------- | ---------------------------------------------- |\n| Unselected border | `border-slate-700` |\n| Unselected background | `bg-slate-800` |\n| Hover | `hover:border-slate-600 hover:bg-slate-700/50` |\n| Selected (outcome) | `border-blue-500 bg-blue-600/20` |\n| Selected (factor) | `border-emerald-500 bg-emerald-600/20` |\n| Disabled | `opacity-50 cursor-not-allowed` |\n\n---\n\n## 4. Segmented Controls\n\nPill-button groups for selecting from 2–5 options.\n\n| Component | Purpose | Selected Style | Indicator |\n| --------------------------- | --------------------- | ------------------------ | ---------------------------- |\n| `FactorSelector` | Boxplot/Pareto factor | `bg-blue-600 text-white` | Amber dot when filter active |\n| `BoxplotDisplayToggle` | Sort criteria | `bg-blue-600 text-white` | — |\n| Mode toggles (Manual Entry) | Standard/Performance | `bg-blue-600 text-white` | — |\n\n**Convention:** Selected = `bg-blue-600 text-white shadow-sm`. Unselected = `text-slate-400 hover:text-white hover:bg-slate-800`. Container = `bg-slate-900 rounded-lg p-0.5 border border-slate-700`. Use dropdown when options exceed 5.\n\n---\n\n## 5. Context Menus\n\nRight-click menus for chart interactions.\n\n| Component | Trigger | Actions |\n| ---------------------------------------- | ------------------------- | --------------------------------- |\n| `AnnotationContextMenu` (Boxplot/Pareto) | Right-click on category | Highlight category, Add text note |\n| `AnnotationContextMenu` (I-Chart) | Right-click on chart area | Add text note (free-floating %) |\n\n**Convention:** Positioned at cursor. Click-outside or Escape to dismiss. Menu items are buttons with hover highlight. Category highlights toggle on/off.\n\n---\n\n## 6. Drag and Drop\n\nNative HTML5 drag-and-drop (no library dependency).\n\n| Component | Draggable | Drop Target | Visual Feedback |\n| --------------------- | ------------- | ------------- | -------------------------------- |\n| `FindingBoardColumns` | Finding cards | Board columns | Drag ghost + drop zone highlight |\n\n**Convention:** Uses native `draggable`, `onDragStart`, `onDragOver`, `onDrop` — no dnd-kit or similar library. Status updates on drop.\n\n---\n\n## Cross-Cutting Conventions\n\n| Convention | Pattern | Where Used |\n| ----------------- | ------------------------------------------------------------- | ------------------------------- |\n| Focus ring | `focus:border-blue-500` or `focus:ring-2 focus:ring-blue-500` | All interactive elements |\n| Blur saves | `onBlur` triggers save/commit, never discard | Inline edit, grid cells |\n| Escape cancels | Revert to pre-edit value | Inline edit, rename, modals |\n| Monospace numbers | `font-mono text-right` | All numeric inputs and displays |\n| Semantic tokens | `bg-surface`, `border-edge`, `text-content` | All shared UI components |\n| Transition | `transition-colors` or `transition-all` | Hover/focus state changes |\n| Disabled | `opacity-50 cursor-not-allowed` | Cards, buttons, inputs |\n\n---\n\n## See Also\n\n- [Forms](../components/forms.md) — Form element code examples\n- [Navigation](navigation.md) — Filter breadcrumbs, drill-down patterns\n- [Accessibility](../foundations/accessibility.md) — WCAG AA guidelines\n- [Feedback](feedback.md) — Loading, error, and success states", + "src/content/docs/06-design-system/patterns/interactions.md", + "cb1a5c4fa55ab62f", + { "html": 12134, "metadata": 12135 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"interaction-patterns\">Interaction Patterns\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#interaction-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interaction Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Design system reference for interactive component behaviors across VariScout.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"1-inline-editing\">1. Inline Editing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#1-inline-editing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Inline Editing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Components that enter edit mode in-place, save on blur/Enter, cancel on Escape.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Trigger\u003C/th>\u003Cth>Save\u003C/th>\u003Cth>Cancel\u003C/th>\u003Cth>Keyboard\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ColumnCard\u003C/code> rename\u003C/td>\u003Ctd>Click pencil icon\u003C/td>\u003Ctd>Blur or Enter\u003C/td>\u003Ctd>Escape (reverts)\u003C/td>\u003Ctd>Enter commits, Escape reverts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">DataTableBase\u003C/code> cells\u003C/td>\u003Ctd>Click cell\u003C/td>\u003Ctd>Blur or Enter\u003C/td>\u003Ctd>Escape (reverts)\u003C/td>\u003Ctd>Arrow Up/Down move between rows, Tab moves to next column\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">EditableChartTitle\u003C/code>\u003C/td>\u003Ctd>Click title text\u003C/td>\u003Ctd>Blur or Enter\u003C/td>\u003Ctd>Escape (reverts)\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">StepAnnotation\u003C/code> notes\u003C/td>\u003Ctd>Click ”+ Add note”\u003C/td>\u003Ctd>Enter\u003C/td>\u003Ctd>Escape\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Convention:\u003C/strong> Blur always saves (never discards). Escape always reverts to the pre-edit value.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"styling-tokens\">Styling Tokens\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#styling-tokens\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Styling Tokens”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>State\u003C/th>\u003Cth>Token\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Input background\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Input border (rest)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">border-edge\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Input border (focus)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">focus:border-blue-500\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Input text\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-content\u003C/code> or \u003Ccode dir=\"auto\">text-white\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Monospace numbers\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">font-mono text-right\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"2-grid--spreadsheet-entry\">2. Grid / Spreadsheet Entry\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#2-grid--spreadsheet-entry\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Grid / Spreadsheet Entry”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Multi-cell data entry with keyboard-driven navigation.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Arrow Keys\u003C/th>\u003Cth>Tab\u003C/th>\u003Cth>Enter\u003C/th>\u003Cth>Paste\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">DataTableBase\u003C/code>\u003C/td>\u003Ctd>Up/Down between rows (save + move)\u003C/td>\u003Ctd>Next column (save + move)\u003C/td>\u003Ctd>Save + exit edit\u003C/td>\u003Ctd>Multi-cell paste (rows × columns)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">StandardEntryGrid\u003C/code>\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Next cell\u003C/td>\u003Ctd>Save row\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">PerformanceEntryGrid\u003C/code>\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Next measure column\u003C/td>\u003Ctd>Save row\u003C/td>\u003Ctd>Paste button for bulk fill\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Convention:\u003C/strong> Arrow/Tab navigation always saves the current cell before moving. Paste detects rows (newlines) and columns (tabs) automatically.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"styling-tokens-1\">Styling Tokens\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#styling-tokens-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Styling Tokens”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Token\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Table background\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cell border\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">border-edge\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Header background\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface-secondary\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Header text\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">text-content-secondary\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Active cell ring\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ring-2 ring-blue-500\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Numeric cells\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">font-mono text-right\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"3-selection-cards\">3. Selection Cards\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#3-selection-cards\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Selection Cards”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Cards that toggle selection state on click, used in column mapping and setup flows.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Click\u003C/th>\u003Cth>Keyboard\u003C/th>\u003Cth>Visual Feedback\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ColumnCard\u003C/code> (outcome)\u003C/td>\u003Ctd>Radio select\u003C/td>\u003Ctd>Enter/Space toggle\u003C/td>\u003Ctd>Blue glow border + filled radio dot\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">ColumnCard\u003C/code> (factor)\u003C/td>\u003Ctd>Checkbox toggle\u003C/td>\u003Ctd>Enter/Space toggle\u003C/td>\u003Ctd>Emerald glow border + check icon\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">MeasureColumnSelector\u003C/code>\u003C/td>\u003Ctd>Checkbox toggle\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Emerald highlight\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Convention:\u003C/strong> Outcome = radio (single select, blue). Factor = checkbox (multi-select, emerald). Cards use \u003Ccode dir=\"auto\">role=\"button\"\u003C/code> with \u003Ccode dir=\"auto\">tabIndex={0}\u003C/code> for keyboard access. Selected state uses colored border + background glow (\u003Ccode dir=\"auto\">shadow-[0_0_10px_...]\u003C/code>).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"styling-tokens-2\">Styling Tokens\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#styling-tokens-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Styling Tokens”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>State\u003C/th>\u003Cth>Token\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Unselected border\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">border-slate-700\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Unselected background\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-slate-800\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hover\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">hover:border-slate-600 hover:bg-slate-700/50\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Selected (outcome)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">border-blue-500 bg-blue-600/20\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Selected (factor)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">border-emerald-500 bg-emerald-600/20\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Disabled\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">opacity-50 cursor-not-allowed\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"4-segmented-controls\">4. Segmented Controls\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#4-segmented-controls\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. Segmented Controls”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pill-button groups for selecting from 2–5 options.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Purpose\u003C/th>\u003Cth>Selected Style\u003C/th>\u003Cth>Indicator\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FactorSelector\u003C/code>\u003C/td>\u003Ctd>Boxplot/Pareto factor\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-blue-600 text-white\u003C/code>\u003C/td>\u003Ctd>Amber dot when filter active\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">BoxplotDisplayToggle\u003C/code>\u003C/td>\u003Ctd>Sort criteria\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-blue-600 text-white\u003C/code>\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Mode toggles (Manual Entry)\u003C/td>\u003Ctd>Standard/Performance\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-blue-600 text-white\u003C/code>\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Convention:\u003C/strong> Selected = \u003Ccode dir=\"auto\">bg-blue-600 text-white shadow-sm\u003C/code>. Unselected = \u003Ccode dir=\"auto\">text-slate-400 hover:text-white hover:bg-slate-800\u003C/code>. Container = \u003Ccode dir=\"auto\">bg-slate-900 rounded-lg p-0.5 border border-slate-700\u003C/code>. Use dropdown when options exceed 5.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"5-context-menus\">5. Context Menus\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#5-context-menus\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Context Menus”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Right-click menus for chart interactions.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Trigger\u003C/th>\u003Cth>Actions\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">AnnotationContextMenu\u003C/code> (Boxplot/Pareto)\u003C/td>\u003Ctd>Right-click on category\u003C/td>\u003Ctd>Highlight category, Add text note\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">AnnotationContextMenu\u003C/code> (I-Chart)\u003C/td>\u003Ctd>Right-click on chart area\u003C/td>\u003Ctd>Add text note (free-floating %)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Convention:\u003C/strong> Positioned at cursor. Click-outside or Escape to dismiss. Menu items are buttons with hover highlight. Category highlights toggle on/off.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"6-drag-and-drop\">6. Drag and Drop\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#6-drag-and-drop\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Drag and Drop”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Native HTML5 drag-and-drop (no library dependency).\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Draggable\u003C/th>\u003Cth>Drop Target\u003C/th>\u003Cth>Visual Feedback\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">FindingBoardColumns\u003C/code>\u003C/td>\u003Ctd>Finding cards\u003C/td>\u003Ctd>Board columns\u003C/td>\u003Ctd>Drag ghost + drop zone highlight\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Convention:\u003C/strong> Uses native \u003Ccode dir=\"auto\">draggable\u003C/code>, \u003Ccode dir=\"auto\">onDragStart\u003C/code>, \u003Ccode dir=\"auto\">onDragOver\u003C/code>, \u003Ccode dir=\"auto\">onDrop\u003C/code> — no dnd-kit or similar library. Status updates on drop.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-cutting-conventions\">Cross-Cutting Conventions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-cutting-conventions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Cutting Conventions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Convention\u003C/th>\u003Cth>Pattern\u003C/th>\u003Cth>Where Used\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Focus ring\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">focus:border-blue-500\u003C/code> or \u003Ccode dir=\"auto\">focus:ring-2 focus:ring-blue-500\u003C/code>\u003C/td>\u003Ctd>All interactive elements\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Blur saves\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">onBlur\u003C/code> triggers save/commit, never discard\u003C/td>\u003Ctd>Inline edit, grid cells\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Escape cancels\u003C/td>\u003Ctd>Revert to pre-edit value\u003C/td>\u003Ctd>Inline edit, rename, modals\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Monospace numbers\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">font-mono text-right\u003C/code>\u003C/td>\u003Ctd>All numeric inputs and displays\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Semantic tokens\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bg-surface\u003C/code>, \u003Ccode dir=\"auto\">border-edge\u003C/code>, \u003Ccode dir=\"auto\">text-content\u003C/code>\u003C/td>\u003Ctd>All shared UI components\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Transition\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">transition-colors\u003C/code> or \u003Ccode dir=\"auto\">transition-all\u003C/code>\u003C/td>\u003Ctd>Hover/focus state changes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Disabled\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">opacity-50 cursor-not-allowed\u003C/code>\u003C/td>\u003Ctd>Cards, buttons, inputs\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../components/forms.md\">Forms\u003C/a> — Form element code examples\u003C/li>\n\u003Cli>\u003Ca href=\"navigation.md\">Navigation\u003C/a> — Filter breadcrumbs, drill-down patterns\u003C/li>\n\u003Cli>\u003Ca href=\"../foundations/accessibility.md\">Accessibility\u003C/a> — WCAG AA guidelines\u003C/li>\n\u003Cli>\u003Ca href=\"feedback.md\">Feedback\u003C/a> — Loading, error, and success states\u003C/li>\n\u003C/ul>", + { + "headings": 12136, + "localImagePaths": 12167, + "remoteImagePaths": 12168, + "frontmatter": 12169, + "imagePaths": 12170 + }, + [12137, 12138, 12141, 12144, 12147, 12149, 12152, 12154, 12157, 12160, 12163, 12166], + { "depth": 30, "slug": 3528, "text": 3529 }, + { "depth": 33, "slug": 12139, "text": 12140 }, + "1-inline-editing", + "1. Inline Editing", + { "depth": 79, "slug": 12142, "text": 12143 }, + "styling-tokens", + "Styling Tokens", + { "depth": 33, "slug": 12145, "text": 12146 }, + "2-grid--spreadsheet-entry", + "2. Grid / Spreadsheet Entry", + { "depth": 79, "slug": 12148, "text": 12143 }, + "styling-tokens-1", + { "depth": 33, "slug": 12150, "text": 12151 }, + "3-selection-cards", + "3. Selection Cards", + { "depth": 79, "slug": 12153, "text": 12143 }, + "styling-tokens-2", + { "depth": 33, "slug": 12155, "text": 12156 }, + "4-segmented-controls", + "4. Segmented Controls", + { "depth": 33, "slug": 12158, "text": 12159 }, + "5-context-menus", + "5. Context Menus", + { "depth": 33, "slug": 12161, "text": 12162 }, + "6-drag-and-drop", + "6. Drag and Drop", + { "depth": 33, "slug": 12164, "text": 12165 }, + "cross-cutting-conventions", + "Cross-Cutting Conventions", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 3529 }, + [], + "06-design-system/patterns/layout", + { + "id": 12171, + "data": 12173, + "body": 12178, + "filePath": 12179, + "digest": 12180, + "rendered": 12181 + }, + { + "title": 12174, + "editUrl": 16, + "head": 12175, + "template": 18, + "sidebar": 12176, + "pagefind": 16, + "draft": 20 + }, + "Layout Patterns", + [], + { "hidden": 20, "attrs": 12177 }, + {}, + "# Layout Patterns\n\nPage and component layout patterns.\n\n## PWA App Layout\n\n### Without Data Panel\n\n```\n┌─────────────────────────────────────────┐\n│ Header (h-14) │\n├─────────────────────────────────────────┤\n│ FilterBreadcrumb (when filters active) │\n├─────────────────────────────────────────┤\n│ │\n│ Main Content (flex-1) │\n│ │\n├─────────────────────────────────────────┤\n│ Footer │\n└─────────────────────────────────────────┘\n```\n\n### With Data Panel (toggled via 📊 button)\n\n```\n┌─────────────────────────────────────────────────────────┐\n│ Header (h-14) │\n├─────────────────────────────────────────────────────────┤\n│ FilterBreadcrumb (when filters active) │\n├─────────────────────────────────┬───────────────────────┤\n│ │ │\n│ Main Content (flex-1) ║ Data Panel │\n│ ║ (resizable width) │\n│ ║ │\n├─────────────────────────────────┴───────────────────────┤\n│ Footer │\n└─────────────────────────────────────────────────────────┘\n```\n\n```jsx\n\u003Cdiv className=\"flex flex-col h-screen bg-slate-900\">\n \u003CAppHeader />\n \u003CFilterBreadcrumb items={breadcrumbs} onNavigate={handleNav} />\n \u003Cdiv className=\"flex flex-1 overflow-hidden\">\n \u003Cmain className=\"flex-1 overflow-hidden\">{content}\u003C/main>\n {showDataPanel && \u003CDataPanel width={dataPanelWidth} onWidthChange={setDataPanelWidth} />}\n \u003C/div>\n \u003CAppFooter />\n\u003C/div>\n```\n\nSee [Navigation Patterns](./navigation.md) for drill-down behavior.\n\n## Dashboard Layout (Desktop)\n\n### Charts Only\n\n```\n┌─────────────────────────────────────────┐\n│ I-Chart (40%) │\n│ │\n├─────────────────────────────────────────┤\n│ ═══════════ Resize Handle ═══════════ │\n├────────────┬────────────┬───────────────┤\n│ Boxplot │ Pareto │ Stats Panel │\n│ │ │ │\n└────────────┴────────────┴───────────────┘\n```\n\n### With Data Panel\n\n```\n┌─────────────────────────────────────────┬─────────────────┐\n│ I-Chart (40%) │ Data Table │\n│ │ │\n├─────────────────────────────────────────┤ [sticky header] │\n│ ═══════════ Resize Handle ═══════════ │ │\n├────────────┬────────────┬───────────────┤ [scrollable │\n│ Boxplot │ Pareto │ Stats Panel │ content] │\n│ │ │ │ │\n└────────────┴────────────┴───────────────┴─────────────────┘\n ↔ draggable divider\n```\n\n```jsx\n\u003CPanelGroup orientation=\"vertical\">\n \u003CPanel defaultSize={40} minSize={20}>\n \u003CIChartCard />\n \u003C/Panel>\n \u003CPanelResizeHandle />\n \u003CPanel defaultSize={60} minSize={20}>\n \u003Cdiv className=\"flex gap-4\">\n \u003CBoxplotCard />\n \u003CParetoCard />\n \u003CStatsPanel />\n \u003C/div>\n \u003C/Panel>\n\u003C/PanelGroup>\n```\n\n**Data Panel** (`DataPanel.tsx`):\n\n- Toggle visibility via 📊 button in header\n- Draggable divider persists width to localStorage\n- Bi-directional sync: click chart → highlight row, click row → highlight chart point\n\n## Dashboard Layout (Mobile)\n\n```\n┌─────────────────┐\n│ Header │\n├─────────────────┤\n│ │\n│ Chart Carousel │\n│ ◀ I-Chart ▶ │\n│ │\n├─────────────────┤\n│ Stats Summary │\n├─────────────────┤\n│ Data Panel │\n│ (bottom sheet) │\n│ ═══════════════ │ ← drag handle\n└─────────────────┘\n```\n\nMobile uses vertical scrolling with carousel-based chart selection.\n\n**Data Panel (Bottom Sheet)**:\n\n- Collapsed: Shows row count + \"Swipe up\"\n- Partial: ~40% screen height\n- Full: ~90% screen height\n- Drag handle for resizing\n\n## Grid Layouts\n\n### 2-Column Grid\n\n```jsx\n\u003Cdiv className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n \u003CCard>Left\u003C/Card>\n \u003CCard>Right\u003C/Card>\n\u003C/div>\n```\n\n### 2×2 Grid (Regression)\n\n```jsx\n\u003Cdiv className=\"grid grid-cols-1 md:grid-cols-2 gap-4 h-full\">\n {charts.map(chart => (\n \u003Cdiv key={chart.id} className=\"min-h-[280px]\">\n \u003CScatterPlot />\n \u003C/div>\n ))}\n\u003C/div>\n```\n\n### Auto-fit Grid\n\n```jsx\n\u003Cdiv\n className=\"grid gap-4\"\n style={{\n gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',\n }}\n>\n {items.map(item => (\n \u003CCard key={item.id} />\n ))}\n\u003C/div>\n```\n\n## Flex Patterns\n\n### Row with Space Between\n\n```jsx\n\u003Cdiv className=\"flex items-center justify-between\">\n \u003Cspan>Label\u003C/span>\n \u003Cspan>Value\u003C/span>\n\u003C/div>\n```\n\n### Centered Content\n\n```jsx\n\u003Cdiv className=\"flex items-center justify-center h-full\">\n \u003CEmptyState />\n\u003C/div>\n```\n\n### Sticky Header with Scrollable Content\n\n```jsx\n\u003Cdiv className=\"flex flex-col h-full\">\n \u003Cdiv className=\"flex-none px-4 py-3 border-b border-slate-700\">Header\u003C/div>\n \u003Cdiv className=\"flex-1 overflow-y-auto p-4\">Scrollable content\u003C/div>\n\u003C/div>\n```\n\n## Chart Container Sizing\n\nCharts need explicit height to render:\n\n```jsx\n// Fixed height\n\u003Cdiv className=\"h-[400px]\">\n \u003CIChart />\n\u003C/div>\n\n// Flex sizing (parent must have height)\n\u003Cdiv className=\"flex-1 min-h-0\">\n \u003CIChart />\n\u003C/div>\n\n// Grid cell\n\u003Cdiv className=\"min-h-[280px]\">\n \u003CScatterPlot />\n\u003C/div>\n```\n\n## Responsive Breakpoints\n\n| Breakpoint | Width | Layout Changes |\n| ---------- | -------- | -------------------------- |\n| Default | \u003C 640px | Single column, mobile menu |\n| sm | ≥ 640px | Desktop header buttons |\n| md | ≥ 768px | 2-column grids |\n| lg | ≥ 1024px | Full 3-panel dashboard |", + "src/content/docs/06-design-system/patterns/layout.md", + "b13a59bd9f9bdd78", + { "html": 12182, "metadata": 12183 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"layout-patterns\">Layout Patterns\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#layout-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Layout Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Page and component layout patterns.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pwa-app-layout\">PWA App Layout\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-app-layout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA App Layout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"without-data-panel\">Without Data Panel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#without-data-panel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Without Data Panel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Header (h-14) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ FilterBreadcrumb (when filters active) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Main Content (flex-1) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Footer │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────┐│ Header (h-14) │├─────────────────────────────────────────┤│ FilterBreadcrumb (when filters active) │├─────────────────────────────────────────┤│ ││ Main Content (flex-1) ││ │├─────────────────────────────────────────┤│ Footer │└─────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"with-data-panel-toggled-via--button\">With Data Panel (toggled via 📊 button)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#with-data-panel-toggled-via--button\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “With Data Panel (toggled via 📊 button)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Header (h-14) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ FilterBreadcrumb (when filters active) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────┬───────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Main Content (flex-1) ║ Data Panel │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ║ (resizable width) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ║ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────┴───────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Footer │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────┐│ Header (h-14) │├─────────────────────────────────────────────────────────┤│ FilterBreadcrumb (when filters active) │├─────────────────────────────────┬───────────────────────┤│ │ ││ Main Content (flex-1) ║ Data Panel ││ ║ (resizable width) ││ ║ │├─────────────────────────────────┴───────────────────────┤│ Footer │└─────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col h-screen bg-slate-900\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">AppHeader\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">FilterBreadcrumb\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">items\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">breadcrumbs\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onNavigate\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">handleNav\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-1 overflow-hidden\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">main\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-1 overflow-hidden\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">content\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">main\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">showDataPanel\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">DataPanel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">width\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">dataPanelWidth\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onWidthChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">setDataPanelWidth\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">AppFooter\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex flex-col h-screen bg-slate-900"> \u003CAppHeader /> \u003CFilterBreadcrumb items={breadcrumbs} onNavigate={handleNav} /> \u003Cdiv className="flex flex-1 overflow-hidden"> \u003Cmain className="flex-1 overflow-hidden">{content}\u003C/main> {showDataPanel && \u003CDataPanel width={dataPanelWidth} onWidthChange={setDataPanelWidth} />} \u003C/div> \u003CAppFooter />\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>See \u003Ca href=\"./navigation.md\">Navigation Patterns\u003C/a> for drill-down behavior.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dashboard-layout-desktop\">Dashboard Layout (Desktop)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dashboard-layout-desktop\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dashboard Layout (Desktop)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"charts-only\">Charts Only\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#charts-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Charts Only”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ I-Chart (40%) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ═══════════ Resize Handle ═══════════ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├────────────┬────────────┬───────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Boxplot │ Pareto │ Stats Panel │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────┴────────────┴───────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────┐│ I-Chart (40%) ││ │├─────────────────────────────────────────┤│ ═══════════ Resize Handle ═══════════ │├────────────┬────────────┬───────────────┤│ Boxplot │ Pareto │ Stats Panel ││ │ │ │└────────────┴────────────┴───────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"with-data-panel\">With Data Panel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#with-data-panel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “With Data Panel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────┬─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ I-Chart (40%) │ Data Table │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────┤ [sticky header] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ═══════════ Resize Handle ═══════════ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├────────────┬────────────┬───────────────┤ [scrollable │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Boxplot │ Pareto │ Stats Panel │ content] │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ │ │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────┴────────────┴───────────────┴─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">↔ draggable divider\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────┬─────────────────┐│ I-Chart (40%) │ Data Table ││ │ │├─────────────────────────────────────────┤ [sticky header] ││ ═══════════ Resize Handle ═══════════ │ │├────────────┬────────────┬───────────────┤ [scrollable ││ Boxplot │ Pareto │ Stats Panel │ content] ││ │ │ │ │└────────────┴────────────┴───────────────┴─────────────────┘ ↔ draggable divider\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PanelGroup\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">orientation\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">vertical\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Panel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">defaultSize\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">40\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">minSize\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChartCard\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Panel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PanelResizeHandle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Panel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">defaultSize\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">60\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">minSize\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex gap-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">BoxplotCard\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ParetoCard\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">StatsPanel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Panel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">PanelGroup\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CPanelGroup orientation="vertical"> \u003CPanel defaultSize={40} minSize={20}> \u003CIChartCard /> \u003C/Panel> \u003CPanelResizeHandle /> \u003CPanel defaultSize={60} minSize={20}> \u003Cdiv className="flex gap-4"> \u003CBoxplotCard /> \u003CParetoCard /> \u003CStatsPanel /> \u003C/div> \u003C/Panel>\u003C/PanelGroup>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Data Panel\u003C/strong> (\u003Ccode dir=\"auto\">DataPanel.tsx\u003C/code>):\u003C/p>\n\u003Cul>\n\u003Cli>Toggle visibility via 📊 button in header\u003C/li>\n\u003Cli>Draggable divider persists width to localStorage\u003C/li>\n\u003Cli>Bi-directional sync: click chart → highlight row, click row → highlight chart point\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dashboard-layout-mobile\">Dashboard Layout (Mobile)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dashboard-layout-mobile\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dashboard Layout (Mobile)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Header │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Chart Carousel │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ◀ I-Chart ▶ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Stats Summary │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Data Panel │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ (bottom sheet) │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ═══════════════ │ ← drag handle\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────┐│ Header │├─────────────────┤│ ││ Chart Carousel ││ ◀ I-Chart ▶ ││ │├─────────────────┤│ Stats Summary │├─────────────────┤│ Data Panel ││ (bottom sheet) ││ ═══════════════ │ ← drag handle└─────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Mobile uses vertical scrolling with carousel-based chart selection.\u003C/p>\n\u003Cp>\u003Cstrong>Data Panel (Bottom Sheet)\u003C/strong>:\u003C/p>\n\u003Cul>\n\u003Cli>Collapsed: Shows row count + “Swipe up”\u003C/li>\n\u003Cli>Partial: ~40% screen height\u003C/li>\n\u003Cli>Full: ~90% screen height\u003C/li>\n\u003Cli>Drag handle for resizing\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"grid-layouts\">Grid Layouts\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#grid-layouts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Grid Layouts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-column-grid\">2-Column Grid\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-column-grid\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2-Column Grid”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">grid grid-cols-1 md:grid-cols-2 gap-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Card\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Left\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Card\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Card\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Right\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Card\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="grid grid-cols-1 md:grid-cols-2 gap-4"> \u003CCard>Left\u003C/Card> \u003CCard>Right\u003C/Card>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"22-grid-regression\">2×2 Grid (Regression)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#22-grid-regression\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2×2 Grid (Regression)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">grid grid-cols-1 md:grid-cols-2 gap-4 h-full\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">charts\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">chart\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">chart\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">id\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">min-h-[280px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ScatterPlot\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="grid grid-cols-1 md:grid-cols-2 gap-4 h-full"> {charts.map(chart => ( \u003Cdiv key={chart.id} className="min-h-[280px]"> \u003CScatterPlot /> \u003C/div> ))}\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"auto-fit-grid\">Auto-fit Grid\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#auto-fit-grid\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Auto-fit Grid”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">grid gap-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">style\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">gridTemplateColumns: \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">repeat(auto-fit, minmax(300px, 1fr))\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">items\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">item\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Card\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">item\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">id\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">))\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="grid gap-4" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', }}> {items.map(item => ( \u003CCard key={item.id} /> ))}\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"flex-patterns\">Flex Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#flex-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Flex Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"row-with-space-between\">Row with Space Between\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#row-with-space-between\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Row with Space Between”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center justify-between\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Label\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Value\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">span\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex items-center justify-between"> \u003Cspan>Label\u003C/span> \u003Cspan>Value\u003C/span>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"centered-content\">Centered Content\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#centered-content\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Centered Content”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center justify-center h-full\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">EmptyState\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex items-center justify-center h-full"> \u003CEmptyState />\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"sticky-header-with-scrollable-content\">Sticky Header with Scrollable Content\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#sticky-header-with-scrollable-content\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sticky Header with Scrollable Content”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col h-full\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-none px-4 py-3 border-b border-slate-700\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Header\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-1 overflow-y-auto p-4\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Scrollable content\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex flex-col h-full"> \u003Cdiv className="flex-none px-4 py-3 border-b border-slate-700">Header\u003C/div> \u003Cdiv className="flex-1 overflow-y-auto p-4">Scrollable content\u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"chart-container-sizing\">Chart Container Sizing\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#chart-container-sizing\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Chart Container Sizing”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Charts need explicit height to render:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Fixed height\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">h-[400px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Flex sizing (parent must have height)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-1 min-h-0\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">IChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Grid cell\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">min-h-[280px]\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ScatterPlot\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// Fixed height\u003Cdiv className="h-[400px]"> \u003CIChart />\u003C/div>// Flex sizing (parent must have height)\u003Cdiv className="flex-1 min-h-0"> \u003CIChart />\u003C/div>// Grid cell\u003Cdiv className="min-h-[280px]"> \u003CScatterPlot />\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"responsive-breakpoints\">Responsive Breakpoints\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#responsive-breakpoints\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Responsive Breakpoints”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Breakpoint\u003C/th>\u003Cth>Width\u003C/th>\u003Cth>Layout Changes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Default\u003C/td>\u003Ctd>< 640px\u003C/td>\u003Ctd>Single column, mobile menu\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>sm\u003C/td>\u003Ctd>≥ 640px\u003C/td>\u003Ctd>Desktop header buttons\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>md\u003C/td>\u003Ctd>≥ 768px\u003C/td>\u003Ctd>2-column grids\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>lg\u003C/td>\u003Ctd>≥ 1024px\u003C/td>\u003Ctd>Full 3-panel dashboard\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>", + { + "headings": 12184, + "localImagePaths": 12238, + "remoteImagePaths": 12239, + "frontmatter": 12240, + "imagePaths": 12241 + }, + [ + 12185, 12187, 12190, 12193, 12196, 12199, 12202, 12205, 12208, 12211, 12214, 12217, 12220, + 12223, 12226, 12229, 12232, 12235 + ], + { "depth": 30, "slug": 12186, "text": 12174 }, + "layout-patterns", + { "depth": 33, "slug": 12188, "text": 12189 }, + "pwa-app-layout", + "PWA App Layout", + { "depth": 79, "slug": 12191, "text": 12192 }, + "without-data-panel", + "Without Data Panel", + { "depth": 79, "slug": 12194, "text": 12195 }, + "with-data-panel-toggled-via--button", + "With Data Panel (toggled via 📊 button)", + { "depth": 33, "slug": 12197, "text": 12198 }, + "dashboard-layout-desktop", + "Dashboard Layout (Desktop)", + { "depth": 79, "slug": 12200, "text": 12201 }, + "charts-only", + "Charts Only", + { "depth": 79, "slug": 12203, "text": 12204 }, + "with-data-panel", + "With Data Panel", + { "depth": 33, "slug": 12206, "text": 12207 }, + "dashboard-layout-mobile", + "Dashboard Layout (Mobile)", + { "depth": 33, "slug": 12209, "text": 12210 }, + "grid-layouts", + "Grid Layouts", + { "depth": 79, "slug": 12212, "text": 12213 }, + "2-column-grid", + "2-Column Grid", + { "depth": 79, "slug": 12215, "text": 12216 }, + "22-grid-regression", + "2×2 Grid (Regression)", + { "depth": 79, "slug": 12218, "text": 12219 }, + "auto-fit-grid", + "Auto-fit Grid", + { "depth": 33, "slug": 12221, "text": 12222 }, + "flex-patterns", + "Flex Patterns", + { "depth": 79, "slug": 12224, "text": 12225 }, + "row-with-space-between", + "Row with Space Between", + { "depth": 79, "slug": 12227, "text": 12228 }, + "centered-content", + "Centered Content", + { "depth": 79, "slug": 12230, "text": 12231 }, + "sticky-header-with-scrollable-content", + "Sticky Header with Scrollable Content", + { "depth": 33, "slug": 12233, "text": 12234 }, + "chart-container-sizing", + "Chart Container Sizing", + { "depth": 33, "slug": 12236, "text": 12237 }, + "responsive-breakpoints", + "Responsive Breakpoints", + [], + [], + { "title": 12174 }, + [], + "06-design-system/patterns/navigation", + { + "id": 12242, + "data": 12244, + "body": 12248, + "filePath": 12249, + "digest": 12250, + "rendered": 12251 + }, + { + "title": 11075, + "editUrl": 16, + "head": 12245, + "template": 18, + "sidebar": 12246, + "pagefind": 16, + "draft": 20 + }, + [], + { "hidden": 20, "attrs": 12247 }, + {}, + "# Navigation Patterns\n\nNavigation patterns used across VariScout applications.\n\n---\n\n## Filter Chips\n\nFilter chips show active filters with contribution % to total variation:\n\n```\n┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐\n│ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │\n└────────────────────┘ └────────────────────┘ └────────────────────┘\n```\n\n### Implementation\n\n```tsx\nimport { useFilterNavigation, useVariationTracking } from '@variscout/hooks';\n\nconst { filterStack, updateFilterValues, removeFilter } = useFilterNavigation(context);\nconst { filterChipData } = useVariationTracking(rawData, filterStack, outcome, factors);\n\n{\n filterChipData.map(chip => (\n \u003CFilterChipDropdown\n key={chip.factor}\n factor={chip.factor}\n values={chip.values}\n contributionPct={chip.contributionPct}\n availableValues={chip.availableValues}\n onValuesChange={newValues => updateFilterValues(chip.factor, newValues)}\n onRemove={() => removeFilter(chip.factor)}\n />\n ));\n}\n```\n\n### Visual Design\n\n| Element | Style |\n| --------------- | ---------------------------------------- |\n| Chip | Rounded pill with factor name and values |\n| Percentage | Contribution % to TOTAL variation |\n| Dropdown arrow | Click to reveal all values with % |\n| Selected values | Checkmarks in dropdown |\n| Remove button | X icon or \"Remove Filter\" in dropdown |\n\n### Multi-Select\n\nChips support selecting multiple values within a factor:\n\n```\n┌────────────────────────┐\n│ Machine: A, C ▼ 45% │\n└────────────────────────┘\n```\n\n---\n\n## Tab Navigation\n\nFor switching between analysis modes.\n\n### PWA\n\n```tsx\n\u003CTabs value={activeTab} onChange={setActiveTab}>\n \u003CTab value=\"analysis\">Analysis\u003C/Tab>\n \u003CTab value=\"performance\">Performance\u003C/Tab>\n \u003CTab value=\"data\">Data\u003C/Tab>\n\u003C/Tabs>\n```\n\n---\n\n## Sidebar Navigation\n\nDesktop layouts use a sidebar for factor selection.\n\n```\nFACTORS\n─────────────────\n○ Shift\n● Machine [selected]\n○ Operator\n○ Product\n\nMEASURES\n─────────────────\n○ Fill Weight\n● Moisture [selected]\n○ Defects\n```\n\n---\n\n## Mobile Menu\n\nMobile uses a hamburger menu with drawer:\n\n```tsx\n\u003CMobileMenu>\n \u003CMenuItem icon={\u003CBarChart />}>Analysis\u003C/MenuItem>\n \u003CMenuItem icon={\u003CSettings />}>Settings\u003C/MenuItem>\n \u003CMenuItem icon={\u003CHelpCircle />}>Help\u003C/MenuItem>\n\u003C/MobileMenu>\n```\n\n---\n\n## Keyboard Navigation\n\n| Key | Action |\n| ----------- | ----------------------------- |\n| `←` / `→` | Navigate between factors |\n| `↑` / `↓` | Navigate within factor levels |\n| `Enter` | Select/drill into |\n| `Backspace` | Remove last filter |\n| `Escape` | Exit focus mode |\n\n---\n\n## See Also\n\n- [Drill-Down Feature](../../03-features/navigation/drill-down.md)\n- [Filter Chips](../../03-features/navigation/breadcrumbs.md)\n- [Accessibility](../foundations/accessibility.md)", + "src/content/docs/06-design-system/patterns/navigation.md", + "32ed9c060272b503", + { "html": 12252, "metadata": 12253 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"navigation-patterns\">Navigation Patterns\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#navigation-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Navigation Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Navigation patterns used across VariScout applications.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"filter-chips\">Filter Chips\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#filter-chips\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter Chips”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Filter chips show active filters with contribution % to total variation:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────────────┘ └────────────────────┘ └────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐│ Shift: Night ▼ 67% │ │ Machine: C ▼ 24% │ │ Operator: Kim ▼ 9% │└────────────────────┘ └────────────────────┘ └────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"implementation\">Implementation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">import\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> { useFilterNavigation, useVariationTracking } \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">from\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">@variscout/hooks\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterStack\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeFilter\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useFilterNavigation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(context);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const { \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">filterChipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> } = \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useVariationTracking\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(rawData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterStack\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">outcome\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">factors);\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">filterChipData\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">map\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">chip\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">FilterChipDropdown\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">factor\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">factor\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">factor\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">values\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">values\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">contributionPct\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">contributionPct\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">availableValues\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">availableValues\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onValuesChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">newValues\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">updateFilterValues\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">factor\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">newValues)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onRemove\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003Cspan style=\"--0:#C792EA\">=>\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeFilter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(chip\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">factor\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">));\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"import { useFilterNavigation, useVariationTracking } from '@variscout/hooks';const { filterStack, updateFilterValues, removeFilter } = useFilterNavigation(context);const { filterChipData } = useVariationTracking(rawData, filterStack, outcome, factors);{ filterChipData.map(chip => ( \u003CFilterChipDropdown key={chip.factor} factor={chip.factor} values={chip.values} contributionPct={chip.contributionPct} availableValues={chip.availableValues} onValuesChange={newValues => updateFilterValues(chip.factor, newValues)} onRemove={() => removeFilter(chip.factor)} /> ));}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"visual-design\">Visual Design\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#visual-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Design”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Style\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Chip\u003C/td>\u003Ctd>Rounded pill with factor name and values\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Percentage\u003C/td>\u003Ctd>Contribution % to TOTAL variation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Dropdown arrow\u003C/td>\u003Ctd>Click to reveal all values with %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Selected values\u003C/td>\u003Ctd>Checkmarks in dropdown\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Remove button\u003C/td>\u003Ctd>X icon or “Remove Filter” in dropdown\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"multi-select\">Multi-Select\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#multi-select\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Multi-Select”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Chips support selecting multiple values within a factor:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ Machine: A, C ▼ 45% │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌────────────────────────┐│ Machine: A, C ▼ 45% │└────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tab-navigation\">Tab Navigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tab-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tab Navigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For switching between analysis modes.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pwa\">PWA\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pwa\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Tabs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">activeTab\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onChange\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">setActiveTab\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Tab\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">analysis\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Analysis\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Tab\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Tab\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">performance\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Performance\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Tab\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Tab\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">value\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">data\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Data\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Tab\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Tabs\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CTabs value={activeTab} onChange={setActiveTab}> \u003CTab value="analysis">Analysis\u003C/Tab> \u003CTab value="performance">Performance\u003C/Tab> \u003CTab value="data">Data\u003C/Tab>\u003C/Tabs>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sidebar-navigation\">Sidebar Navigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sidebar-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sidebar Navigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Desktop layouts use a sidebar for factor selection.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">FACTORS\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">─────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">○ Shift\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● Machine [selected]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">○ Operator\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">○ Product\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">MEASURES\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">─────────────────\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">○ Fill Weight\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">● Moisture [selected]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">○ Defects\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"FACTORS─────────────────○ Shift● Machine [selected]○ Operator○ ProductMEASURES─────────────────○ Fill Weight● Moisture [selected]○ Defects\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"mobile-menu\">Mobile Menu\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-menu\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Menu”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Mobile uses a hamburger menu with drawer:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"tsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">MobileMenu\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">MenuItem\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">icon\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">BarChart\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Analysis\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">MenuItem\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">MenuItem\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">icon\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">Settings\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Settings\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">MenuItem\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">MenuItem\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">icon\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">HelpCircle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Help\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">MenuItem\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"></\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">MobileMenu\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003CMobileMenu> \u003CMenuItem icon={\u003CBarChart />}>Analysis\u003C/MenuItem> \u003CMenuItem icon={\u003CSettings />}>Settings\u003C/MenuItem> \u003CMenuItem icon={\u003CHelpCircle />}>Help\u003C/MenuItem>\u003C/MobileMenu>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"keyboard-navigation\">Keyboard Navigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#keyboard-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Keyboard Navigation”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Key\u003C/th>\u003Cth>Action\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">←\u003C/code> / \u003Ccode dir=\"auto\">→\u003C/code>\u003C/td>\u003Ctd>Navigate between factors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">↑\u003C/code> / \u003Ccode dir=\"auto\">↓\u003C/code>\u003C/td>\u003Ctd>Navigate within factor levels\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Enter\u003C/code>\u003C/td>\u003Ctd>Select/drill into\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Backspace\u003C/code>\u003C/td>\u003Ctd>Remove last filter\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">Escape\u003C/code>\u003C/td>\u003Ctd>Exit focus mode\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../03-features/navigation/drill-down.md\">Drill-Down Feature\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../03-features/navigation/breadcrumbs.md\">Filter Chips\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../foundations/accessibility.md\">Accessibility\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 12254, + "localImagePaths": 12272, + "remoteImagePaths": 12273, + "frontmatter": 12274, + "imagePaths": 12275 + }, + [12255, 12256, 12257, 12258, 12259, 12260, 12263, 12264, 12267, 12270, 12271], + { "depth": 30, "slug": 11074, "text": 11075 }, + { "depth": 33, "slug": 7397, "text": 7398 }, + { "depth": 79, "slug": 1885, "text": 1886 }, + { "depth": 79, "slug": 3686, "text": 3687 }, + { "depth": 79, "slug": 7418, "text": 7419 }, + { "depth": 33, "slug": 12261, "text": 12262 }, + "tab-navigation", + "Tab Navigation", + { "depth": 79, "slug": 5545, "text": 5546 }, + { "depth": 33, "slug": 12265, "text": 12266 }, + "sidebar-navigation", + "Sidebar Navigation", + { "depth": 33, "slug": 12268, "text": 12269 }, + "mobile-menu", + "Mobile Menu", + { "depth": 33, "slug": 1194, "text": 1195 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 11075 }, + [], + "06-design-system/patterns/panels-and-drawers", + { + "id": 12276, + "data": 12278, + "body": 12283, + "filePath": 12284, + "digest": 12285, + "rendered": 12286 + }, + { + "title": 12279, + "editUrl": 16, + "head": 12280, + "template": 18, + "sidebar": 12281, + "pagefind": 16, + "draft": 20 + }, + "Panels and Drawers", + [], + { "hidden": 20, "attrs": 12282 }, + {}, + "# Panels and Drawers\n\nPanel patterns for VariScout, aligned with [Fluent 2 design principles](../../07-decisions/adr-017-fluent-design-alignment.md). Covers when to use each type, CSS patterns, responsive behavior, and dismiss conventions.\n\n## Decision Framework\n\n### When to use which panel type\n\n| Type | Fluent 2 Name | User Intent | Content Relationship | Example |\n| ----------- | --------------- | ---------------------------------- | ------------------------ | -------------------------- |\n| Inline | `DrawerInline` | Work with panel _and_ main content | Simultaneous / reference | DataPanel, FindingsPanel |\n| Overlay | `DrawerOverlay` | Focused attention on panel | Interrupting / settings | SettingsPanel |\n| Full-screen | Page / route | Dedicated workflow | Replaces main content | WhatIfPage |\n| Modal | `Dialog` | Quick confirmation or form | Blocking interaction | Reset confirmation, modals |\n\n### Decision tree\n\n```\nNeed to show supplementary content?\n├── User needs BOTH panel and main content visible?\n│ └── YES → Inline panel (flex-shrink-0, resizable divider)\n├── User needs FOCUSED attention on panel content?\n│ └── YES → Overlay panel (fixed, backdrop, slide-in-right)\n├── Content is a full workflow (multiple steps, complex interaction)?\n│ └── YES → Full-screen page (route or full-viewport component)\n└── Quick confirmation or small form?\n └── YES → Modal dialog (centered, backdrop blur)\n```\n\n---\n\n## Panel Type Specifications\n\n### Inline Panel\n\nSits beside the main content in a flex row. User works with both simultaneously.\n\n**Fluent 2 equivalent**: `DrawerInline`\n\n**CSS pattern**:\n\n```jsx\n\u003Cdiv className=\"flex flex-1 overflow-hidden\">\n \u003Cmain className=\"flex-1 overflow-hidden\">{content}\u003C/main>\n {/* Resizable divider */}\n \u003Cdiv\n className=\"w-1 bg-surface-tertiary hover:bg-blue-500 cursor-col-resize flex-shrink-0\"\n onMouseDown={handleMouseDown}\n />\n {/* Panel */}\n \u003Cdiv\n className=\"flex-shrink-0 bg-surface-secondary border-l border-edge flex flex-col overflow-hidden\"\n style={{ width }}\n >\n {panelContent}\n \u003C/div>\n\u003C/div>\n```\n\n**Current implementations**:\n\n| Panel | Width Range | Default | Storage Key | File |\n| ----------------- | ----------- | ------- | ---------------------------------- | ---------------------------------------------------------------- |\n| DataPanel (PWA) | 280–600px | 350px | `variscout-data-panel-width` | `apps/pwa/src/components/data/DataPanel.tsx` |\n| DataPanel (Azure) | 280–600px | 350px | `variscout-azure-data-panel-width` | `apps/azure/src/components/data/DataPanel.tsx` |\n| FindingsPanel | 320–600px | 384px | App-specific via `resizeConfig` | `packages/ui/src/components/FindingsPanel/FindingsPanelBase.tsx` |\n\n**Width persistence**: All inline panels use `useResizablePanel` from `@variscout/hooks`, which persists width to `localStorage` via the storage key.\n\n**Dismiss**: X button + Escape key. No backdrop (content is always visible alongside).\n\n---\n\n### Overlay Panel\n\nCovers part of the screen with a backdrop. User focuses on panel content.\n\n**Fluent 2 equivalent**: `DrawerOverlay`\n\n**CSS pattern**:\n\n```jsx\n\u003Cdiv className=\"fixed inset-0 z-[60] flex items-start justify-end\">\n {/* Backdrop */}\n \u003Cdiv className=\"absolute inset-0 bg-black/40\" onClick={onClose} />\n {/* Panel */}\n \u003Cdiv\n className=\"relative w-80 h-full bg-surface border-l border-edge shadow-2xl\n overflow-y-auto animate-slide-in-right\"\n >\n {panelContent}\n \u003C/div>\n\u003C/div>\n```\n\n**Current implementations**:\n\n| Panel | Width | z-index | Animation | File |\n| ------------- | ----- | -------- | -------------- | ---------------------------------------------------------------- |\n| SettingsPanel | 320px | `z-[60]` | slide-in-right | `packages/ui/src/components/SettingsPanel/SettingsPanelBase.tsx` |\n\n**Dismiss**: X button + Escape key + backdrop click.\n\n---\n\n### Full-Screen Page\n\nReplaces the main content entirely for dedicated workflows.\n\n**Fluent 2 equivalent**: Dedicated page / route\n\n**CSS pattern**:\n\n```jsx\n\u003Cdiv className=\"flex flex-col h-full bg-surface overflow-y-auto\">\n {/* Header with back button */}\n \u003Cdiv className=\"flex items-center gap-3 p-4 border-b border-edge\">\n \u003Cbutton onClick={onBack}>\n \u003CArrowLeft />\n \u003C/button>\n \u003Ch1>Page Title\u003C/h1>\n \u003C/div>\n {/* Page content */}\n \u003Cdiv className=\"flex-1 p-6\">{content}\u003C/div>\n\u003C/div>\n```\n\n**Current implementations**:\n\n| Page | Entry Point | File |\n| ---------- | ------------------------------------------- | ---------------------------------------------------------- |\n| WhatIfPage | Header button (PWA), toolbar button (Azure) | `packages/ui/src/components/WhatIfPage/WhatIfPageBase.tsx` |\n\n**Dismiss**: Back button (ArrowLeft). Escape typically not bound (page-level, not panel).\n\n---\n\n### Modal Dialog\n\nCentered overlay for quick confirmations or compact forms. See [Modals](../components/modals.md) for full patterns.\n\n**Fluent 2 equivalent**: `Dialog`\n\n**Dismiss**: X button + Escape key + backdrop click.\n\n---\n\n## Responsive Conversion\n\nWhen the viewport is below the phone breakpoint (\u003C 640px, `useIsMobile(640)`), inline panels convert to full-screen overlays.\n\n| Panel | Desktop (≥ 640px) | Phone (\u003C 640px) |\n| ------------- | ----------------------------- | -------------------------------------- |\n| DataPanel | Inline with resizable divider | Hidden; opens as DataTableModal |\n| FindingsPanel | Inline with resizable divider | Full-screen overlay (`z-40`, slide-up) |\n| SettingsPanel | Overlay (`z-[60]`) | Same (overlay already works on phone) |\n\n**Phone FindingsPanel pattern** (`Editor.tsx:1015`):\n\n```jsx\n{isPhone && panels.isFindingsOpen ? (\n \u003Cdiv className=\"fixed inset-0 z-40 bg-surface flex flex-col animate-slide-up safe-area-bottom\">\n {/* Header */}\n \u003Cdiv className=\"flex items-center justify-between px-4 py-3 border-b border-edge bg-surface-secondary\">\n \u003Ch2 className=\"text-sm font-semibold text-content\">Findings\u003C/h2>\n \u003Cbutton onClick={onClose} style={{ minWidth: 44, minHeight: 44 }}>\n \u003CX size={20} />\n \u003C/button>\n \u003C/div>\n \u003CFindingsPanel ... />\n \u003C/div>\n) : (\n /* Desktop inline panel */\n \u003CFindingsPanel ... />\n)}\n```\n\nTouch targets on phone use minimum 44×44px dimensions (`minWidth: 44, minHeight: 44`).\n\n---\n\n## Z-Index Scale\n\nExtended from the [Modals](../components/modals.md#z-index-scale) z-index table:\n\n| Level | z-index | Usage | Examples |\n| ------------------ | --------- | ------------------------------------ | ------------------------------------------ |\n| Sticky headers | `z-10` | Table headers, app header | `DataTableBase` thead, `AppHeader` |\n| Navigation | `z-30` | Sticky nav bars | Dashboard nav bar |\n| Phone overlays | `z-40` | Full-screen phone panels, backdrops | Phone FindingsPanel, MobileMenu backdrop |\n| Modals & dropdowns | `z-50` | Standard modals, popovers, menus | Confirmation modal, AxisEditor, MobileMenu |\n| Overlay panels | `z-[60]` | Panels above modals (settings, sync) | SettingsPanel, SyncToast |\n| Skip links | `z-[100]` | Accessibility skip-to-content | Skip link (`sr-only focus:z-[100]`) |\n\n**Rule**: Overlay panels use `z-[60]` so they appear above any modal that may be open underneath. Phone full-screen overlays use `z-40` because they replace the main content (no modal beneath).\n\n---\n\n## Dismiss Behavior Matrix\n\n| Panel Type | X Button | Escape | Backdrop Click | Back Button |\n| ----------- | -------- | ------ | -------------- | ----------- |\n| Inline | Yes | Yes | N/A | No |\n| Overlay | Yes | Yes | Yes | No |\n| Full-screen | No | No | N/A | Yes |\n| Modal | Yes | Yes | Yes | No |\n\nAll dismiss handlers use the same `useEffect` pattern:\n\n```jsx\nuseEffect(() => {\n if (!isOpen) return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n}, [isOpen, onClose]);\n```\n\n---\n\n## Animation Specifications\n\n| Animation | Class | Duration | Easing | Direction | Used By |\n| ----------------- | ------------------------ | -------- | -------- | ----------- | ---------------------------- |\n| Slide from right | `animate-slide-in-right` | 0.25s | ease-out | translateX | SettingsPanel |\n| Slide from bottom | `animate-slide-up` | 0.3s | ease-out | translateY | Phone overlays, mobile menus |\n| Fade in | `animate-fade-in` | 0.15s | ease-out | opacity + Y | Popovers, dropdown menus |\n\nDefined in `packages/ui/src/styles/components.css`.\n\n**Reduced motion**: Use `prefers-reduced-motion: reduce` media query to disable animations. Currently applied to chart highlight animations in `apps/pwa/src/index.css`. Panel animations should respect this preference — when adding new animations, wrap with:\n\n```css\n@media (prefers-reduced-motion: reduce) {\n .animate-slide-in-right,\n .animate-slide-up {\n animation: none;\n }\n}\n```\n\n---\n\n## Adding a New Panel — Checklist\n\n1. **Choose panel type**: Consult the decision tree above\n2. **Pick z-index**: Use the z-index scale table\n3. **Implement dismiss**: X button + Escape (all types), backdrop click (overlay/modal), back button (full-screen)\n4. **Add animation**: `animate-slide-in-right` (side panels), `animate-slide-up` (bottom/phone panels)\n5. **Handle responsive**: If inline panel, decide phone behavior (hide, convert to overlay, or convert to modal)\n6. **Persist width**: For inline resizable panels, use `useResizablePanel` with a unique storage key\n7. **Touch targets**: Ensure 44×44px minimum for phone interactions\n8. **Test Escape**: Verify `useEffect` cleanup removes listener on close\n9. **Update this doc**: Add the new panel to the relevant implementation table\n\n---\n\n## See Also\n\n- [ADR-017: Fluent 2 Design Alignment](../../07-decisions/adr-017-fluent-design-alignment.md) — Decision to adopt principles without library\n- [Modals](../components/modals.md) — Modal dialog patterns, sizing, keyboard handling\n- [Layout](layout.md) — Page layout patterns, dashboard grid, responsive breakpoints\n- [Interactions](interactions.md) — Inline editing, context menus, drag-and-drop", + "src/content/docs/06-design-system/patterns/panels-and-drawers.md", + "17e983ec2ee9365b", + { "html": 12287, "metadata": 12288 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"panels-and-drawers\">Panels and Drawers\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#panels-and-drawers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Panels and Drawers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Panel patterns for VariScout, aligned with \u003Ca href=\"../../07-decisions/adr-017-fluent-design-alignment.md\">Fluent 2 design principles\u003C/a>. Covers when to use each type, CSS patterns, responsive behavior, and dismiss conventions.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"decision-framework\">Decision Framework\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#decision-framework\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision Framework”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"when-to-use-which-panel-type\">When to use which panel type\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-use-which-panel-type\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to use which panel type”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Type\u003C/th>\u003Cth>Fluent 2 Name\u003C/th>\u003Cth>User Intent\u003C/th>\u003Cth>Content Relationship\u003C/th>\u003Cth>Example\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Inline\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DrawerInline\u003C/code>\u003C/td>\u003Ctd>Work with panel \u003Cem>and\u003C/em> main content\u003C/td>\u003Ctd>Simultaneous / reference\u003C/td>\u003Ctd>DataPanel, FindingsPanel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Overlay\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DrawerOverlay\u003C/code>\u003C/td>\u003Ctd>Focused attention on panel\u003C/td>\u003Ctd>Interrupting / settings\u003C/td>\u003Ctd>SettingsPanel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Full-screen\u003C/td>\u003Ctd>Page / route\u003C/td>\u003Ctd>Dedicated workflow\u003C/td>\u003Ctd>Replaces main content\u003C/td>\u003Ctd>WhatIfPage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Modal\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">Dialog\u003C/code>\u003C/td>\u003Ctd>Quick confirmation or form\u003C/td>\u003Ctd>Blocking interaction\u003C/td>\u003Ctd>Reset confirmation, modals\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"decision-tree\">Decision tree\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#decision-tree\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Decision tree”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Need to show supplementary content?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── User needs BOTH panel and main content visible?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── YES → Inline panel (flex-shrink-0, resizable divider)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── User needs FOCUSED attention on panel content?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── YES → Overlay panel (fixed, backdrop, slide-in-right)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Content is a full workflow (multiple steps, complex interaction)?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └── YES → Full-screen page (route or full-viewport component)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Quick confirmation or small form?\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── YES → Modal dialog (centered, backdrop blur)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Need to show supplementary content?├── User needs BOTH panel and main content visible?│ └── YES → Inline panel (flex-shrink-0, resizable divider)├── User needs FOCUSED attention on panel content?│ └── YES → Overlay panel (fixed, backdrop, slide-in-right)├── Content is a full workflow (multiple steps, complex interaction)?│ └── YES → Full-screen page (route or full-viewport component)└── Quick confirmation or small form? └── YES → Modal dialog (centered, backdrop blur)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"panel-type-specifications\">Panel Type Specifications\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#panel-type-specifications\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Panel Type Specifications”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"inline-panel\">Inline Panel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#inline-panel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Inline Panel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Sits beside the main content in a flex row. User works with both simultaneously.\u003C/p>\n\u003Cp>\u003Cstrong>Fluent 2 equivalent\u003C/strong>: \u003Ccode dir=\"auto\">DrawerInline\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>CSS pattern\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-1 overflow-hidden\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">main\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-1 overflow-hidden\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">content\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">main\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Resizable divider */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">w-1 bg-surface-tertiary hover:bg-blue-500 cursor-col-resize flex-shrink-0\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onMouseDown\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">handleMouseDown\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">/>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Panel */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-shrink-0 bg-surface-secondary border-l border-edge flex flex-col overflow-hidden\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">style\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ \u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">width\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">panelContent\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex flex-1 overflow-hidden"> \u003Cmain className="flex-1 overflow-hidden">{content}\u003C/main> {/* Resizable divider */} \u003Cdiv className="w-1 bg-surface-tertiary hover:bg-blue-500 cursor-col-resize flex-shrink-0" onMouseDown={handleMouseDown} /> {/* Panel */} \u003Cdiv className="flex-shrink-0 bg-surface-secondary border-l border-edge flex flex-col overflow-hidden" style={{ width }} > {panelContent} \u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Current implementations\u003C/strong>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Panel\u003C/th>\u003Cth>Width Range\u003C/th>\u003Cth>Default\u003C/th>\u003Cth>Storage Key\u003C/th>\u003Cth>File\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>DataPanel (PWA)\u003C/td>\u003Ctd>280–600px\u003C/td>\u003Ctd>350px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">variscout-data-panel-width\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/pwa/src/components/data/DataPanel.tsx\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>DataPanel (Azure)\u003C/td>\u003Ctd>280–600px\u003C/td>\u003Ctd>350px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">variscout-azure-data-panel-width\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">apps/azure/src/components/data/DataPanel.tsx\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>FindingsPanel\u003C/td>\u003Ctd>320–600px\u003C/td>\u003Ctd>384px\u003C/td>\u003Ctd>App-specific via \u003Ccode dir=\"auto\">resizeConfig\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/FindingsPanel/FindingsPanelBase.tsx\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Width persistence\u003C/strong>: All inline panels use \u003Ccode dir=\"auto\">useResizablePanel\u003C/code> from \u003Ccode dir=\"auto\">@variscout/hooks\u003C/code>, which persists width to \u003Ccode dir=\"auto\">localStorage\u003C/code> via the storage key.\u003C/p>\n\u003Cp>\u003Cstrong>Dismiss\u003C/strong>: X button + Escape key. No backdrop (content is always visible alongside).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"overlay-panel\">Overlay Panel\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#overlay-panel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overlay Panel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Covers part of the screen with a backdrop. User focuses on panel content.\u003C/p>\n\u003Cp>\u003Cstrong>Fluent 2 equivalent\u003C/strong>: \u003Ccode dir=\"auto\">DrawerOverlay\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>CSS pattern\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">fixed inset-0 z-[60] flex items-start justify-end\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Backdrop */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">absolute inset-0 bg-black/40\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">onClose\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Panel */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">relative w-80 h-full bg-surface border-l border-edge shadow-2xl\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">overflow-y-auto animate-slide-in-right\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">panelContent\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="fixed inset-0 z-[60] flex items-start justify-end"> {/* Backdrop */} \u003Cdiv className="absolute inset-0 bg-black/40" onClick={onClose} /> {/* Panel */} \u003Cdiv className="relative w-80 h-full bg-surface border-l border-edge shadow-2xl overflow-y-auto animate-slide-in-right" > {panelContent} \u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Current implementations\u003C/strong>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Panel\u003C/th>\u003Cth>Width\u003C/th>\u003Cth>z-index\u003C/th>\u003Cth>Animation\u003C/th>\u003Cth>File\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>SettingsPanel\u003C/td>\u003Ctd>320px\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">z-[60]\u003C/code>\u003C/td>\u003Ctd>slide-in-right\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/SettingsPanel/SettingsPanelBase.tsx\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Dismiss\u003C/strong>: X button + Escape key + backdrop click.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"full-screen-page\">Full-Screen Page\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#full-screen-page\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Full-Screen Page”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Replaces the main content entirely for dedicated workflows.\u003C/p>\n\u003Cp>\u003Cstrong>Fluent 2 equivalent\u003C/strong>: Dedicated page / route\u003C/p>\n\u003Cp>\u003Cstrong>CSS pattern\u003C/strong>:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex flex-col h-full bg-surface overflow-y-auto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Header with back button */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center gap-3 p-4 border-b border-edge\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">onBack\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">ArrowLeft\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h1\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Page Title\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h1\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Page content */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex-1 p-6\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">content\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"\u003Cdiv className="flex flex-col h-full bg-surface overflow-y-auto"> {/* Header with back button */} \u003Cdiv className="flex items-center gap-3 p-4 border-b border-edge"> \u003Cbutton onClick={onBack}> \u003CArrowLeft /> \u003C/button> \u003Ch1>Page Title\u003C/h1> \u003C/div> {/* Page content */} \u003Cdiv className="flex-1 p-6">{content}\u003C/div>\u003C/div>\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>Current implementations\u003C/strong>:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Page\u003C/th>\u003Cth>Entry Point\u003C/th>\u003Cth>File\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>WhatIfPage\u003C/td>\u003Ctd>Header button (PWA), toolbar button (Azure)\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packages/ui/src/components/WhatIfPage/WhatIfPageBase.tsx\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Dismiss\u003C/strong>: Back button (ArrowLeft). Escape typically not bound (page-level, not panel).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"modal-dialog\">Modal Dialog\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#modal-dialog\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Modal Dialog”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Centered overlay for quick confirmations or compact forms. See \u003Ca href=\"../components/modals.md\">Modals\u003C/a> for full patterns.\u003C/p>\n\u003Cp>\u003Cstrong>Fluent 2 equivalent\u003C/strong>: \u003Ccode dir=\"auto\">Dialog\u003C/code>\u003C/p>\n\u003Cp>\u003Cstrong>Dismiss\u003C/strong>: X button + Escape key + backdrop click.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"responsive-conversion\">Responsive Conversion\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#responsive-conversion\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Responsive Conversion”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>When the viewport is below the phone breakpoint (< 640px, \u003Ccode dir=\"auto\">useIsMobile(640)\u003C/code>), inline panels convert to full-screen overlays.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Panel\u003C/th>\u003Cth>Desktop (≥ 640px)\u003C/th>\u003Cth>Phone (< 640px)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>DataPanel\u003C/td>\u003Ctd>Inline with resizable divider\u003C/td>\u003Ctd>Hidden; opens as DataTableModal\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>FindingsPanel\u003C/td>\u003Ctd>Inline with resizable divider\u003C/td>\u003Ctd>Full-screen overlay (\u003Ccode dir=\"auto\">z-40\u003C/code>, slide-up)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>SettingsPanel\u003C/td>\u003Ctd>Overlay (\u003Ccode dir=\"auto\">z-[60]\u003C/code>)\u003C/td>\u003Ctd>Same (overlay already works on phone)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Phone FindingsPanel pattern\u003C/strong> (\u003Ccode dir=\"auto\">Editor.tsx:1015\u003C/code>):\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">isPhone\u003C/span>\u003Cspan style=\"--0:#D6DEEB\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">&&\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">panels\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">isFindingsOpen\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">fixed inset-0 z-40 bg-surface flex flex-col animate-slide-up safe-area-bottom\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Header */\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">flex items-center justify-between px-4 py-3 border-b border-edge bg-surface-secondary\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">className\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">text-sm font-semibold text-content\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">\"\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">Findings\u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">h2\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"><\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">onClick\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">onClose\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">style\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">{ minWidth: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">44\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">, minHeight: \u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">44\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> }\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\">>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">X\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">size\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">{\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">20\u003C/span>\u003Cspan style=\"--0:#E2817F;--1:#B23834\">}\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">button\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">FindingsPanel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFFFFF;--1:#984E4D\">...\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--1:#8844AE\">\u003Cspan style=\"--0:#7FDBCA\"></\u003C/span>\u003Cspan style=\"--0:#CAECE6\">div\u003C/span>\u003Cspan style=\"--0:#7FDBCA\">>\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">) \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5F636F\">/* Desktop inline panel */\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"><\u003C/span>\u003Cspan style=\"--0:#F78C6C;--1:#AA0982\">FindingsPanel\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFFFFF;--1:#984E4D\">...\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#8844AE\"> />\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"{isPhone && panels.isFindingsOpen ? ( \u003Cdiv className="fixed inset-0 z-40 bg-surface flex flex-col animate-slide-up safe-area-bottom"> {/* Header */} \u003Cdiv className="flex items-center justify-between px-4 py-3 border-b border-edge bg-surface-secondary"> \u003Ch2 className="text-sm font-semibold text-content">Findings\u003C/h2> \u003Cbutton onClick={onClose} style={{ minWidth: 44, minHeight: 44 }}> \u003CX size={20} /> \u003C/button> \u003C/div> \u003CFindingsPanel ... /> \u003C/div>) : ( /* Desktop inline panel */ \u003CFindingsPanel ... />)}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Touch targets on phone use minimum 44×44px dimensions (\u003Ccode dir=\"auto\">minWidth: 44, minHeight: 44\u003C/code>).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"z-index-scale\">Z-Index Scale\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#z-index-scale\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Z-Index Scale”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Extended from the \u003Ca href=\"../components/modals.md#z-index-scale\">Modals\u003C/a> z-index table:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Level\u003C/th>\u003Cth>z-index\u003C/th>\u003Cth>Usage\u003C/th>\u003Cth>Examples\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Sticky headers\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">z-10\u003C/code>\u003C/td>\u003Ctd>Table headers, app header\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">DataTableBase\u003C/code> thead, \u003Ccode dir=\"auto\">AppHeader\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Navigation\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">z-30\u003C/code>\u003C/td>\u003Ctd>Sticky nav bars\u003C/td>\u003Ctd>Dashboard nav bar\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Phone overlays\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">z-40\u003C/code>\u003C/td>\u003Ctd>Full-screen phone panels, backdrops\u003C/td>\u003Ctd>Phone FindingsPanel, MobileMenu backdrop\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Modals & dropdowns\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">z-50\u003C/code>\u003C/td>\u003Ctd>Standard modals, popovers, menus\u003C/td>\u003Ctd>Confirmation modal, AxisEditor, MobileMenu\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Overlay panels\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">z-[60]\u003C/code>\u003C/td>\u003Ctd>Panels above modals (settings, sync)\u003C/td>\u003Ctd>SettingsPanel, SyncToast\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Skip links\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">z-[100]\u003C/code>\u003C/td>\u003Ctd>Accessibility skip-to-content\u003C/td>\u003Ctd>Skip link (\u003Ccode dir=\"auto\">sr-only focus:z-[100]\u003C/code>)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Rule\u003C/strong>: Overlay panels use \u003Ccode dir=\"auto\">z-[60]\u003C/code> so they appear above any modal that may be open underneath. Phone full-screen overlays use \u003Ccode dir=\"auto\">z-40\u003C/code> because they replace the main content (no modal beneath).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dismiss-behavior-matrix\">Dismiss Behavior Matrix\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dismiss-behavior-matrix\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dismiss Behavior Matrix”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Panel Type\u003C/th>\u003Cth>X Button\u003C/th>\u003Cth>Escape\u003C/th>\u003Cth>Backdrop Click\u003C/th>\u003Cth>Back Button\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Inline\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>N/A\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Overlay\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Full-screen\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>N/A\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Modal\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>All dismiss handlers use the same \u003Ccode dir=\"auto\">useEffect\u003C/code> pattern:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"jsx\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">useEffect\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> (\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">!\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D7DBE0\">isOpen\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">) \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">handleKeyDown\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> = \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">e\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--1:#111111\">\u003Cspan style=\"--0:#FFCB8B\">KeyboardEvent\u003C/span>\u003Cspan style=\"--0:#D9F5DD\">)\u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> => {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">if \u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">e\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">key\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> === \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">Escape\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">)\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">onClose\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">()\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">}\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">document\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">addEventListener\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">keydown\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">handleKeyDown\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">return\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">=>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">document\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">.\u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">removeEventListener\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">(\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">keydown\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">handleKeyDown\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--1:#403F53\">\u003Cspan style=\"--0:#D6DEEB\">}, [\u003C/span>\u003Cspan style=\"--0:#D7DBE0\">isOpen\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">, \u003C/span>\u003Cspan style=\"--0:#D7DBE0\">onClose\u003C/span>\u003Cspan style=\"--0:#D6DEEB\">]);\u003C/span>\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"useEffect(() => { if (!isOpen) return; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown);}, [isOpen, onClose]);\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"animation-specifications\">Animation Specifications\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#animation-specifications\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Animation Specifications”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Animation\u003C/th>\u003Cth>Class\u003C/th>\u003Cth>Duration\u003C/th>\u003Cth>Easing\u003C/th>\u003Cth>Direction\u003C/th>\u003Cth>Used By\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Slide from right\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">animate-slide-in-right\u003C/code>\u003C/td>\u003Ctd>0.25s\u003C/td>\u003Ctd>ease-out\u003C/td>\u003Ctd>translateX\u003C/td>\u003Ctd>SettingsPanel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Slide from bottom\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">animate-slide-up\u003C/code>\u003C/td>\u003Ctd>0.3s\u003C/td>\u003Ctd>ease-out\u003C/td>\u003Ctd>translateY\u003C/td>\u003Ctd>Phone overlays, mobile menus\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Fade in\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">animate-fade-in\u003C/code>\u003C/td>\u003Ctd>0.15s\u003C/td>\u003Ctd>ease-out\u003C/td>\u003Ctd>opacity + Y\u003C/td>\u003Ctd>Popovers, dropdown menus\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Defined in \u003Ccode dir=\"auto\">packages/ui/src/styles/components.css\u003C/code>.\u003C/p>\n\u003Cp>\u003Cstrong>Reduced motion\u003C/strong>: Use \u003Ccode dir=\"auto\">prefers-reduced-motion: reduce\u003C/code> media query to disable animations. Currently applied to chart highlight animations in \u003Ccode dir=\"auto\">apps/pwa/src/index.css\u003C/code>. Panel animations should respect this preference — when adding new animations, wrap with:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"css\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">@media\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">prefers-reduced-motion: reduce\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">.animate-slide-in-right\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">,\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">.animate-slide-up\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\"> \u003C/span>\u003Cspan style=\"--0:#80CBC4;--1:#096E72\">animation\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">: \u003C/span>\u003Cspan style=\"--0:#FF6D6D;--1:#984E4D\">none\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"@media (prefers-reduced-motion: reduce) { .animate-slide-in-right, .animate-slide-up { animation: none; }}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"adding-a-new-panel--checklist\">Adding a New Panel — Checklist\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#adding-a-new-panel--checklist\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Adding a New Panel — Checklist”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Choose panel type\u003C/strong>: Consult the decision tree above\u003C/li>\n\u003Cli>\u003Cstrong>Pick z-index\u003C/strong>: Use the z-index scale table\u003C/li>\n\u003Cli>\u003Cstrong>Implement dismiss\u003C/strong>: X button + Escape (all types), backdrop click (overlay/modal), back button (full-screen)\u003C/li>\n\u003Cli>\u003Cstrong>Add animation\u003C/strong>: \u003Ccode dir=\"auto\">animate-slide-in-right\u003C/code> (side panels), \u003Ccode dir=\"auto\">animate-slide-up\u003C/code> (bottom/phone panels)\u003C/li>\n\u003Cli>\u003Cstrong>Handle responsive\u003C/strong>: If inline panel, decide phone behavior (hide, convert to overlay, or convert to modal)\u003C/li>\n\u003Cli>\u003Cstrong>Persist width\u003C/strong>: For inline resizable panels, use \u003Ccode dir=\"auto\">useResizablePanel\u003C/code> with a unique storage key\u003C/li>\n\u003Cli>\u003Cstrong>Touch targets\u003C/strong>: Ensure 44×44px minimum for phone interactions\u003C/li>\n\u003Cli>\u003Cstrong>Test Escape\u003C/strong>: Verify \u003Ccode dir=\"auto\">useEffect\u003C/code> cleanup removes listener on close\u003C/li>\n\u003Cli>\u003Cstrong>Update this doc\u003C/strong>: Add the new panel to the relevant implementation table\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-017-fluent-design-alignment.md\">ADR-017: Fluent 2 Design Alignment\u003C/a> — Decision to adopt principles without library\u003C/li>\n\u003Cli>\u003Ca href=\"../components/modals.md\">Modals\u003C/a> — Modal dialog patterns, sizing, keyboard handling\u003C/li>\n\u003Cli>\u003Ca href=\"layout.md\">Layout\u003C/a> — Page layout patterns, dashboard grid, responsive breakpoints\u003C/li>\n\u003Cli>\u003Ca href=\"interactions.md\">Interactions\u003C/a> — Inline editing, context menus, drag-and-drop\u003C/li>\n\u003C/ul>", + { + "headings": 12289, + "localImagePaths": 12330, + "remoteImagePaths": 12331, + "frontmatter": 12332, + "imagePaths": 12333 + }, + [ + 12290, 12292, 12295, 12298, 12301, 12304, 12307, 12310, 12313, 12316, 12319, 12320, 12323, + 12326, 12329 + ], + { "depth": 30, "slug": 12291, "text": 12279 }, + "panels-and-drawers", + { "depth": 33, "slug": 12293, "text": 12294 }, + "decision-framework", + "Decision Framework", + { "depth": 79, "slug": 12296, "text": 12297 }, + "when-to-use-which-panel-type", + "When to use which panel type", + { "depth": 79, "slug": 12299, "text": 12300 }, + "decision-tree", + "Decision tree", + { "depth": 33, "slug": 12302, "text": 12303 }, + "panel-type-specifications", + "Panel Type Specifications", + { "depth": 79, "slug": 12305, "text": 12306 }, + "inline-panel", + "Inline Panel", + { "depth": 79, "slug": 12308, "text": 12309 }, + "overlay-panel", + "Overlay Panel", + { "depth": 79, "slug": 12311, "text": 12312 }, + "full-screen-page", + "Full-Screen Page", + { "depth": 79, "slug": 12314, "text": 12315 }, + "modal-dialog", + "Modal Dialog", + { "depth": 33, "slug": 12317, "text": 12318 }, + "responsive-conversion", + "Responsive Conversion", + { "depth": 33, "slug": 10946, "text": 10947 }, + { "depth": 33, "slug": 12321, "text": 12322 }, + "dismiss-behavior-matrix", + "Dismiss Behavior Matrix", + { "depth": 33, "slug": 12324, "text": 12325 }, + "animation-specifications", + "Animation Specifications", + { "depth": 33, "slug": 12327, "text": 12328 }, + "adding-a-new-panel--checklist", + "Adding a New Panel — Checklist", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 12279 }, + [], + "08-products/powerbi", + { + "id": 12334, + "data": 12336, + "body": 12341, + "filePath": 12342, + "digest": 12343, + "rendered": 12344 + }, + { + "title": 12337, + "editUrl": 16, + "head": 12338, + "template": 18, + "sidebar": 12339, + "pagefind": 16, + "draft": 20 + }, + "Power BI Custom Visuals", + [], + { "hidden": 20, "attrs": 12340 }, + {}, + "# Power BI Custom Visuals\n\nVariScout charts as Power BI custom visuals.\n\n---\n\n## Status\n\n**Planned** - Not yet in development.\n\n---\n\n## Concept\n\nPower BI custom visuals would bring VariScout charts to Power BI dashboards:\n\n- Native Power BI data binding\n- Linked filtering via Power BI slicers\n- VariScout methodology in BI context\n\n---\n\n## Planned Visuals\n\n| Visual | Description | Priority |\n| ---------- | ------------------------- | -------- |\n| I-Chart | Control chart with limits | High |\n| Boxplot | Factor comparison | High |\n| Capability | Histogram with specs | Medium |\n| Pareto | Category ranking | Medium |\n\n---\n\n## Technical Approach\n\n- Use Power BI visuals SDK\n- Port Visx charts to visuals framework\n- Share calculation logic from @variscout/core\n\n---\n\n## Distribution\n\n- Power BI AppSource\n- Organizational visuals\n\n---\n\n## See Also\n\n- [Products Overview](../index.md)", + "src/content/docs/08-products/powerbi/index.md", + "fa692e32fbcfc3fe", + { "html": 12345, "metadata": 12346 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"power-bi-custom-visuals\">Power BI Custom Visuals\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#power-bi-custom-visuals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Power BI Custom Visuals”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout charts as Power BI custom visuals.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"status\">Status\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#status\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Status”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Planned\u003C/strong> - Not yet in development.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"concept\">Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Power BI custom visuals would bring VariScout charts to Power BI dashboards:\u003C/p>\n\u003Cul>\n\u003Cli>Native Power BI data binding\u003C/li>\n\u003Cli>Linked filtering via Power BI slicers\u003C/li>\n\u003Cli>VariScout methodology in BI context\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"planned-visuals\">Planned Visuals\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#planned-visuals\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Planned Visuals”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Visual\u003C/th>\u003Cth>Description\u003C/th>\u003Cth>Priority\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>I-Chart\u003C/td>\u003Ctd>Control chart with limits\u003C/td>\u003Ctd>High\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Factor comparison\u003C/td>\u003Ctd>High\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability\u003C/td>\u003Ctd>Histogram with specs\u003C/td>\u003Ctd>Medium\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto\u003C/td>\u003Ctd>Category ranking\u003C/td>\u003Ctd>Medium\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-approach\">Technical Approach\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-approach\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Approach”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Use Power BI visuals SDK\u003C/li>\n\u003Cli>Port Visx charts to visuals framework\u003C/li>\n\u003Cli>Share calculation logic from @variscout/core\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"distribution\">Distribution\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#distribution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Distribution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Power BI AppSource\u003C/li>\n\u003Cli>Organizational visuals\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../index.md\">Products Overview\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 12347, + "localImagePaths": 12362, + "remoteImagePaths": 12363, + "frontmatter": 12364, + "imagePaths": 12365 + }, + [12348, 12350, 12353, 12354, 12357, 12360, 12361], + { "depth": 30, "slug": 12349, "text": 12337 }, + "power-bi-custom-visuals", + { "depth": 33, "slug": 12351, "text": 12352 }, + "status", + "Status", + { "depth": 33, "slug": 7160, "text": 7161 }, + { "depth": 33, "slug": 12355, "text": 12356 }, + "planned-visuals", + "Planned Visuals", + { "depth": 33, "slug": 12358, "text": 12359 }, + "technical-approach", + "Technical Approach", + { "depth": 33, "slug": 11667, "text": 11668 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 12337 }, + [], + "08-products/pwa", + { + "id": 12366, + "data": 12368, + "body": 12373, + "filePath": 12374, + "digest": 12375, + "rendered": 12376 + }, + { + "title": 12369, + "editUrl": 16, + "head": 12370, + "template": 18, + "sidebar": 12371, + "pagefind": 16, + "draft": 20 + }, + "PWA (Free Training Tool)", + [], + { "hidden": 20, "attrs": 12372 }, + {}, + "# PWA (Free Training Tool)\n\n> **Role**: Free variation analysis training and education tool for quality professionals, students, and developing countries.\n>\n> Per [ADR-007](../../07-decisions/adr-007-azure-marketplace-distribution.md), the PWA provides free access to core analysis features. The [Azure App](../azure/index.md) adds file upload (alongside paste), save/persistence, Performance Mode, and team features.\n\n---\n\n## Purpose: Free Training & Education\n\nThe PWA is a **free variation analysis training tool** that provides:\n\n1. **Core analysis for everyone** — I-Chart, Boxplot, Pareto, Capability, ANOVA\n2. **Pre-loaded case study datasets** — Same datasets as documentation\n3. **Copy-paste from Excel/Sheets** — No file upload, paste data directly\n4. **Zero friction** — No signup, no payment, no installation required\n\n```mermaid\nflowchart LR\n A[Paste Data or Load Sample] --> B[Auto-Detect Columns]\n B --> C[Confirm Mapping]\n C --> D[Analyze with Full Toolkit]\n D --> E{Need More?}\n E -->|File upload, save, teams| F[Azure App]\n```\n\n---\n\n## Target Users\n\n| User | Context | Why PWA Works |\n| --------------------- | -------------------------------- | ------------------------------------------ |\n| **LSS Trainers** | Green Belt / Black Belt courses | Minitab replacement with zero installation |\n| **Students** | University statistics courses | Free, browser-based, no license needed |\n| **Quality Champions** | SMEs in developing countries | Better tools than Excel, completely free |\n| **Evaluators** | Assessing VariScout capabilities | Try with sample data before purchasing |\n\n---\n\n## Pre-Loaded Case Studies\n\nThe PWA comes with datasets from the documentation case studies:\n\n| Dataset | Case Study | Demonstrates |\n| ------------- | ----------------------------------------------------------- | ------------------------ |\n| Coffee | [Coffee Case](../../04-cases/coffee/index.md) | Factor comparison, MSA |\n| Bottleneck | [Bottleneck Case](../../04-cases/bottleneck/index.md) | Process flow, drill-down |\n| Hospital Ward | [Hospital Ward Case](../../04-cases/hospital-ward/index.md) | Aggregation trap |\n| Packaging | [Packaging Case](../../04-cases/packaging/index.md) | Pareto, capability |\n\n**Learning continuity**: The same data appears in docs, PWA, and teaching materials.\n\n---\n\n## Features (Free)\n\nAll core analysis features:\n\n- I-Chart, Boxplot, Pareto, Capability Histogram, ANOVA\n- Drill-down with breadcrumb navigation\n- Linked filtering across charts\n- Data input: copy-paste from Excel/Sheets + sample datasets\n- VariScout branding on charts\n\n---\n\n## Restrictions (Free Tier)\n\n| Feature | PWA (Free) | Azure App (Paid) |\n| ----------------------- | ------------ | ---------------- |\n| Paste data | ✓ | ✓ |\n| File upload (CSV/Excel) | - | ✓ |\n| .vrs import/export | - | ✓ |\n| Save/persistence | Session only | OneDrive sync |\n| Performance Mode | - | ✓ |\n| Branding on charts | Always shown | Hidden |\n| Authentication | None | Microsoft SSO |\n| Team collaboration | - | Shared projects |\n\n---\n\n## Use Cases\n\n| Use Case | Appropriate | Notes |\n| ------------------------ | :---------: | ---------------------------------- |\n| SPC training courses | ✓ | Full Green Belt coverage |\n| University education | ✓ | Free, no license needed |\n| Try case study data | ✓ | Pre-loaded datasets |\n| Analyze own data (paste) | ✓ | Copy-paste from Excel |\n| Demo to stakeholders | ✓ | No setup required |\n| **Production use** | ✗ | Use [Azure App](../azure/index.md) |\n| **Team collaboration** | ✗ | Use Azure App with OneDrive |\n| **File upload** | ✗ | Use Azure App |\n| **Data persistence** | ✗ | Session only (no save) |\n\n---\n\n## Technical Stack\n\n| Component | Technology |\n| --------- | ------------------------- |\n| Framework | React 18 + TypeScript |\n| Build | Vite |\n| Styling | Tailwind CSS |\n| Charts | Visx (@variscout/charts) |\n| State | React Context |\n| Offline | Workbox (vite-plugin-pwa) |\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│ USER'S BROWSER │\n├─────────────────────────────────────────────────────────────────┤\n│ ┌─────────────────────────────────────────────────────────────┐ │\n│ │ REACT APPLICATION │ │\n│ │ DataContext → Charts → Analysis │ │\n│ └─────────────────────────────────────────────────────────────┘ │\n│ │\n│ ┌─────────────────────────────────────────────────────────────┐ │\n│ │ Service Worker (Workbox, offline) │ │\n│ └─────────────────────────────────────────────────────────────┘ │\n└──────────────────────────────────────────────────────────────────┘\n```\n\n### Service Worker (Workbox)\n\nConfigured via `vite-plugin-pwa` with `autoUpdate` strategy:\n\n- **clientsClaim + skipWaiting** — new service worker activates immediately\n- **navigateFallback** — `/index.html` for SPA offline routing\n- **globPatterns** — caches `**/*.{js,css,html,ico,png,svg,woff,woff2}`\n- Self-hosted Caveat font (no CDN dependency — works fully offline)\n\n### Code Splitting\n\n`React.lazy` splits 9 route-level components (Dashboard, HomeScreen, PasteScreen, ManualEntry, WhatIfPage, SettingsPanel, DataTableModal, DataPanel, FindingsPanel). Bundle analysis available via `ANALYZE=true pnpm build`.\n\n### Accessibility\n\n- `aria-live` region for dynamic chart updates (Dashboard)\n- Per-chart `ErrorBoundary` — one chart failure doesn't crash the app\n- `prefers-reduced-motion` media query respected in CSS animations\n\n---\n\n## Development Commands\n\n```bash\n# Start development server\npnpm dev\n\n# Build for production\npnpm build\n\n# Run tests\npnpm --filter @variscout/pwa test\n```\n\n---\n\n## Role in Development Workflow\n\nThe PWA serves as the **feature development sandbox**:\n\n1. **New features** are prototyped in the PWA first\n2. **Shared packages** are developed against PWA use cases\n3. **Azure App** adopts features after PWA validation\n\n---\n\n## Upgrade Path\n\n| Ready For... | Next Step |\n| ------------------------ | ------------------------------------------------------------------------------- |\n| File upload, save, teams | [Azure App](../azure/index.md) — from €99/month (Standard) or €299/month (Team) |\n\n---\n\n## See Also\n\n- [Storage](storage.md) - IndexedDB and session storage details\n- [Azure App (Primary Product)](../azure/index.md) - Production platform\n- [Feature Parity](../feature-parity.md) - Platform comparison\n- [ADR-007: Distribution Strategy](../../07-decisions/adr-007-azure-marketplace-distribution.md)\n- [ADR-004: Offline-First](../../07-decisions/adr-004-offline-first.md)", + "src/content/docs/08-products/pwa/index.md", + "8d1b8a7c6bfec4c7", + { "html": 12377, "metadata": 12378 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"pwa-free-training-tool\">PWA (Free Training Tool)\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-free-training-tool\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA (Free Training Tool)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>Role\u003C/strong>: Free variation analysis training and education tool for quality professionals, students, and developing countries.\u003C/p>\n\u003Cp>Per \u003Ca href=\"../../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a>, the PWA provides free access to core analysis features. The \u003Ca href=\"../azure/index.md\">Azure App\u003C/a> adds file upload (alongside paste), save/persistence, Performance Mode, and team features.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"purpose-free-training--education\">Purpose: Free Training & Education\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#purpose-free-training--education\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Purpose: Free Training & Education”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA is a \u003Cstrong>free variation analysis training tool\u003C/strong> that provides:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Core analysis for everyone\u003C/strong> — I-Chart, Boxplot, Pareto, Capability, ANOVA\u003C/li>\n\u003Cli>\u003Cstrong>Pre-loaded case study datasets\u003C/strong> — Same datasets as documentation\u003C/li>\n\u003Cli>\u003Cstrong>Copy-paste from Excel/Sheets\u003C/strong> — No file upload, paste data directly\u003C/li>\n\u003Cli>\u003Cstrong>Zero friction\u003C/strong> — No signup, no payment, no installation required\u003C/li>\n\u003C/ol>\n\u003Cpre class=\"mermaid\" dir=\"ltr\">flowchart LR\n A[Paste Data or Load Sample] --> B[Auto-Detect Columns]\n B --> C[Confirm Mapping]\n C --> D[Analyze with Full Toolkit]\n D --> E{Need More?}\n E -->|File upload, save, teams| F[Azure App]\n\u003C/pre>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"target-users\">Target Users\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#target-users\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Target Users”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>User\u003C/th>\u003Cth>Context\u003C/th>\u003Cth>Why PWA Works\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>LSS Trainers\u003C/strong>\u003C/td>\u003Ctd>Green Belt / Black Belt courses\u003C/td>\u003Ctd>Minitab replacement with zero installation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Students\u003C/strong>\u003C/td>\u003Ctd>University statistics courses\u003C/td>\u003Ctd>Free, browser-based, no license needed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Quality Champions\u003C/strong>\u003C/td>\u003Ctd>SMEs in developing countries\u003C/td>\u003Ctd>Better tools than Excel, completely free\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Evaluators\u003C/strong>\u003C/td>\u003Ctd>Assessing VariScout capabilities\u003C/td>\u003Ctd>Try with sample data before purchasing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"pre-loaded-case-studies\">Pre-Loaded Case Studies\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#pre-loaded-case-studies\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pre-Loaded Case Studies”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA comes with datasets from the documentation case studies:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dataset\u003C/th>\u003Cth>Case Study\u003C/th>\u003Cth>Demonstrates\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Coffee\u003C/td>\u003Ctd>\u003Ca href=\"../../04-cases/coffee/index.md\">Coffee Case\u003C/a>\u003C/td>\u003Ctd>Factor comparison, MSA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Bottleneck\u003C/td>\u003Ctd>\u003Ca href=\"../../04-cases/bottleneck/index.md\">Bottleneck Case\u003C/a>\u003C/td>\u003Ctd>Process flow, drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hospital Ward\u003C/td>\u003Ctd>\u003Ca href=\"../../04-cases/hospital-ward/index.md\">Hospital Ward Case\u003C/a>\u003C/td>\u003Ctd>Aggregation trap\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Packaging\u003C/td>\u003Ctd>\u003Ca href=\"../../04-cases/packaging/index.md\">Packaging Case\u003C/a>\u003C/td>\u003Ctd>Pareto, capability\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Learning continuity\u003C/strong>: The same data appears in docs, PWA, and teaching materials.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"features-free\">Features (Free)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#features-free\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Features (Free)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All core analysis features:\u003C/p>\n\u003Cul>\n\u003Cli>I-Chart, Boxplot, Pareto, Capability Histogram, ANOVA\u003C/li>\n\u003Cli>Drill-down with breadcrumb navigation\u003C/li>\n\u003Cli>Linked filtering across charts\u003C/li>\n\u003Cli>Data input: copy-paste from Excel/Sheets + sample datasets\u003C/li>\n\u003Cli>VariScout branding on charts\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"restrictions-free-tier\">Restrictions (Free Tier)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#restrictions-free-tier\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Restrictions (Free Tier)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>PWA (Free)\u003C/th>\u003Cth>Azure App (Paid)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Paste data\u003C/td>\u003Ctd>✓\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>File upload (CSV/Excel)\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>.vrs import/export\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Save/persistence\u003C/td>\u003Ctd>Session only\u003C/td>\u003Ctd>OneDrive sync\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance Mode\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>✓\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Branding on charts\u003C/td>\u003Ctd>Always shown\u003C/td>\u003Ctd>Hidden\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Authentication\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>Microsoft SSO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Team collaboration\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>Shared projects\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"use-cases\">Use Cases\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#use-cases\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Cases”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Use Case\u003C/th>\u003Cth align=\"center\">Appropriate\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>SPC training courses\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Full Green Belt coverage\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>University education\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Free, no license needed\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Try case study data\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Pre-loaded datasets\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analyze own data (paste)\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>Copy-paste from Excel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Demo to stakeholders\u003C/td>\u003Ctd align=\"center\">✓\u003C/td>\u003Ctd>No setup required\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Production use\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✗\u003C/td>\u003Ctd>Use \u003Ca href=\"../azure/index.md\">Azure App\u003C/a>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Team collaboration\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✗\u003C/td>\u003Ctd>Use Azure App with OneDrive\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>File upload\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✗\u003C/td>\u003Ctd>Use Azure App\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Data persistence\u003C/strong>\u003C/td>\u003Ctd align=\"center\">✗\u003C/td>\u003Ctd>Session only (no save)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technical-stack\">Technical Stack\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technical-stack\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technical Stack”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Technology\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Framework\u003C/td>\u003Ctd>React 18 + TypeScript\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Build\u003C/td>\u003Ctd>Vite\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Styling\u003C/td>\u003Ctd>Tailwind CSS\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Charts\u003C/td>\u003Ctd>Visx (@variscout/charts)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>State\u003C/td>\u003Ctd>React Context\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Offline\u003C/td>\u003Ctd>Workbox (vite-plugin-pwa)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"architecture\">Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">┌─────────────────────────────────────────────────────────────────┐\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ USER'S BROWSER │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├─────────────────────────────────────────────────────────────────┤\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌─────────────────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ REACT APPLICATION │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ DataContext → Charts → Analysis │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └─────────────────────────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ ┌─────────────────────────────────────────────────────────────┐ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ │ Service Worker (Workbox, offline) │ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│ └─────────────────────────────────────────────────────────────┘ │\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└──────────────────────────────────────────────────────────────────┘\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"┌─────────────────────────────────────────────────────────────────┐│ USER'S BROWSER │├─────────────────────────────────────────────────────────────────┤│ ┌─────────────────────────────────────────────────────────────┐ ││ │ REACT APPLICATION │ ││ │ DataContext → Charts → Analysis │ ││ └─────────────────────────────────────────────────────────────┘ ││ ││ ┌─────────────────────────────────────────────────────────────┐ ││ │ Service Worker (Workbox, offline) │ ││ └─────────────────────────────────────────────────────────────┘ │└──────────────────────────────────────────────────────────────────┘\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"service-worker-workbox\">Service Worker (Workbox)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#service-worker-workbox\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Service Worker (Workbox)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Configured via \u003Ccode dir=\"auto\">vite-plugin-pwa\u003C/code> with \u003Ccode dir=\"auto\">autoUpdate\u003C/code> strategy:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>clientsClaim + skipWaiting\u003C/strong> — new service worker activates immediately\u003C/li>\n\u003Cli>\u003Cstrong>navigateFallback\u003C/strong> — \u003Ccode dir=\"auto\">/index.html\u003C/code> for SPA offline routing\u003C/li>\n\u003Cli>\u003Cstrong>globPatterns\u003C/strong> — caches \u003Ccode dir=\"auto\">**/*.{js,css,html,ico,png,svg,woff,woff2}\u003C/code>\u003C/li>\n\u003Cli>Self-hosted Caveat font (no CDN dependency — works fully offline)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"code-splitting\">Code Splitting\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#code-splitting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Code Splitting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">React.lazy\u003C/code> splits 9 route-level components (Dashboard, HomeScreen, PasteScreen, ManualEntry, WhatIfPage, SettingsPanel, DataTableModal, DataPanel, FindingsPanel). Bundle analysis available via \u003Ccode dir=\"auto\">ANALYZE=true pnpm build\u003C/code>.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"accessibility\">Accessibility\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#accessibility\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Accessibility”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ccode dir=\"auto\">aria-live\u003C/code> region for dynamic chart updates (Dashboard)\u003C/li>\n\u003Cli>Per-chart \u003Ccode dir=\"auto\">ErrorBoundary\u003C/code> — one chart failure doesn’t crash the app\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">prefers-reduced-motion\u003C/code> media query respected in CSS animations\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"development-commands\">Development Commands\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#development-commands\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Development Commands”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame is-terminal not-content\">\u003Cfigcaption class=\"header\">\u003Cspan class=\"title\">\u003C/span>\u003Cspan class=\"sr-only\">Terminal window\u003C/span>\u003C/figcaption>\u003Cpre data-language=\"bash\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Start development server\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">dev\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Build for production\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">build\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5F636F\"># Run tests\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">pnpm\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">--filter\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">@variscout/pwa\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#3B61B0\">test\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"pnpm devpnpm buildpnpm --filter @variscout/pwa test\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"role-in-development-workflow\">Role in Development Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#role-in-development-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Role in Development Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA serves as the \u003Cstrong>feature development sandbox\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>New features\u003C/strong> are prototyped in the PWA first\u003C/li>\n\u003Cli>\u003Cstrong>Shared packages\u003C/strong> are developed against PWA use cases\u003C/li>\n\u003Cli>\u003Cstrong>Azure App\u003C/strong> adopts features after PWA validation\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"upgrade-path\">Upgrade Path\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#upgrade-path\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Upgrade Path”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Ready For…\u003C/th>\u003Cth>Next Step\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>File upload, save, teams\u003C/td>\u003Ctd>\u003Ca href=\"../azure/index.md\">Azure App\u003C/a> — from €99/month (Standard) or €299/month (Team)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"storage.md\">Storage\u003C/a> - IndexedDB and session storage details\u003C/li>\n\u003Cli>\u003Ca href=\"../azure/index.md\">Azure App (Primary Product)\u003C/a> - Production platform\u003C/li>\n\u003Cli>\u003Ca href=\"../feature-parity.md\">Feature Parity\u003C/a> - Platform comparison\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007: Distribution Strategy\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-004-offline-first.md\">ADR-004: Offline-First\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 12379, + "localImagePaths": 12415, + "remoteImagePaths": 12416, + "frontmatter": 12417, + "imagePaths": 12418 + }, + [ + 12380, 12382, 12385, 12386, 12389, 12392, 12395, 12396, 12399, 12400, 12403, 12406, 12407, + 12410, 12413, 12414 + ], + { "depth": 30, "slug": 12381, "text": 12369 }, + "pwa-free-training-tool", + { "depth": 33, "slug": 12383, "text": 12384 }, + "purpose-free-training--education", + "Purpose: Free Training & Education", + { "depth": 33, "slug": 995, "text": 996 }, + { "depth": 33, "slug": 12387, "text": 12388 }, + "pre-loaded-case-studies", + "Pre-Loaded Case Studies", + { "depth": 33, "slug": 12390, "text": 12391 }, + "features-free", + "Features (Free)", + { "depth": 33, "slug": 12393, "text": 12394 }, + "restrictions-free-tier", + "Restrictions (Free Tier)", + { "depth": 33, "slug": 907, "text": 908 }, + { "depth": 33, "slug": 12397, "text": 12398 }, + "technical-stack", + "Technical Stack", + { "depth": 33, "slug": 1819, "text": 1820 }, + { "depth": 79, "slug": 12401, "text": 12402 }, + "service-worker-workbox", + "Service Worker (Workbox)", + { "depth": 79, "slug": 12404, "text": 12405 }, + "code-splitting", + "Code Splitting", + { "depth": 79, "slug": 3565, "text": 3566 }, + { "depth": 33, "slug": 12408, "text": 12409 }, + "development-commands", + "Development Commands", + { "depth": 33, "slug": 12411, "text": 12412 }, + "role-in-development-workflow", + "Role in Development Workflow", + { "depth": 33, "slug": 4477, "text": 4478 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 12369 }, + [], + "08-products/pwa/storage", + { + "id": 12419, + "data": 12421, + "body": 12426, + "filePath": 12427, + "digest": 12428, + "rendered": 12429 + }, + { + "title": 12422, + "editUrl": 16, + "head": 12423, + "template": 18, + "sidebar": 12424, + "pagefind": 16, + "draft": 20 + }, + "PWA Session Model", + [], + { "hidden": 20, "attrs": 12425 }, + {}, + "# PWA Session Model\n\nThe PWA is a free training and education tool — data persistence is intentionally not provided.\n\n---\n\n## How It Works\n\n- Data entered via paste lives in React state only\n- No IndexedDB, no localStorage (except theme preference), no `.vrs` files\n- Page refresh = data lost (by design)\n- No save/load functionality\n\n---\n\n## Why Session-Only?\n\nThe PWA is **free forever** — it exists to teach SPC concepts and let users try VariScout with their own data. Persistence features (save, load, team sharing, OneDrive sync) are part of the [Azure App](../azure/) value proposition (from €99/month).\n\nThis is documented in [ADR-007](../../07-decisions/adr-007-azure-marketplace-distribution.md).\n\n---\n\n## What IS Preserved\n\n| Data | Storage | Notes |\n| ---------------- | ------------ | ------------------------------------------------------- |\n| Theme preference | localStorage | Light/dark/system (Azure only, PWA has no theme toggle) |\n\n---\n\n## See Also\n\n- [Project Persistence](../../03-features/data/storage.md) — Full persistence model (Azure App)\n- [Offline-First Architecture](../../05-technical/architecture/offline-first.md)", + "src/content/docs/08-products/pwa/storage.md", + "aab674acab09cec3", + { "html": 12430, "metadata": 12431 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"pwa-session-model\">PWA Session Model\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#pwa-session-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “PWA Session Model”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA is a free training and education tool — data persistence is intentionally not provided.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-it-works\">How It Works\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-it-works\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How It Works”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Data entered via paste lives in React state only\u003C/li>\n\u003Cli>No IndexedDB, no localStorage (except theme preference), no \u003Ccode dir=\"auto\">.vrs\u003C/code> files\u003C/li>\n\u003Cli>Page refresh = data lost (by design)\u003C/li>\n\u003Cli>No save/load functionality\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"why-session-only\">Why Session-Only?\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#why-session-only\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Why Session-Only?”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The PWA is \u003Cstrong>free forever\u003C/strong> — it exists to teach SPC concepts and let users try VariScout with their own data. Persistence features (save, load, team sharing, OneDrive sync) are part of the \u003Ca href=\"../azure/\">Azure App\u003C/a> value proposition (from €99/month).\u003C/p>\n\u003Cp>This is documented in \u003Ca href=\"../../07-decisions/adr-007-azure-marketplace-distribution.md\">ADR-007\u003C/a>.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"what-is-preserved\">What IS Preserved\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#what-is-preserved\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What IS Preserved”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Data\u003C/th>\u003Cth>Storage\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Theme preference\u003C/td>\u003Ctd>localStorage\u003C/td>\u003Ctd>Light/dark/system (Azure only, PWA has no theme toggle)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../03-features/data/storage.md\">Project Persistence\u003C/a> — Full persistence model (Azure App)\u003C/li>\n\u003Cli>\u003Ca href=\"../../05-technical/architecture/offline-first.md\">Offline-First Architecture\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 12432, + "localImagePaths": 12442, + "remoteImagePaths": 12443, + "frontmatter": 12444, + "imagePaths": 12445 + }, + [12433, 12435, 12436, 12439, 12441], + { "depth": 30, "slug": 12434, "text": 12422 }, + "pwa-session-model", + { "depth": 33, "slug": 1173, "text": 1174 }, + { "depth": 33, "slug": 12437, "text": 12438 }, + "why-session-only", + "Why Session-Only?", + { "depth": 33, "slug": 11981, "text": 12440 }, + "What IS Preserved", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 12422 }, + [], + "08-products/website/content-architecture", + { + "id": 12446, + "data": 12448, + "body": 12453, + "filePath": 12454, + "digest": 12455, + "rendered": 12456 + }, + { + "title": 12449, + "editUrl": 16, + "head": 12450, + "template": 18, + "sidebar": 12451, + "pagefind": 16, + "draft": 20 + }, + "Website Content Architecture", + [], + { "hidden": 20, "attrs": 12452 }, + {}, + "# Website Content Architecture\n\nTechnical specification for how content is organized, cross-linked, and rendered on the VariScout website.\n\n---\n\n## Three Surfaces\n\n```\nACQUISITION REFERENCE PROOF\n(Problem-first) (Method-first) (Story-first)\n\nUse Case Page ---------> Tool Page Case Study\n\"Your supplier \"How Capability \"The supplier said\n Cpk is wrong\" analysis works\" Cpk = 1.72. We\n | | found 0.98.\"\n | (i) tooltips |\n | | |\n | Glossary Term |\n | \"Cpk = min(CPU,CPL)\" |\n | ^ |\n | | |\n +--------> PWA \u003C---------+--------------------+\n \"Try it\" \"Learn more\" \"Try it\"\n (from HelpTooltip)\n```\n\n---\n\n## Content Type Inventory\n\n| Content Type | Data File | Count | Template | URL Pattern |\n| ------------ | ------------------ | ----- | ------------------------------- | ------------------------------------ |\n| Use Cases | `useCaseData.ts` | 13 | `[lang]/use-cases/[slug].astro` | `/en/use-cases/supplier-performance` |\n| Tools | `toolsData.ts` | 7 | `[lang]/tools/[tool].astro` | `/en/tools/i-chart` |\n| Learn Topics | `learnData.ts` | 11 | `[lang]/learn/[topic].astro` | `/en/learn/two-voices` |\n| Glossary | `glossaryData.ts` | 35+ | `[lang]/glossary/[term].astro` | `/en/glossary/cpk` |\n| Case Studies | inline in template | 10 | `[lang]/cases/[slug].astro` | `/en/cases/bottleneck` |\n| Products | inline in template | 3+ | `[lang]/product/[slug].astro` | `/en/product/azure` |\n\nAll content types multiply by 5 languages (en, de, es, fr, pt).\n\n---\n\n## Cross-Linking Graph\n\n| From \\ To | Tools | Learn | Glossary | Cases | Use Cases |\n| ------------- | ------------ | ------------- | ----------------- | ------------------------ | --------- |\n| **Tools** | nextTools | relatedLearn | — | relatedCases | — |\n| **Learn** | relatedTools | relatedTopics | — | relatedCases | — |\n| **Glossary** | relatedTools | relatedLearn | relatedTerms | — | — |\n| **Cases** | tools | — | — | relatedCases (WhatsNext) | — |\n| **Use Cases** | relatedTools | relatedLearn | (inline tooltips) | relatedCases | — |\n\n---\n\n## Data File Pattern\n\nAll data files follow the same conventions:\n\n```typescript\n// 1. Export interface\nexport interface ContentType { ... }\n\n// 2. Export const array\nexport const ITEMS: ContentType[] = [ ... ];\n\n// 3. Export helper functions\nexport function getBySlug(slug: string): ContentType | undefined;\nexport function getAllSlugs(): string[];\n```\n\n### useCaseData.ts (NEW)\n\n```typescript\nexport interface UseCase {\n slug: string;\n title: string;\n subtitle: string;\n industry: string;\n role: string;\n problem: {\n headline: string;\n description: string;\n misleadingMetric: string;\n reality: string;\n };\n demo: {\n sampleKey: string;\n chartType: 'i-chart' | 'boxplot' | 'capability' | 'pareto' | 'performance';\n caption: string;\n };\n journey: Array\u003C{\n step: number;\n tool: string;\n title: string;\n description: string;\n insight: string;\n }>;\n ahaQuote: string;\n beforeAfter: Array\u003C{ before: string; after: string }>;\n relatedCases: string[];\n relatedTools: string[];\n relatedLearn: string[];\n platformFit: Array\u003C{\n stage: string;\n product: 'pwa' | 'azure';\n reason: string;\n }>;\n keywords: string[];\n metaDescription: string;\n}\n```\n\n### toolsData.ts (EXTENDED)\n\nAdd field:\n\n```typescript\nrelatedCases?: string[]; // Case study slugs for \"See It in Action\"\n```\n\n### learnData.ts (EXTENDED)\n\nAdd field:\n\n```typescript\nrelatedCases?: string[]; // Case study slugs for \"See It in Practice\"\n```\n\n---\n\n## Use Case Template Anatomy\n\nThe `[lang]/use-cases/[slug].astro` template renders 6 sections:\n\n### Section 1: Hero\n\n- Industry badge (Manufacturing, Healthcare, etc.)\n- Role context (\"Supplier Quality Engineer\")\n- SEO headline (problem-first, keyword-targeted)\n- Subtitle (2 sentences of context)\n\n### Section 2: The Problem\n\n- Misleading metric callout (\"Your dashboard says...\")\n- Reality statement (\"But actually...\")\n- 2-3 sentence problem description\n\n### Section 3: Interactive Demo\n\n- React island chart with pre-loaded sample data\n- Caption explaining what the chart shows\n- Same chart components used in the real product\n\n### Section 4: The Journey\n\n- Numbered steps (1-4) with tool badges\n- Each step: tool name, title, description, insight\n- \"Aha\" quote at the end\n\n### Section 5: Before / After\n\n- Two-column comparison table\n- Concrete transformations (e.g., \"Gut-feeling priorities\" -> \"Data-driven Pareto ranking\")\n\n### Section 6: What's Next\n\n- Related case studies (\"See the proof\")\n- Related tools (linked cards)\n- Platform fit table (PWA vs Azure)\n- Primary CTA: \"Try with your data\"\n\n---\n\n## Sample Data Requirements\n\n| Use Case | Sample Key | Status | Notes |\n| -------------------- | --------------- | ------ | --------------------- |\n| Assembly Bottleneck | `bottleneck` | Exists | Perfect match |\n| University SPC | `coffee` | Exists | Good fit for training |\n| Supplier PPAP | `mango-export` | Exists | Reuse for capability |\n| Supplier Performance | `journey` | Exists | Multiple factors |\n| COPQ Drill-Down | `packaging` | Exists | Defect types + shifts |\n| Customer Complaint | `cookie-weight` | Exists | Before/after pattern |\n| Patient Wait Time | `hospital-ward` | Exists | Phase 2 |\n| Call Center | `call-wait` | Exists | Phase 2 |\n| On-Time Delivery | `delivery` | Exists | Phase 2 |\n| Batch Consistency | `packaging` | Exists | Phase 3, reuse |\n| Consultant Delivery | `journey` | Exists | Phase 3, reuse |\n| Pharma OOS | — | Needed | Phase 3 |\n| Lead Time Variation | — | Needed | Phase 3 |\n\n---\n\n## Navigation Structure\n\n### Header\n\n```\n[Home] [Journey] [Methods v] [Solutions v] [Product v] [Try Now]\n\nMethods dropdown:\n+-- TOOLS (heading)\n| +-- I-Chart Patterns over time\n| +-- Boxplot Compare factors\n| +-- Pareto Prioritize problems\n| +-- Capability Meet specs\n+-- FRAMEWORKS (heading)\n| +-- Two Voices Control vs Spec\n| +-- Four Lenses Watson framework\n| +-- EDA Philosophy Visual exploration\n+-- All Methods\n\nSolutions dropdown:\n+-- Assembly Bottleneck Manufacturing\n+-- Supplier Performance Supply Chain\n+-- Supplier PPAP Automotive\n+-- University SPC Education\n+-- COPQ Drill-Down Cross-industry\n+-- Customer Complaints Cross-industry\n+-- All Use Cases\n\nProduct dropdown:\n+-- Web App Free training tool\n+-- Azure App Full power for teams\n+-- Pricing\n+-- Enterprise & IT Security & compliance\n```\n\nNote: Pricing is inside the Product dropdown (no standalone nav link). Getting Started is removed from navigation but remains in footer and linked from enterprise/pricing pages.\n\n### Footer\n\nProduct section includes Getting Started (translated via `nav.gettingStarted`). Use Cases section lists top use cases with \"All Use Cases\" link.\n\n---\n\n## How to Add a New Use Case\n\n1. Add entry to `apps/website/src/data/useCaseData.ts`\n2. Ensure sample dataset exists in `@variscout/data` (or reuse existing)\n3. Add any new i18n strings to `src/i18n/ui.ts` if needed for nav\n4. Update footer links if adding to a new industry grouping\n5. Run `pnpm --filter @variscout/website build` to verify\n\nThe template auto-generates pages for all languages. No template changes needed.\n\n---\n\n## i18n Considerations\n\n- Use case data is English-only (no translation of problem descriptions, journey steps, etc.)\n- Navigation labels (Solutions, industry names) need translation in `ui.ts`\n- URL slugs remain English across all languages (`/de/use-cases/supplier-performance`)\n- Chart content comes from `@variscout/data` which is language-neutral (numbers, chart labels)\n\n---\n\n## See Also\n\n- [ADR-008: Website Content Architecture](../../07-decisions/adr-008-website-content-architecture.md)\n- [Design Philosophy](design-philosophy.md)\n- [Website Overview](index.md)\n- [Use Cases Documentation](../../02-journeys/use-cases/index.md)", + "src/content/docs/08-products/website/content-architecture.md", + "960ea88ed7b147af", + { "html": 12457, "metadata": 12458 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"website-content-architecture\">Website Content Architecture\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#website-content-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Content Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Technical specification for how content is organized, cross-linked, and rendered on the VariScout website.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"three-surfaces\">Three Surfaces\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#three-surfaces\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Three Surfaces”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">ACQUISITION REFERENCE PROOF\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">(Problem-first) (Method-first) (Story-first)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Use Case Page ---------> Tool Page Case Study\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"Your supplier \"How Capability \"The supplier said\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Cpk is wrong\" analysis works\" Cpk = 1.72. We\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| | found 0.98.\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| (i) tooltips |\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| | |\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| Glossary Term |\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| \"Cpk = min(CPU,CPL)\" |\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| ^ |\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| | |\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+--------> PWA <---------+--------------------+\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">\"Try it\" \"Learn more\" \"Try it\"\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">(from HelpTooltip)\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"ACQUISITION REFERENCE PROOF(Problem-first) (Method-first) (Story-first)Use Case Page ---------> Tool Page Case Study"Your supplier "How Capability "The supplier said Cpk is wrong" analysis works" Cpk = 1.72. We | | found 0.98." | (i) tooltips | | | | | Glossary Term | | "Cpk = min(CPU,CPL)" | | ^ | | | | +--------> PWA \u003C---------+--------------------+ "Try it" "Learn more" "Try it" (from HelpTooltip)\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"content-type-inventory\">Content Type Inventory\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#content-type-inventory\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Content Type Inventory”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Content Type\u003C/th>\u003Cth>Data File\u003C/th>\u003Cth>Count\u003C/th>\u003Cth>Template\u003C/th>\u003Cth>URL Pattern\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Use Cases\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useCaseData.ts\u003C/code>\u003C/td>\u003Ctd>13\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/use-cases/[slug].astro\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/en/use-cases/supplier-performance\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Tools\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">toolsData.ts\u003C/code>\u003C/td>\u003Ctd>7\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/tools/[tool].astro\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/en/tools/i-chart\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Learn Topics\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">learnData.ts\u003C/code>\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/learn/[topic].astro\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/en/learn/two-voices\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Glossary\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">glossaryData.ts\u003C/code>\u003C/td>\u003Ctd>35+\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/glossary/[term].astro\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/en/glossary/cpk\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Case Studies\u003C/td>\u003Ctd>inline in template\u003C/td>\u003Ctd>10\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/cases/[slug].astro\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/en/cases/bottleneck\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Products\u003C/td>\u003Ctd>inline in template\u003C/td>\u003Ctd>3+\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/product/[slug].astro\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/en/product/azure\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>All content types multiply by 5 languages (en, de, es, fr, pt).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-linking-graph\">Cross-Linking Graph\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-linking-graph\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Linking Graph”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>From \\ To\u003C/th>\u003Cth>Tools\u003C/th>\u003Cth>Learn\u003C/th>\u003Cth>Glossary\u003C/th>\u003Cth>Cases\u003C/th>\u003Cth>Use Cases\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Tools\u003C/strong>\u003C/td>\u003Ctd>nextTools\u003C/td>\u003Ctd>relatedLearn\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>relatedCases\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Learn\u003C/strong>\u003C/td>\u003Ctd>relatedTools\u003C/td>\u003Ctd>relatedTopics\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>relatedCases\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Glossary\u003C/strong>\u003C/td>\u003Ctd>relatedTools\u003C/td>\u003Ctd>relatedLearn\u003C/td>\u003Ctd>relatedTerms\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Cases\u003C/strong>\u003C/td>\u003Ctd>tools\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>relatedCases (WhatsNext)\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Use Cases\u003C/strong>\u003C/td>\u003Ctd>relatedTools\u003C/td>\u003Ctd>relatedLearn\u003C/td>\u003Ctd>(inline tooltips)\u003C/td>\u003Ctd>relatedCases\u003C/td>\u003Ctd>—\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-file-pattern\">Data File Pattern\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-file-pattern\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data File Pattern”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All data files follow the same conventions:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 1. Export interface\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ContentType { \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 2. Export const array\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export const \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">ITEMS\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ContentType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[]\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\"> =\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> [ \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">...\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> ];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// 3. Export helper functions\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getBySlug\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">(\u003C/span>\u003Cspan style=\"--0:#D7DBE0;--1:#403F53\">slug\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">)\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">ContentType\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">undefined\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">function\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#82AAFF;--1:#3B61B0\">getAllSlugs\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">()\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"// 1. Export interfaceexport interface ContentType { ... }// 2. Export const arrayexport const ITEMS: ContentType[] = [ ... ];// 3. Export helper functionsexport function getBySlug(slug: string): ContentType | undefined;export function getAllSlugs(): string[];\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"usecasedatats-new\">useCaseData.ts (NEW)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#usecasedatats-new\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “useCaseData.ts (NEW)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">export\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">interface\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> UseCase {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">slug\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">title\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">subtitle\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">industry\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">role\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">problem\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">headline\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">description\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">misleadingMetric\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">reality\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">demo\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> {\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">sampleKey\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">chartType\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">i-chart\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">boxplot\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">capability\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pareto\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">performance\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">caption\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">};\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">journey\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Array\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">step\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">number\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">tool\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">title\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">description\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">insight\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">ahaQuote\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">beforeAfter\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Array\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><{ before\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">; after\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> }>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">relatedCases\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">relatedTools\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">relatedLearn\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">platformFit\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#FFCB8B;--1:#111111\">Array\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"><{\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">stage\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">product\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">pwa\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">|\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#ECC48D;--1:#984E4D\">azure\u003C/span>\u003Cspan style=\"--0:#D9F5DD;--1:#111111\">'\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">reason\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}>;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">keywords\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">[];\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">metaDescription\u003C/span>\u003Cspan style=\"--0:#7FDBCA;--1:#096E72\">:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> \u003C/span>\u003Cspan style=\"--0:#C5E478;--1:#3B61B0\">string\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">;\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">}\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"export interface UseCase { slug: string; title: string; subtitle: string; industry: string; role: string; problem: { headline: string; description: string; misleadingMetric: string; reality: string; }; demo: { sampleKey: string; chartType: 'i-chart' | 'boxplot' | 'capability' | 'pareto' | 'performance'; caption: string; }; journey: Array\u003C{ step: number; tool: string; title: string; description: string; insight: string; }>; ahaQuote: string; beforeAfter: Array\u003C{ before: string; after: string }>; relatedCases: string[]; relatedTools: string[]; relatedLearn: string[]; platformFit: Array\u003C{ stage: string; product: 'pwa' | 'azure'; reason: string; }>; keywords: string[]; metaDescription: string;}\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"toolsdatats-extended\">toolsData.ts (EXTENDED)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#toolsdatats-extended\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “toolsData.ts (EXTENDED)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Add field:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">relatedCases\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> string[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Case study slugs for \"See It in Action\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"relatedCases?: string[]; // Case study slugs for "See It in Action"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"learndatats-extended\">learnData.ts (EXTENDED)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#learndatats-extended\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “learnData.ts (EXTENDED)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Add field:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"typescript\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\">relatedCases\u003C/span>\u003Cspan style=\"--0:#C792EA;--1:#8844AE\">?:\u003C/span>\u003Cspan style=\"--0:#D6DEEB;--1:#403F53\"> string[]; \u003C/span>\u003Cspan style=\"--0:#919F9F;--1:#5D6376\">// Case study slugs for \"See It in Practice\"\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"relatedCases?: string[]; // Case study slugs for "See It in Practice"\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"use-case-template-anatomy\">Use Case Template Anatomy\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#use-case-template-anatomy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Use Case Template Anatomy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">[lang]/use-cases/[slug].astro\u003C/code> template renders 6 sections:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"section-1-hero\">Section 1: Hero\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#section-1-hero\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Section 1: Hero”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Industry badge (Manufacturing, Healthcare, etc.)\u003C/li>\n\u003Cli>Role context (“Supplier Quality Engineer”)\u003C/li>\n\u003Cli>SEO headline (problem-first, keyword-targeted)\u003C/li>\n\u003Cli>Subtitle (2 sentences of context)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"section-2-the-problem\">Section 2: The Problem\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#section-2-the-problem\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Section 2: The Problem”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Misleading metric callout (“Your dashboard says…”)\u003C/li>\n\u003Cli>Reality statement (“But actually…”)\u003C/li>\n\u003Cli>2-3 sentence problem description\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"section-3-interactive-demo\">Section 3: Interactive Demo\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#section-3-interactive-demo\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Section 3: Interactive Demo”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>React island chart with pre-loaded sample data\u003C/li>\n\u003Cli>Caption explaining what the chart shows\u003C/li>\n\u003Cli>Same chart components used in the real product\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"section-4-the-journey\">Section 4: The Journey\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#section-4-the-journey\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Section 4: The Journey”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Numbered steps (1-4) with tool badges\u003C/li>\n\u003Cli>Each step: tool name, title, description, insight\u003C/li>\n\u003Cli>“Aha” quote at the end\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"section-5-before--after\">Section 5: Before / After\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#section-5-before--after\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Section 5: Before / After”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Two-column comparison table\u003C/li>\n\u003Cli>Concrete transformations (e.g., “Gut-feeling priorities” -> “Data-driven Pareto ranking”)\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"section-6-whats-next\">Section 6: What’s Next\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#section-6-whats-next\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Section 6: What’s Next”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Related case studies (“See the proof”)\u003C/li>\n\u003Cli>Related tools (linked cards)\u003C/li>\n\u003Cli>Platform fit table (PWA vs Azure)\u003C/li>\n\u003Cli>Primary CTA: “Try with your data”\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sample-data-requirements\">Sample Data Requirements\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sample-data-requirements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sample Data Requirements”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Use Case\u003C/th>\u003Cth>Sample Key\u003C/th>\u003Cth>Status\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Assembly Bottleneck\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">bottleneck\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Perfect match\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>University SPC\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">coffee\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Good fit for training\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Supplier PPAP\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">mango-export\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Reuse for capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Supplier Performance\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">journey\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Multiple factors\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>COPQ Drill-Down\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packaging\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Defect types + shifts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Customer Complaint\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">cookie-weight\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Before/after pattern\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Patient Wait Time\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">hospital-ward\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Phase 2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Call Center\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">call-wait\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Phase 2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>On-Time Delivery\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">delivery\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Phase 2\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Batch Consistency\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">packaging\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Phase 3, reuse\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Consultant Delivery\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">journey\u003C/code>\u003C/td>\u003Ctd>Exists\u003C/td>\u003Ctd>Phase 3, reuse\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pharma OOS\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Needed\u003C/td>\u003Ctd>Phase 3\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Lead Time Variation\u003C/td>\u003Ctd>—\u003C/td>\u003Ctd>Needed\u003C/td>\u003Ctd>Phase 3\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"navigation-structure\">Navigation Structure\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#navigation-structure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Navigation Structure”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"header\">Header\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#header\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Header”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">[Home] [Journey] [Methods v] [Solutions v] [Product v] [Try Now]\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Methods dropdown:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- TOOLS (heading)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| +-- I-Chart Patterns over time\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| +-- Boxplot Compare factors\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| +-- Pareto Prioritize problems\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| +-- Capability Meet specs\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- FRAMEWORKS (heading)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| +-- Two Voices Control vs Spec\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| +-- Four Lenses Watson framework\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">| +-- EDA Philosophy Visual exploration\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- All Methods\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Solutions dropdown:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- Assembly Bottleneck Manufacturing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- Supplier Performance Supply Chain\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- Supplier PPAP Automotive\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- University SPC Education\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- COPQ Drill-Down Cross-industry\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- Customer Complaints Cross-industry\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- All Use Cases\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\n\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Product dropdown:\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- Web App Free training tool\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- Azure App Full power for teams\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- Pricing\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">+-- Enterprise & IT Security & compliance\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"[Home] [Journey] [Methods v] [Solutions v] [Product v] [Try Now]Methods dropdown:+-- TOOLS (heading)| +-- I-Chart Patterns over time| +-- Boxplot Compare factors| +-- Pareto Prioritize problems| +-- Capability Meet specs+-- FRAMEWORKS (heading)| +-- Two Voices Control vs Spec| +-- Four Lenses Watson framework| +-- EDA Philosophy Visual exploration+-- All MethodsSolutions dropdown:+-- Assembly Bottleneck Manufacturing+-- Supplier Performance Supply Chain+-- Supplier PPAP Automotive+-- University SPC Education+-- COPQ Drill-Down Cross-industry+-- Customer Complaints Cross-industry+-- All Use CasesProduct dropdown:+-- Web App Free training tool+-- Azure App Full power for teams+-- Pricing+-- Enterprise & IT Security & compliance\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Note: Pricing is inside the Product dropdown (no standalone nav link). Getting Started is removed from navigation but remains in footer and linked from enterprise/pricing pages.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"footer\">Footer\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#footer\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Footer”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Product section includes Getting Started (translated via \u003Ccode dir=\"auto\">nav.gettingStarted\u003C/code>). Use Cases section lists top use cases with “All Use Cases” link.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-to-add-a-new-use-case\">How to Add a New Use Case\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-to-add-a-new-use-case\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How to Add a New Use Case”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Add entry to \u003Ccode dir=\"auto\">apps/website/src/data/useCaseData.ts\u003C/code>\u003C/li>\n\u003Cli>Ensure sample dataset exists in \u003Ccode dir=\"auto\">@variscout/data\u003C/code> (or reuse existing)\u003C/li>\n\u003Cli>Add any new i18n strings to \u003Ccode dir=\"auto\">src/i18n/ui.ts\u003C/code> if needed for nav\u003C/li>\n\u003Cli>Update footer links if adding to a new industry grouping\u003C/li>\n\u003Cli>Run \u003Ccode dir=\"auto\">pnpm --filter @variscout/website build\u003C/code> to verify\u003C/li>\n\u003C/ol>\n\u003Cp>The template auto-generates pages for all languages. No template changes needed.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"i18n-considerations\">i18n Considerations\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#i18n-considerations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “i18n Considerations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Use case data is English-only (no translation of problem descriptions, journey steps, etc.)\u003C/li>\n\u003Cli>Navigation labels (Solutions, industry names) need translation in \u003Ccode dir=\"auto\">ui.ts\u003C/code>\u003C/li>\n\u003Cli>URL slugs remain English across all languages (\u003Ccode dir=\"auto\">/de/use-cases/supplier-performance\u003C/code>)\u003C/li>\n\u003Cli>Chart content comes from \u003Ccode dir=\"auto\">@variscout/data\u003C/code> which is language-neutral (numbers, chart labels)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-008-website-content-architecture.md\">ADR-008: Website Content Architecture\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"design-philosophy.md\">Design Philosophy\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"index.md\">Website Overview\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../02-journeys/use-cases/index.md\">Use Cases Documentation\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 12459, + "localImagePaths": 12521, + "remoteImagePaths": 12522, + "frontmatter": 12523, + "imagePaths": 12524 + }, + [ + 12460, 12462, 12463, 12466, 12469, 12472, 12475, 12478, 12481, 12484, 12487, 12490, 12493, + 12496, 12499, 12502, 12505, 12508, 12511, 12514, 12517, 12520 + ], + { "depth": 30, "slug": 12461, "text": 12449 }, + "website-content-architecture", + { "depth": 33, "slug": 2435, "text": 2436 }, + { "depth": 33, "slug": 12464, "text": 12465 }, + "content-type-inventory", + "Content Type Inventory", + { "depth": 33, "slug": 12467, "text": 12468 }, + "cross-linking-graph", + "Cross-Linking Graph", + { "depth": 33, "slug": 12470, "text": 12471 }, + "data-file-pattern", + "Data File Pattern", + { "depth": 79, "slug": 12473, "text": 12474 }, + "usecasedatats-new", + "useCaseData.ts (NEW)", + { "depth": 79, "slug": 12476, "text": 12477 }, + "toolsdatats-extended", + "toolsData.ts (EXTENDED)", + { "depth": 79, "slug": 12479, "text": 12480 }, + "learndatats-extended", + "learnData.ts (EXTENDED)", + { "depth": 33, "slug": 12482, "text": 12483 }, + "use-case-template-anatomy", + "Use Case Template Anatomy", + { "depth": 79, "slug": 12485, "text": 12486 }, + "section-1-hero", + "Section 1: Hero", + { "depth": 79, "slug": 12488, "text": 12489 }, + "section-2-the-problem", + "Section 2: The Problem", + { "depth": 79, "slug": 12491, "text": 12492 }, + "section-3-interactive-demo", + "Section 3: Interactive Demo", + { "depth": 79, "slug": 12494, "text": 12495 }, + "section-4-the-journey", + "Section 4: The Journey", + { "depth": 79, "slug": 12497, "text": 12498 }, + "section-5-before--after", + "Section 5: Before / After", + { "depth": 79, "slug": 12500, "text": 12501 }, + "section-6-whats-next", + "Section 6: What’s Next", + { "depth": 33, "slug": 12503, "text": 12504 }, + "sample-data-requirements", + "Sample Data Requirements", + { "depth": 33, "slug": 12506, "text": 12507 }, + "navigation-structure", + "Navigation Structure", + { "depth": 79, "slug": 12509, "text": 12510 }, + "header", + "Header", + { "depth": 79, "slug": 12512, "text": 12513 }, + "footer", + "Footer", + { "depth": 33, "slug": 12515, "text": 12516 }, + "how-to-add-a-new-use-case", + "How to Add a New Use Case", + { "depth": 33, "slug": 12518, "text": 12519 }, + "i18n-considerations", + "i18n Considerations", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 12449 }, + [], + "08-products/website/design-philosophy", + { + "id": 12525, + "data": 12527, + "body": 12532, + "filePath": 12533, + "digest": 12534, + "rendered": 12535 + }, + { + "title": 12528, + "editUrl": 16, + "head": 12529, + "template": 18, + "sidebar": 12530, + "pagefind": 16, + "draft": 20 + }, + "Website Design Philosophy", + [], + { "hidden": 20, "attrs": 12531 }, + {}, + "# Website Design Philosophy\n\n> **\"Guided Problem Playground\"** — Every page starts with a professional's real problem, proves the solution with a live interactive chart, and offers contextual depth exactly where you need it.\n\n---\n\n## The Philosophy in One Sentence\n\nShowcase (problem-first, Stripe model) + Playground (live charts, Desmos model) + Contextual Learning (Minitab-style progressive disclosure).\n\n---\n\n## Three Pillars\n\n### 1. Problem-First (from Showcase / Stripe)\n\nEvery use case page opens with a headline that names the professional's pain:\n\n> \"Your average wait time is fine. Your patients' experience isn't.\"\n\nThe visitor immediately sees themselves in the problem — before VariScout is even mentioned. The \"job to be done\" drives the page structure, not the feature list.\n\n**Anti-pattern:** Generic feature tours without problem context. \"Our I-Chart has auto-calculated control limits\" means nothing without \"Your supplier's data shows a shift at batch 47 — here's what that means.\"\n\n### 2. Live Proof (from Playground / Desmos)\n\nThe demo on every page is NOT a video, NOT a screenshot — it's the actual chart with real data.\n\n- Pre-loaded sample dataset illustrates the exact problem described in the headline\n- The visitor can interact: hover for values, see tooltips, understand the data\n- One click to \"Try with your own data\" → opens PWA with the same view\n\n**Anti-pattern:** Screenshots of charts, embed videos, or static illustrations where a live interactive chart could be shown.\n\n### 3. Contextual Depth (from Minitab Assistant + Progressive Disclosure)\n\nLearning is NOT a separate section — it's woven into the experience:\n\n- When you see a Cpk value, there's a (i) HelpTooltip that explains what Cpk means\n- \"How to read this chart\" is a collapsible section ON the chart, not a separate page\n- \"Why this matters\" callouts explain the methodology inline\n- The existing Learn pages, Glossary, and Tool pages are the **deep reference layer** — linked from contextual tooltips, not presented as a separate navigation path\n\n**Anti-pattern:** A separate \"Academy\" or \"Learn\" section that competes with reference pages for attention. Learning should happen IN context, not BEFORE context.\n\n---\n\n## The Visitor Experience\n\n### A Supplier Quality Engineer searches \"how to verify supplier Cpk data\"\n\n1. **Lands on** `/use-cases/supplier-ppap` — headline: \"Verify supplier capability in minutes, not hours.\"\n2. **Sees the problem** described in 2 sentences (they recognize their situation)\n3. **Below:** A live interactive chart showing an I-Chart of supplier data — one point outside limits is highlighted\n4. **Scrolls to the journey:** Step 1 I-Chart → Step 2 Capability → Step 3 Performance Mode. Each step has a mini-chart demo.\n5. **On the Capability chart**, Cpk = 0.98 is shown. A (i) HelpTooltip explains: \"Cpk measures how centered your process is within spec limits. Below 1.0 means the process is producing out-of-spec parts.\"\n6. **\"Learn more\"** opens the glossary Cpk page for the full formula and thresholds — but the visitor already understood the key insight WITHOUT leaving the page\n7. **Before/After table** shows the transformation\n8. **CTA:** \"Try with your PPAP data\" → opens PWA, OR \"See the full analysis\" → links to relevant case study\n9. **Platform fit table:** \"For full PPAP review across 25+ characteristics → Azure App\"\n\n---\n\n## Dual-Audience Design\n\nEvery reference page serves two audiences simultaneously:\n\n| Audience | Arrives From | Needs | Content Strategy |\n| ------------- | ------------------------ | ------------------------------------- | --------------------------------------- |\n| Cold searcher | Google search | Context, explanation, trust | Problem framing, live demo, methodology |\n| Warm app user | HelpTooltip \"Learn more\" | Focused reference, formula, threshold | Clean definition, interpretation table |\n\nThe same page works for both because:\n\n- **Top section** is definitional (serves the warm user immediately)\n- **Middle section** is explanatory (serves the cold searcher)\n- **Bottom section** connects to related content (serves both)\n\n---\n\n## How This Differs from Alternatives\n\n### vs Pure Showcase (Stripe)\n\n| Pure Showcase | Guided Problem Playground |\n| -------------------------- | ---------------------------- |\n| Screenshot or illustration | Live interactive chart |\n| \"See features\" CTA | \"Try with your data\" CTA |\n| Learning in docs section | Learning inline via tooltips |\n| Separate product pages | Product IS the demo |\n\n### vs Pure Playground (Desmos)\n\n| Pure Playground | Guided Problem Playground |\n| ---------------------------- | ----------------------------------------- |\n| Tool IS the homepage | Problem IS the homepage, tool proves it |\n| No narrative context | Story frames the data |\n| Learning through exploration | Guided discovery with contextual hints |\n| Weak SEO (no text content) | Strong SEO (problem narrative + keywords) |\n\n### vs Academy (Moz/Ahrefs)\n\n| Academy | Guided Problem Playground |\n| ----------------------------- | ------------------------------------------ |\n| Read → understand → try | See problem → see proof → dig deeper |\n| Education drives discovery | Problem drives discovery |\n| Blog posts as primary content | Use case pages as primary content |\n| \"Learn about Cpk\" | \"This supplier's Cpk is 0.98 — here's why\" |\n\n---\n\n## Minitab Comparison\n\nMinitab uses three separate layers:\n\n| Layer | Minitab | VariScout Equivalent |\n| ------------------- | ------------------------------- | ------------------------------ |\n| In-App Assistant | Desktop decision tree + dialogs | HelpTooltip (i) + useGlossary |\n| support.minitab.com | 4-page reference per topic | Learn pages + Glossary pages |\n| minitab.com | Marketing site | Use case pages + Product pages |\n\n**Key differences:**\n\n- VariScout puts all three on one domain (better for SEO)\n- VariScout Learn/Glossary pages have live interactive charts (Minitab has static images)\n- VariScout's help is public and free (Minitab's is for paid users)\n\n---\n\n## Content Principles\n\n1. **Every page starts with a problem, not a feature** — The visitor should recognize their situation before they see VariScout\n2. **Every claim has a live interactive proof** — If you can show a chart instead of describing one, show the chart\n3. **Learning is contextual, not structural** — Inline tooltips and collapsible sections, not a separate Academy\n4. **Reference pages are clean and focused** — No marketing noise on Learn/Glossary pages; they serve dual audiences\n5. **Cross-links form a web, not a funnel** — Any page can lead to any other relevant page; don't force linear paths\n\n---\n\n## Anti-Patterns\n\n| Don't | Do Instead |\n| ------------------------------------------- | ------------------------------------- |\n| Feature tours without problem context | Name the professional's pain first |\n| Screenshots when a live chart can be shown | Use React island with sample data |\n| Separate \"Academy\" competing with reference | Embed learning inline with tooltips |\n| Marketing noise on reference pages | Keep Learn/Glossary clean and focused |\n| Force linear funnels | Let cross-links form a natural web |\n| Generic \"SPC software\" messaging | Industry-specific problem framing |\n\n---\n\n## See Also\n\n- [ADR-008: Website Content Architecture](../../07-decisions/adr-008-website-content-architecture.md)\n- [Content Architecture](content-architecture.md)\n- [Website Overview](index.md)", + "src/content/docs/08-products/website/design-philosophy.md", + "4d15ef081d581e5f", + { "html": 12536, "metadata": 12537 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"website-design-philosophy\">Website Design Philosophy\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#website-design-philosophy\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Website Design Philosophy”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>“Guided Problem Playground”\u003C/strong> — Every page starts with a professional’s real problem, proves the solution with a live interactive chart, and offers contextual depth exactly where you need it.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-philosophy-in-one-sentence\">The Philosophy in One Sentence\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-philosophy-in-one-sentence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Philosophy in One Sentence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Showcase (problem-first, Stripe model) + Playground (live charts, Desmos model) + Contextual Learning (Minitab-style progressive disclosure).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"three-pillars\">Three Pillars\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#three-pillars\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Three Pillars”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-problem-first-from-showcase--stripe\">1. Problem-First (from Showcase / Stripe)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-problem-first-from-showcase--stripe\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Problem-First (from Showcase / Stripe)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every use case page opens with a headline that names the professional’s pain:\u003C/p>\n\u003Cblockquote>\n\u003Cp>“Your average wait time is fine. Your patients’ experience isn’t.”\u003C/p>\n\u003C/blockquote>\n\u003Cp>The visitor immediately sees themselves in the problem — before VariScout is even mentioned. The “job to be done” drives the page structure, not the feature list.\u003C/p>\n\u003Cp>\u003Cstrong>Anti-pattern:\u003C/strong> Generic feature tours without problem context. “Our I-Chart has auto-calculated control limits” means nothing without “Your supplier’s data shows a shift at batch 47 — here’s what that means.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-live-proof-from-playground--desmos\">2. Live Proof (from Playground / Desmos)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-live-proof-from-playground--desmos\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Live Proof (from Playground / Desmos)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The demo on every page is NOT a video, NOT a screenshot — it’s the actual chart with real data.\u003C/p>\n\u003Cul>\n\u003Cli>Pre-loaded sample dataset illustrates the exact problem described in the headline\u003C/li>\n\u003Cli>The visitor can interact: hover for values, see tooltips, understand the data\u003C/li>\n\u003Cli>One click to “Try with your own data” → opens PWA with the same view\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Anti-pattern:\u003C/strong> Screenshots of charts, embed videos, or static illustrations where a live interactive chart could be shown.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-contextual-depth-from-minitab-assistant--progressive-disclosure\">3. Contextual Depth (from Minitab Assistant + Progressive Disclosure)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-contextual-depth-from-minitab-assistant--progressive-disclosure\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Contextual Depth (from Minitab Assistant + Progressive Disclosure)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Learning is NOT a separate section — it’s woven into the experience:\u003C/p>\n\u003Cul>\n\u003Cli>When you see a Cpk value, there’s a (i) HelpTooltip that explains what Cpk means\u003C/li>\n\u003Cli>“How to read this chart” is a collapsible section ON the chart, not a separate page\u003C/li>\n\u003Cli>“Why this matters” callouts explain the methodology inline\u003C/li>\n\u003Cli>The existing Learn pages, Glossary, and Tool pages are the \u003Cstrong>deep reference layer\u003C/strong> — linked from contextual tooltips, not presented as a separate navigation path\u003C/li>\n\u003C/ul>\n\u003Cp>\u003Cstrong>Anti-pattern:\u003C/strong> A separate “Academy” or “Learn” section that competes with reference pages for attention. Learning should happen IN context, not BEFORE context.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-visitor-experience\">The Visitor Experience\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-visitor-experience\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Visitor Experience”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"a-supplier-quality-engineer-searches-how-to-verify-supplier-cpk-data\">A Supplier Quality Engineer searches “how to verify supplier Cpk data”\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#a-supplier-quality-engineer-searches-how-to-verify-supplier-cpk-data\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “A Supplier Quality Engineer searches “how to verify supplier Cpk data””\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Lands on\u003C/strong> \u003Ccode dir=\"auto\">/use-cases/supplier-ppap\u003C/code> — headline: “Verify supplier capability in minutes, not hours.”\u003C/li>\n\u003Cli>\u003Cstrong>Sees the problem\u003C/strong> described in 2 sentences (they recognize their situation)\u003C/li>\n\u003Cli>\u003Cstrong>Below:\u003C/strong> A live interactive chart showing an I-Chart of supplier data — one point outside limits is highlighted\u003C/li>\n\u003Cli>\u003Cstrong>Scrolls to the journey:\u003C/strong> Step 1 I-Chart → Step 2 Capability → Step 3 Performance Mode. Each step has a mini-chart demo.\u003C/li>\n\u003Cli>\u003Cstrong>On the Capability chart\u003C/strong>, Cpk = 0.98 is shown. A (i) HelpTooltip explains: “Cpk measures how centered your process is within spec limits. Below 1.0 means the process is producing out-of-spec parts.”\u003C/li>\n\u003Cli>\u003Cstrong>“Learn more”\u003C/strong> opens the glossary Cpk page for the full formula and thresholds — but the visitor already understood the key insight WITHOUT leaving the page\u003C/li>\n\u003Cli>\u003Cstrong>Before/After table\u003C/strong> shows the transformation\u003C/li>\n\u003Cli>\u003Cstrong>CTA:\u003C/strong> “Try with your PPAP data” → opens PWA, OR “See the full analysis” → links to relevant case study\u003C/li>\n\u003Cli>\u003Cstrong>Platform fit table:\u003C/strong> “For full PPAP review across 25+ characteristics → Azure App”\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"dual-audience-design\">Dual-Audience Design\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#dual-audience-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dual-Audience Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Every reference page serves two audiences simultaneously:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Audience\u003C/th>\u003Cth>Arrives From\u003C/th>\u003Cth>Needs\u003C/th>\u003Cth>Content Strategy\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Cold searcher\u003C/td>\u003Ctd>Google search\u003C/td>\u003Ctd>Context, explanation, trust\u003C/td>\u003Ctd>Problem framing, live demo, methodology\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Warm app user\u003C/td>\u003Ctd>HelpTooltip “Learn more”\u003C/td>\u003Ctd>Focused reference, formula, threshold\u003C/td>\u003Ctd>Clean definition, interpretation table\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The same page works for both because:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Top section\u003C/strong> is definitional (serves the warm user immediately)\u003C/li>\n\u003Cli>\u003Cstrong>Middle section\u003C/strong> is explanatory (serves the cold searcher)\u003C/li>\n\u003Cli>\u003Cstrong>Bottom section\u003C/strong> connects to related content (serves both)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-this-differs-from-alternatives\">How This Differs from Alternatives\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-this-differs-from-alternatives\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How This Differs from Alternatives”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"vs-pure-showcase-stripe\">vs Pure Showcase (Stripe)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#vs-pure-showcase-stripe\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “vs Pure Showcase (Stripe)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pure Showcase\u003C/th>\u003Cth>Guided Problem Playground\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Screenshot or illustration\u003C/td>\u003Ctd>Live interactive chart\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”See features” CTA\u003C/td>\u003Ctd>”Try with your data” CTA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Learning in docs section\u003C/td>\u003Ctd>Learning inline via tooltips\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Separate product pages\u003C/td>\u003Ctd>Product IS the demo\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"vs-pure-playground-desmos\">vs Pure Playground (Desmos)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#vs-pure-playground-desmos\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “vs Pure Playground (Desmos)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pure Playground\u003C/th>\u003Cth>Guided Problem Playground\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Tool IS the homepage\u003C/td>\u003Ctd>Problem IS the homepage, tool proves it\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>No narrative context\u003C/td>\u003Ctd>Story frames the data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Learning through exploration\u003C/td>\u003Ctd>Guided discovery with contextual hints\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Weak SEO (no text content)\u003C/td>\u003Ctd>Strong SEO (problem narrative + keywords)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"vs-academy-mozahrefs\">vs Academy (Moz/Ahrefs)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#vs-academy-mozahrefs\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “vs Academy (Moz/Ahrefs)”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Academy\u003C/th>\u003Cth>Guided Problem Playground\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Read → understand → try\u003C/td>\u003Ctd>See problem → see proof → dig deeper\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Education drives discovery\u003C/td>\u003Ctd>Problem drives discovery\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Blog posts as primary content\u003C/td>\u003Ctd>Use case pages as primary content\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>”Learn about Cpk\"\u003C/td>\u003Ctd>\"This supplier’s Cpk is 0.98 — here’s why”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"minitab-comparison\">Minitab Comparison\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#minitab-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Minitab Comparison”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Minitab uses three separate layers:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Layer\u003C/th>\u003Cth>Minitab\u003C/th>\u003Cth>VariScout Equivalent\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>In-App Assistant\u003C/td>\u003Ctd>Desktop decision tree + dialogs\u003C/td>\u003Ctd>HelpTooltip (i) + useGlossary\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>support.minitab.com\u003C/td>\u003Ctd>4-page reference per topic\u003C/td>\u003Ctd>Learn pages + Glossary pages\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>minitab.com\u003C/td>\u003Ctd>Marketing site\u003C/td>\u003Ctd>Use case pages + Product pages\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Key differences:\u003C/strong>\u003C/p>\n\u003Cul>\n\u003Cli>VariScout puts all three on one domain (better for SEO)\u003C/li>\n\u003Cli>VariScout Learn/Glossary pages have live interactive charts (Minitab has static images)\u003C/li>\n\u003Cli>VariScout’s help is public and free (Minitab’s is for paid users)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"content-principles\">Content Principles\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#content-principles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Content Principles”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\u003Cstrong>Every page starts with a problem, not a feature\u003C/strong> — The visitor should recognize their situation before they see VariScout\u003C/li>\n\u003Cli>\u003Cstrong>Every claim has a live interactive proof\u003C/strong> — If you can show a chart instead of describing one, show the chart\u003C/li>\n\u003Cli>\u003Cstrong>Learning is contextual, not structural\u003C/strong> — Inline tooltips and collapsible sections, not a separate Academy\u003C/li>\n\u003Cli>\u003Cstrong>Reference pages are clean and focused\u003C/strong> — No marketing noise on Learn/Glossary pages; they serve dual audiences\u003C/li>\n\u003Cli>\u003Cstrong>Cross-links form a web, not a funnel\u003C/strong> — Any page can lead to any other relevant page; don’t force linear paths\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"anti-patterns\">Anti-Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#anti-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Anti-Patterns”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Don’t\u003C/th>\u003Cth>Do Instead\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Feature tours without problem context\u003C/td>\u003Ctd>Name the professional’s pain first\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Screenshots when a live chart can be shown\u003C/td>\u003Ctd>Use React island with sample data\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Separate “Academy” competing with reference\u003C/td>\u003Ctd>Embed learning inline with tooltips\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Marketing noise on reference pages\u003C/td>\u003Ctd>Keep Learn/Glossary clean and focused\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Force linear funnels\u003C/td>\u003Ctd>Let cross-links form a natural web\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Generic “SPC software” messaging\u003C/td>\u003Ctd>Industry-specific problem framing\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-008-website-content-architecture.md\">ADR-008: Website Content Architecture\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"content-architecture.md\">Content Architecture\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"index.md\">Website Overview\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 12538, + "localImagePaths": 12585, + "remoteImagePaths": 12586, + "frontmatter": 12587, + "imagePaths": 12588 + }, + [ + 12539, 12541, 12544, 12545, 12548, 12551, 12554, 12557, 12560, 12563, 12566, 12569, 12572, + 12575, 12578, 12581, 12584 + ], + { "depth": 30, "slug": 12540, "text": 12528 }, + "website-design-philosophy", + { "depth": 33, "slug": 12542, "text": 12543 }, + "the-philosophy-in-one-sentence", + "The Philosophy in One Sentence", + { "depth": 33, "slug": 2438, "text": 2439 }, + { "depth": 79, "slug": 12546, "text": 12547 }, + "1-problem-first-from-showcase--stripe", + "1. Problem-First (from Showcase / Stripe)", + { "depth": 79, "slug": 12549, "text": 12550 }, + "2-live-proof-from-playground--desmos", + "2. Live Proof (from Playground / Desmos)", + { "depth": 79, "slug": 12552, "text": 12553 }, + "3-contextual-depth-from-minitab-assistant--progressive-disclosure", + "3. Contextual Depth (from Minitab Assistant + Progressive Disclosure)", + { "depth": 33, "slug": 12555, "text": 12556 }, + "the-visitor-experience", + "The Visitor Experience", + { "depth": 79, "slug": 12558, "text": 12559 }, + "a-supplier-quality-engineer-searches-how-to-verify-supplier-cpk-data", + "A Supplier Quality Engineer searches “how to verify supplier Cpk data”", + { "depth": 33, "slug": 12561, "text": 12562 }, + "dual-audience-design", + "Dual-Audience Design", + { "depth": 33, "slug": 12564, "text": 12565 }, + "how-this-differs-from-alternatives", + "How This Differs from Alternatives", + { "depth": 79, "slug": 12567, "text": 12568 }, + "vs-pure-showcase-stripe", + "vs Pure Showcase (Stripe)", + { "depth": 79, "slug": 12570, "text": 12571 }, + "vs-pure-playground-desmos", + "vs Pure Playground (Desmos)", + { "depth": 79, "slug": 12573, "text": 12574 }, + "vs-academy-mozahrefs", + "vs Academy (Moz/Ahrefs)", + { "depth": 33, "slug": 12576, "text": 12577 }, + "minitab-comparison", + "Minitab Comparison", + { "depth": 33, "slug": 12579, "text": 12580 }, + "content-principles", + "Content Principles", + { "depth": 33, "slug": 12582, "text": 12583 }, + "anti-patterns", + "Anti-Patterns", + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 12528 }, + [], + "08-products/website", + { + "id": 12589, + "data": 12591, + "body": 12596, + "filePath": 12597, + "digest": 12598, + "rendered": 12599 + }, + { + "title": 12592, + "editUrl": 16, + "head": 12593, + "template": 18, + "sidebar": 12594, + "pagefind": 16, + "draft": 20 + }, + "Marketing Website", + [], + { "hidden": 20, "attrs": 12595 }, + {}, + "# Marketing Website\n\nThe variscout.com website serves three strategic purposes: **lead generation** through SEO-optimized educational content, **product education** through interactive chart demos, and **conversion** by funneling visitors toward the PWA (free) and Azure App (paid).\n\n---\n\n## Overview\n\nThe website is the top of the VaRiScout funnel. It targets quality professionals, Lean Six Sigma learners, and operations managers searching for variation analysis tools and SPC concepts.\n\n| Purpose | How |\n| ----------------- | ---------------------------------------------------------------- |\n| Lead generation | Tool pages, glossary, and learn topics rank for SPC search terms |\n| Product education | Live Visx chart demos show VaRiScout in action without signup |\n| Conversion | Every page funnels toward \"Try Now\" CTA linking to the PWA |\n\nThe website does **not** contain the application itself. The PWA and Azure App are separate products with their own codebases and deployment.\n\n---\n\n## Three Surfaces\n\nThe website follows a **\"Guided Problem Playground\"** philosophy (see [ADR-008](../../07-decisions/adr-008-website-content-architecture.md)) organized into three content surfaces:\n\n| Surface | Pages | Audience | Character |\n| -------------------------- | ---------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------- |\n| **Showcase (Acquisition)** | 6 use case pages (7 more planned), homepage, product pages | Cold visitors from search | Problem-first, live demos, professional framing |\n| **Reference (Learning)** | 6 tool pages, 11 learn topics, 35+ glossary terms | Both cold searchers AND app users (via HelpTooltip) | Clean, focused, reference-first with live charts |\n| **Proof (Case Studies)** | 10 case studies | Evaluators, curious visitors | 3-act narrative with interactive data exploration |\n\nAll three surfaces cross-link bidirectionally. See [Design Philosophy](design-philosophy.md) and [Content Architecture](content-architecture.md) for details.\n\n---\n\n## Technology Stack\n\n| Component | Technology | Why |\n| ----------- | ---------------------------- | ------------------------------------------------------------- |\n| Framework | Astro 5 | Static HTML + selective hydration = fast page loads, good SEO |\n| Interactive | React 19 Islands | Only chart demos need client-side JS |\n| Styling | Tailwind CSS v4 | Utility-first, consistent with PWA/Azure design tokens |\n| Charts | Visx (via @variscout/charts) | Same chart components used in the real product |\n| Icons | lucide-astro | Lightweight, tree-shakeable |\n| Hosting | Vercel | Auto-deploy on push to main, global CDN |\n\n---\n\n## Architecture: Astro Islands\n\nThe website is primarily static HTML. React only loads for interactive chart demos.\n\n```\nPage request\n └─ Astro renders static HTML (Header, Hero, content, Footer)\n └─ React islands hydrate when scrolled into view (client:visible)\n └─ IChartIsland, BoxplotIsland, ParetoIsland, etc.\n └─ Use @variscout/charts + @variscout/data for live demos\n```\n\n**9 React islands:** IChartIsland, BoxplotIsland, ParetoIsland, StatsIsland, PerformanceDemo, ToolChartIsland, CaseStudyChartsIsland, GlossaryTooltipIsland, ChartContainer\n\n**23 Astro components:** Header, Footer, Hero, FourLenses, PricingCard, ProductCard, UseCaseCard, FeatureCard, and more (static, zero JS)\n\n---\n\n## Internationalization (i18n)\n\nFive languages with locale-prefixed routing:\n\n| Language | Prefix | Example |\n| ----------------- | ------ | ------------------- |\n| English (default) | none | `/tools/i-chart` |\n| German | `/de` | `/de/tools/i-chart` |\n| Spanish | `/es` | `/es/tools/i-chart` |\n| French | `/fr` | `/fr/tools/i-chart` |\n| Portuguese | `/pt` | `/pt/tools/i-chart` |\n\nConfigured in `astro.config.mjs` with `prefixDefaultLocale: false`. Translation strings live in `src/i18n/ui.ts` (~170 lines covering nav, footer, glossary UI).\n\n---\n\n## Page Inventory\n\n| Route template | Dynamic data source | Pages per lang | Total (5 langs) |\n| ------------------------- | ----------------------------- | -------------- | --------------- |\n| `[lang]/index` | - | 1 | 5 |\n| `[lang]/pricing` | - | 1 | 5 |\n| `[lang]/journey` | - | 1 | 5 |\n| `[lang]/getting-started` | inline in template | 1 | 5 |\n| `[lang]/product/[slug]` | hardcoded slugs | 2 | ~10 |\n| `[lang]/use-cases/index` | `useCaseData.ts` | 1 | 5 |\n| `[lang]/use-cases/[slug]` | `useCaseData.ts` (6 Phase 1) | 6 | 30 |\n| `[lang]/tools/[tool]` | `toolsData.ts` (6 tools) | 6 | 30 |\n| `[lang]/learn/[topic]` | `learnData.ts` (11 topics) | 11 | 55 |\n| `[lang]/cases/[slug]` | case data | varies | varies |\n| `[lang]/glossary/[term]` | `glossaryData.ts` (~26 terms) | ~26 | ~130 |\n| `[lang]/glossary/index` | - | 1 | 5 |\n| Static pages | - | 7 | 7 |\n\n**Static pages** (not localized): `/`, `/404`, `/app`, `/about`, `/contact`, `/resources/tutorials`, `/resources/sample-data`, `/legal/privacy`, `/legal/terms`\n\n---\n\n## Content Architecture\n\nAll content is managed through three TypeScript data files (no CMS, no Markdown):\n\n| File | Interface | Items | Content |\n| ----------------- | ------------------ | ------ | -------------------------------------------------------------------------------------------------- |\n| `useCaseData.ts` | `UseCase` | 6 (13) | Problem, demo config, journey steps, before/after, cross-links, platform fit, SEO keywords |\n| `toolsData.ts` | `ToolData` | 6 | Tool name, lens, hero, when-to-use, data requirements, how-to-read, patterns, features, sample key |\n| `learnData.ts` | `LearnTopic` | 11 | Topic title, sections with visuals (comparison, diagram, list, quote, chart) |\n| `glossaryData.ts` | `GlossaryPageData` | ~26 | Extends `@variscout/core` glossary with SEO metadata, rich sections, practical tips |\n\nEach file exports helper functions (`getToolBySlug()`, `getLearnTopicBySlug()`, `getGlossaryPageData()`) used by dynamic route pages for static generation.\n\n---\n\n## Product Funnel\n\n```\nSearch / Social / Referral\n │\n ▼\n Website (variscout.com)\n ├── Tool pages ──────── \"Try this chart\" ──► PWA (free, instant)\n ├── Learn topics ─────── \"Practice now\" ──► PWA (free, instant)\n ├── Glossary ──────────── Cross-links ──► Tool & Learn pages\n ├── Case studies ───── \"See it in action\" ──► PWA (free, instant)\n ├── Use cases ────── \"For your workflow\" ──► Product pages\n └── Pricing ────────── \"Get started\" ──► Azure Marketplace\n```\n\nEvery page includes a CTA. Tool and learn pages link to the free PWA for immediate engagement. Pricing and product pages link to the Azure Marketplace (from €99/month).\n\n---\n\n## User Journeys\n\nThe website supports five primary visitor flows:\n\n| Journey | Entry | Path | Goal |\n| ---------------- | -------------------------- | ---------------------------- | ----------------------- |\n| SEO Learner | Google search for SPC term | Tool/glossary/learn page | Try PWA |\n| Social Discovery | LinkedIn/social share | Case study | Explore tools |\n| Enterprise | Referral/direct | Product comparison + pricing | Azure signup |\n| Content | YouTube/blog link | Learn topic | Engage with methodology |\n| Return Visitor | Direct URL | PWA/app page | Use product |\n\nSee [User Journeys](../../02-journeys/index.md) and [Flow Documentation](../../02-journeys/flows/) for details.\n\n---\n\n## SEO Implementation\n\n`BaseLayout.astro` provides SEO infrastructure for every page:\n\n- **Meta tags:** title, description, canonical URL (per-page)\n- **Open Graph:** og:title, og:description, og:image, og:locale (per language)\n- **Twitter Cards:** summary_large_image with per-page content\n- **Schema.org:** `SoftwareApplication` structured data with pricing (Free Web App, from €99/month Azure App)\n- **Sitemap:** auto-generated via `@astrojs/sitemap` integration\n- **Canonical URLs:** resolve to `https://variscout.com` with correct locale paths\n- **Self-hosted fonts:** woff2 files in `public/fonts/` (GDPR-clean — no requests to Google)\n\n---\n\n## Performance\n\n| Feature | Implementation | Benefit |\n| ------------------ | ------------------------------------- | ----------------------------------------------- |\n| View Transitions | `ClientRouter` in BaseLayout | Smooth cross-fade navigation, no white flash |\n| Prefetching | `hover` strategy in astro.config | Near-instant page loads after hover |\n| Deferred hydration | `client:visible` on all chart islands | JS loads only when scrolled into view |\n| Loading skeletons | Pulse animation in ChartContainer | No blank-box flash before charts render |\n| Self-hosted fonts | woff2 in `public/fonts/` | GDPR-clean, faster (same-origin), works offline |\n| Skip-to-content | Accessible skip link in BaseLayout | WCAG 2.1 AA keyboard navigation |\n\n---\n\n## Deployment\n\n| Setting | Value |\n| --------------------- | -------------------------------- |\n| Host | Vercel |\n| Deploy trigger | Push to `main` branch |\n| Build command | `astro build` |\n| Output | Static files (no server runtime) |\n| Environment variables | None required |\n| Domain | variscout.com |\n\nThe website is fully static. No server-side code, no database, no environment variables needed at runtime.\n\n---\n\n## See Also\n\n- [ADR-008: Website Content Architecture](../../07-decisions/adr-008-website-content-architecture.md)\n- [Design Philosophy](design-philosophy.md)\n- [Content Architecture](content-architecture.md)\n- `apps/website/README.md` (developer guide)\n- [User Journeys](../../02-journeys/index.md)\n- [Design System](../../06-design-system/index.md)\n- [Deployment Guide](../../05-technical/implementation/deployment.md)\n- [Feature Parity Matrix](../feature-parity.md)", + "src/content/docs/08-products/website/index.md", + "c84cc20d0c293224", + { "html": 12600, "metadata": 12601 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"marketing-website\">Marketing Website\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#marketing-website\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Marketing Website”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The variscout.com website serves three strategic purposes: \u003Cstrong>lead generation\u003C/strong> through SEO-optimized educational content, \u003Cstrong>product education\u003C/strong> through interactive chart demos, and \u003Cstrong>conversion\u003C/strong> by funneling visitors toward the PWA (free) and Azure App (paid).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"overview\">Overview\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#overview\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Overview”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The website is the top of the VaRiScout funnel. It targets quality professionals, Lean Six Sigma learners, and operations managers searching for variation analysis tools and SPC concepts.\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Purpose\u003C/th>\u003Cth>How\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Lead generation\u003C/td>\u003Ctd>Tool pages, glossary, and learn topics rank for SPC search terms\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Product education\u003C/td>\u003Ctd>Live Visx chart demos show VaRiScout in action without signup\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Conversion\u003C/td>\u003Ctd>Every page funnels toward “Try Now” CTA linking to the PWA\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The website does \u003Cstrong>not\u003C/strong> contain the application itself. The PWA and Azure App are separate products with their own codebases and deployment.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"three-surfaces\">Three Surfaces\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#three-surfaces\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Three Surfaces”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The website follows a \u003Cstrong>“Guided Problem Playground”\u003C/strong> philosophy (see \u003Ca href=\"../../07-decisions/adr-008-website-content-architecture.md\">ADR-008\u003C/a>) organized into three content surfaces:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Surface\u003C/th>\u003Cth>Pages\u003C/th>\u003Cth>Audience\u003C/th>\u003Cth>Character\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Showcase (Acquisition)\u003C/strong>\u003C/td>\u003Ctd>6 use case pages (7 more planned), homepage, product pages\u003C/td>\u003Ctd>Cold visitors from search\u003C/td>\u003Ctd>Problem-first, live demos, professional framing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Reference (Learning)\u003C/strong>\u003C/td>\u003Ctd>6 tool pages, 11 learn topics, 35+ glossary terms\u003C/td>\u003Ctd>Both cold searchers AND app users (via HelpTooltip)\u003C/td>\u003Ctd>Clean, focused, reference-first with live charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Proof (Case Studies)\u003C/strong>\u003C/td>\u003Ctd>10 case studies\u003C/td>\u003Ctd>Evaluators, curious visitors\u003C/td>\u003Ctd>3-act narrative with interactive data exploration\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>All three surfaces cross-link bidirectionally. See \u003Ca href=\"design-philosophy.md\">Design Philosophy\u003C/a> and \u003Ca href=\"content-architecture.md\">Content Architecture\u003C/a> for details.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"technology-stack\">Technology Stack\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#technology-stack\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Technology Stack”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Component\u003C/th>\u003Cth>Technology\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Framework\u003C/td>\u003Ctd>Astro 5\u003C/td>\u003Ctd>Static HTML + selective hydration = fast page loads, good SEO\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Interactive\u003C/td>\u003Ctd>React 19 Islands\u003C/td>\u003Ctd>Only chart demos need client-side JS\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Styling\u003C/td>\u003Ctd>Tailwind CSS v4\u003C/td>\u003Ctd>Utility-first, consistent with PWA/Azure design tokens\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Charts\u003C/td>\u003Ctd>Visx (via @variscout/charts)\u003C/td>\u003Ctd>Same chart components used in the real product\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Icons\u003C/td>\u003Ctd>lucide-astro\u003C/td>\u003Ctd>Lightweight, tree-shakeable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Hosting\u003C/td>\u003Ctd>Vercel\u003C/td>\u003Ctd>Auto-deploy on push to main, global CDN\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"architecture-astro-islands\">Architecture: Astro Islands\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#architecture-astro-islands\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Architecture: Astro Islands”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The website is primarily static HTML. React only loads for interactive chart demos.\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Page request\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ Astro renders static HTML (Header, Hero, content, Footer)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ React islands hydrate when scrolled into view (client:visible)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ IChartIsland, BoxplotIsland, ParetoIsland, etc.\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└─ Use @variscout/charts + @variscout/data for live demos\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Page request └─ Astro renders static HTML (Header, Hero, content, Footer) └─ React islands hydrate when scrolled into view (client:visible) └─ IChartIsland, BoxplotIsland, ParetoIsland, etc. └─ Use @variscout/charts + @variscout/data for live demos\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>\u003Cstrong>9 React islands:\u003C/strong> IChartIsland, BoxplotIsland, ParetoIsland, StatsIsland, PerformanceDemo, ToolChartIsland, CaseStudyChartsIsland, GlossaryTooltipIsland, ChartContainer\u003C/p>\n\u003Cp>\u003Cstrong>23 Astro components:\u003C/strong> Header, Footer, Hero, FourLenses, PricingCard, ProductCard, UseCaseCard, FeatureCard, and more (static, zero JS)\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"internationalization-i18n\">Internationalization (i18n)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#internationalization-i18n\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Internationalization (i18n)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Five languages with locale-prefixed routing:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Language\u003C/th>\u003Cth>Prefix\u003C/th>\u003Cth>Example\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>English (default)\u003C/td>\u003Ctd>none\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/tools/i-chart\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>German\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/de\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/de/tools/i-chart\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Spanish\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/es\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/es/tools/i-chart\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>French\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/fr\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/fr/tools/i-chart\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Portuguese\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/pt\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">/pt/tools/i-chart\u003C/code>\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Configured in \u003Ccode dir=\"auto\">astro.config.mjs\u003C/code> with \u003Ccode dir=\"auto\">prefixDefaultLocale: false\u003C/code>. Translation strings live in \u003Ccode dir=\"auto\">src/i18n/ui.ts\u003C/code> (~170 lines covering nav, footer, glossary UI).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"page-inventory\">Page Inventory\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#page-inventory\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Page Inventory”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Route template\u003C/th>\u003Cth>Dynamic data source\u003C/th>\u003Cth>Pages per lang\u003C/th>\u003Cth>Total (5 langs)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/index\u003C/code>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/pricing\u003C/code>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/journey\u003C/code>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/getting-started\u003C/code>\u003C/td>\u003Ctd>inline in template\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/product/[slug]\u003C/code>\u003C/td>\u003Ctd>hardcoded slugs\u003C/td>\u003Ctd>2\u003C/td>\u003Ctd>~10\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/use-cases/index\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useCaseData.ts\u003C/code>\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/use-cases/[slug]\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">useCaseData.ts\u003C/code> (6 Phase 1)\u003C/td>\u003Ctd>6\u003C/td>\u003Ctd>30\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/tools/[tool]\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">toolsData.ts\u003C/code> (6 tools)\u003C/td>\u003Ctd>6\u003C/td>\u003Ctd>30\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/learn/[topic]\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">learnData.ts\u003C/code> (11 topics)\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>55\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/cases/[slug]\u003C/code>\u003C/td>\u003Ctd>case data\u003C/td>\u003Ctd>varies\u003C/td>\u003Ctd>varies\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/glossary/[term]\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">glossaryData.ts\u003C/code> (~26 terms)\u003C/td>\u003Ctd>~26\u003C/td>\u003Ctd>~130\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">[lang]/glossary/index\u003C/code>\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>1\u003C/td>\u003Ctd>5\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Static pages\u003C/td>\u003Ctd>-\u003C/td>\u003Ctd>7\u003C/td>\u003Ctd>7\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>\u003Cstrong>Static pages\u003C/strong> (not localized): \u003Ccode dir=\"auto\">/\u003C/code>, \u003Ccode dir=\"auto\">/404\u003C/code>, \u003Ccode dir=\"auto\">/app\u003C/code>, \u003Ccode dir=\"auto\">/about\u003C/code>, \u003Ccode dir=\"auto\">/contact\u003C/code>, \u003Ccode dir=\"auto\">/resources/tutorials\u003C/code>, \u003Ccode dir=\"auto\">/resources/sample-data\u003C/code>, \u003Ccode dir=\"auto\">/legal/privacy\u003C/code>, \u003Ccode dir=\"auto\">/legal/terms\u003C/code>\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"content-architecture\">Content Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#content-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Content Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>All content is managed through three TypeScript data files (no CMS, no Markdown):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>File\u003C/th>\u003Cth>Interface\u003C/th>\u003Cth>Items\u003C/th>\u003Cth>Content\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">useCaseData.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">UseCase\u003C/code>\u003C/td>\u003Ctd>6 (13)\u003C/td>\u003Ctd>Problem, demo config, journey steps, before/after, cross-links, platform fit, SEO keywords\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">toolsData.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ToolData\u003C/code>\u003C/td>\u003Ctd>6\u003C/td>\u003Ctd>Tool name, lens, hero, when-to-use, data requirements, how-to-read, patterns, features, sample key\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">learnData.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">LearnTopic\u003C/code>\u003C/td>\u003Ctd>11\u003C/td>\u003Ctd>Topic title, sections with visuals (comparison, diagram, list, quote, chart)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Ccode dir=\"auto\">glossaryData.ts\u003C/code>\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">GlossaryPageData\u003C/code>\u003C/td>\u003Ctd>~26\u003C/td>\u003Ctd>Extends \u003Ccode dir=\"auto\">@variscout/core\u003C/code> glossary with SEO metadata, rich sections, practical tips\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>Each file exports helper functions (\u003Ccode dir=\"auto\">getToolBySlug()\u003C/code>, \u003Ccode dir=\"auto\">getLearnTopicBySlug()\u003C/code>, \u003Ccode dir=\"auto\">getGlossaryPageData()\u003C/code>) used by dynamic route pages for static generation.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"product-funnel\">Product Funnel\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#product-funnel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Funnel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"expressive-code\">\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Search / Social / Referral\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">│\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">▼\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">Website (variscout.com)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Tool pages ──────── \"Try this chart\" ──► PWA (free, instant)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Learn topics ─────── \"Practice now\" ──► PWA (free, instant)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Glossary ──────────── Cross-links ──► Tool & Learn pages\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Case studies ───── \"See it in action\" ──► PWA (free, instant)\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">├── Use cases ────── \"For your workflow\" ──► Product pages\u003C/span>\u003C/div>\u003C/div>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan class=\"indent\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\"> \u003C/span>\u003C/span>\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">└── Pricing ────────── \"Get started\" ──► Azure Marketplace\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"Search / Social / Referral │ ▼ Website (variscout.com) ├── Tool pages ──────── "Try this chart" ──► PWA (free, instant) ├── Learn topics ─────── "Practice now" ──► PWA (free, instant) ├── Glossary ──────────── Cross-links ──► Tool & Learn pages ├── Case studies ───── "See it in action" ──► PWA (free, instant) ├── Use cases ────── "For your workflow" ──► Product pages └── Pricing ────────── "Get started" ──► Azure Marketplace\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>Every page includes a CTA. Tool and learn pages link to the free PWA for immediate engagement. Pricing and product pages link to the Azure Marketplace (from €99/month).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"user-journeys\">User Journeys\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#user-journeys\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “User Journeys”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The website supports five primary visitor flows:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Journey\u003C/th>\u003Cth>Entry\u003C/th>\u003Cth>Path\u003C/th>\u003Cth>Goal\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>SEO Learner\u003C/td>\u003Ctd>Google search for SPC term\u003C/td>\u003Ctd>Tool/glossary/learn page\u003C/td>\u003Ctd>Try PWA\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Social Discovery\u003C/td>\u003Ctd>LinkedIn/social share\u003C/td>\u003Ctd>Case study\u003C/td>\u003Ctd>Explore tools\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Enterprise\u003C/td>\u003Ctd>Referral/direct\u003C/td>\u003Ctd>Product comparison + pricing\u003C/td>\u003Ctd>Azure signup\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Content\u003C/td>\u003Ctd>YouTube/blog link\u003C/td>\u003Ctd>Learn topic\u003C/td>\u003Ctd>Engage with methodology\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Return Visitor\u003C/td>\u003Ctd>Direct URL\u003C/td>\u003Ctd>PWA/app page\u003C/td>\u003Ctd>Use product\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>See \u003Ca href=\"../../02-journeys/index.md\">User Journeys\u003C/a> and \u003Ca href=\"../../02-journeys/flows/\">Flow Documentation\u003C/a> for details.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"seo-implementation\">SEO Implementation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#seo-implementation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SEO Implementation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">BaseLayout.astro\u003C/code> provides SEO infrastructure for every page:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Meta tags:\u003C/strong> title, description, canonical URL (per-page)\u003C/li>\n\u003Cli>\u003Cstrong>Open Graph:\u003C/strong> og:title, og:description, og:image, og:locale (per language)\u003C/li>\n\u003Cli>\u003Cstrong>Twitter Cards:\u003C/strong> summary_large_image with per-page content\u003C/li>\n\u003Cli>\u003Cstrong>Schema.org:\u003C/strong> \u003Ccode dir=\"auto\">SoftwareApplication\u003C/code> structured data with pricing (Free Web App, from €99/month Azure App)\u003C/li>\n\u003Cli>\u003Cstrong>Sitemap:\u003C/strong> auto-generated via \u003Ccode dir=\"auto\">@astrojs/sitemap\u003C/code> integration\u003C/li>\n\u003Cli>\u003Cstrong>Canonical URLs:\u003C/strong> resolve to \u003Ccode dir=\"auto\">https://variscout.com\u003C/code> with correct locale paths\u003C/li>\n\u003Cli>\u003Cstrong>Self-hosted fonts:\u003C/strong> woff2 files in \u003Ccode dir=\"auto\">public/fonts/\u003C/code> (GDPR-clean — no requests to Google)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"performance\">Performance\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#performance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Performance”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>Implementation\u003C/th>\u003Cth>Benefit\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>View Transitions\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ClientRouter\u003C/code> in BaseLayout\u003C/td>\u003Ctd>Smooth cross-fade navigation, no white flash\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Prefetching\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">hover\u003C/code> strategy in astro.config\u003C/td>\u003Ctd>Near-instant page loads after hover\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Deferred hydration\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">client:visible\u003C/code> on all chart islands\u003C/td>\u003Ctd>JS loads only when scrolled into view\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Loading skeletons\u003C/td>\u003Ctd>Pulse animation in ChartContainer\u003C/td>\u003Ctd>No blank-box flash before charts render\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Self-hosted fonts\u003C/td>\u003Ctd>woff2 in \u003Ccode dir=\"auto\">public/fonts/\u003C/code>\u003C/td>\u003Ctd>GDPR-clean, faster (same-origin), works offline\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Skip-to-content\u003C/td>\u003Ctd>Accessible skip link in BaseLayout\u003C/td>\u003Ctd>WCAG 2.1 AA keyboard navigation\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"deployment\">Deployment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#deployment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Deployment”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Setting\u003C/th>\u003Cth>Value\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Host\u003C/td>\u003Ctd>Vercel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Deploy trigger\u003C/td>\u003Ctd>Push to \u003Ccode dir=\"auto\">main\u003C/code> branch\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Build command\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">astro build\u003C/code>\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Output\u003C/td>\u003Ctd>Static files (no server runtime)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Environment variables\u003C/td>\u003Ctd>None required\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Domain\u003C/td>\u003Ctd>variscout.com\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The website is fully static. No server-side code, no database, no environment variables needed at runtime.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"see-also\">See Also\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#see-also\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “See Also”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../../07-decisions/adr-008-website-content-architecture.md\">ADR-008: Website Content Architecture\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"design-philosophy.md\">Design Philosophy\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"content-architecture.md\">Content Architecture\u003C/a>\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">apps/website/README.md\u003C/code> (developer guide)\u003C/li>\n\u003Cli>\u003Ca href=\"../../02-journeys/index.md\">User Journeys\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../06-design-system/index.md\">Design System\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../../05-technical/implementation/deployment.md\">Deployment Guide\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"../feature-parity.md\">Feature Parity Matrix\u003C/a>\u003C/li>\n\u003C/ul>", + { + "headings": 12602, + "localImagePaths": 12632, + "remoteImagePaths": 12633, + "frontmatter": 12634, + "imagePaths": 12635 + }, + [ + 12603, 12605, 12606, 12607, 12610, 12613, 12614, 12617, 12620, 12623, 12624, 12627, 12630, 12631 + ], + { "depth": 30, "slug": 12604, "text": 12592 }, + "marketing-website", + { "depth": 33, "slug": 447, "text": 448 }, + { "depth": 33, "slug": 2435, "text": 2436 }, + { "depth": 33, "slug": 12608, "text": 12609 }, + "technology-stack", + "Technology Stack", + { "depth": 33, "slug": 12611, "text": 12612 }, + "architecture-astro-islands", + "Architecture: Astro Islands", + { "depth": 33, "slug": 1487, "text": 1488 }, + { "depth": 33, "slug": 12615, "text": 12616 }, + "page-inventory", + "Page Inventory", + { "depth": 33, "slug": 12618, "text": 12619 }, + "content-architecture", + "Content Architecture", + { "depth": 33, "slug": 12621, "text": 12622 }, + "product-funnel", + "Product Funnel", + { "depth": 33, "slug": 899, "text": 887 }, + { "depth": 33, "slug": 12625, "text": 12626 }, + "seo-implementation", + "SEO Implementation", + { "depth": 33, "slug": 12628, "text": 12629 }, + "performance", + "Performance", + { "depth": 33, "slug": 11685, "text": 11686 }, + { "depth": 33, "slug": 149, "text": 150 }, + [], + [], + { "title": 12592 }, + [], + "01-vision/evaluations/patterns/auto-combination-finder", + { + "id": 12636, + "data": 12638, + "body": 12643, + "filePath": 12644, + "digest": 12645, + "rendered": 12646 + }, + { + "title": 12639, + "editUrl": 16, + "head": 12640, + "template": 18, + "sidebar": 12641, + "pagefind": 16, + "draft": 20 + }, + "Auto-Combination Finder", + [], + { "hidden": 20, "attrs": 12642 }, + {}, + "# Auto-Combination Finder\n\n> Use the regression engine to identify the highest-impact 2--3 filter combination automatically.\n\n## The Concept\n\nInstead of the analyst building a drill-down path manually --- one factor at a time, choosing at each step --- the system would use the existing regression engine to identify the top 2--3 factor combinations that explain the most variation. The result is presented as a starting hypothesis: \"Machine C + Night Shift + Material Batch 7 explains 62% of total variation.\"\n\nThe analyst then validates, adjusts, or explores from this starting point. This inverts the current workflow: instead of bottom-up exploration converging on a finding, the analyst starts with a system-generated finding and drills around it to understand _why_ that combination matters. The regression calculation is already available in `@variscout/core` --- this pattern surfaces its output earlier in the workflow rather than requiring the analyst to navigate to the regression panel.\n\nThe risk is twofold. First, for learning audiences, it short-circuits the entire progressive stratification methodology. The analyst never experiences the \"where is the variation?\" investigation that builds statistical intuition. Second, for all audiences, it may create false confidence: the system says \"here's your answer\" before the analyst has developed any context about the data. A top combination that's statistically strong but operationally meaningless (the factor can't be changed) feels like a wrong answer from the tool, even though the statistics are correct.\n\n## Tensions Addressed\n\n- [Hierarchy Assumption](../tensions/hierarchy-assumption.md) --- Regression-based detection naturally captures interaction effects that one-factor drilling misses.\n- [Factor Ordering](../tensions/factor-ordering.md) --- Bypasses factor ordering entirely by jumping to the optimal combination.\n- [Path Dependency](../tensions/path-dependency.md) --- Eliminates path dependency by starting from the endpoint rather than navigating to it.\n\n## Philosophy Alignment\n\n- **EDA for process improvement**: Partially conflicts. EDA is about exploration and pattern discovery. Auto-combination finding is closer to automated hypothesis generation --- useful but a different cognitive mode.\n- **Guided frustration pedagogy**: Strongly conflicts. The Sock Mystery depends on the analyst's journey from confusion to understanding. An auto-finder skips the journey entirely. This pattern is fundamentally at odds with the learning mission of the PWA.\n- **Four Lenses coordination**: Neutral to positive. Once a combination is surfaced, the analyst can examine it through all four lenses. The coordination still works; only the entry point changes.\n- **Two Voices**: Positive. The regression engine could weight combinations by both process-voice (variation explained) and customer-voice (Cpk impact), surfacing the combinations that matter most to the customer.\n\n## Persona Impact\n\n| Persona | Effect | Why |\n| --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | Positive | Gary wants efficiency. He can validate the system's suggestion against his domain knowledge rather than building the analysis from scratch. |\n| Student Sara | Negative | Sara needs the exploration journey to learn. An auto-finder teaches her to trust the tool's answer rather than develop her own analytical skills. |\n| OpEx Olivia | Positive | Olivia's team gets faster, more consistent results. The auto-finder is a productivity multiplier for experienced analysts. |\n| Trainer Tina | Negative | Tina would never use this in training. It undermines the pedagogical approach. She might use it personally for consulting work but would want it disabled for students. |\n| Evaluator Erik | Neutral | Doesn't affect Erik's evaluation criteria. |\n| Curious Carlos | Positive | Carlos wants to see \"the answer\" quickly. Auto-combination finding matches his attention span and delivers the dopamine hit of a clear finding. |\n\n## Platform Fit\n\n| Platform | Fit | Notes |\n| ------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------- |\n| PWA (free training) | Poor | Conflicts with the PWA's educational mission. Should not be available or should be clearly labeled as \"skip exploration.\" |\n| Azure (paid team) | Good | Professional teams prioritize speed and consistency. This is a premium feature that justifies the paid tier. |\n| Excel Add-in | N/A | The Excel Add-in's slicer-based filtering doesn't support this workflow. |\n\n## Competitive Landscape\n\n- **Minitab**: The Response Optimizer finds optimal factor settings but requires designed experiments with controlled factor levels — full factorial, fractional factorial, or response surface designs. This is fundamentally different from scanning observational process data for the highest-impact combination. Minitab's DOE workflow assumes the analyst has already identified which factors to study and has run a controlled experiment. See [Minitab Benchmark](../competitive/minitab-benchmark.md).\n- **JMP**: The Prediction Profiler shows main effects and interactions from a fitted model, allowing the analyst to slide factor inputs and see predicted response changes. However, the model must be specified first — the analyst must choose which factors to include and fit the model before the Profiler becomes available. JMP's approach is model-first exploration, not data-first automatic scanning. See [JMP Benchmark](../competitive/jmp-benchmark.md).\n- **SigmaXL**: An Excel add-in ($299/year) that provides multiple regression with stepwise variable selection — forward, backward, and stepwise algorithms that automate which predictors to include. This is the closest existing tool to automatic combination finding, but it requires the analyst to configure the analysis, understand regression assumptions, and interpret model diagnostics. It is an expert statistical tool, not a guided investigation feature. See [Minor Competitors](../competitive/minor-competitors.md).\n- **EDAScout**: Does not implement automatic combination finding. Their heuristic detection is simpler --- outlier flagging and subgroup suggestions via AI Smart Cards --- without multi-factor combination scanning. Their ANOVA is single-factor only, with no interaction detection. See [EDAScout Benchmark](../competitive/edascout-benchmark.md).\n\nVariScout's version would be unique in combining automatic combination detection with a visual drill-down validation workflow. The differentiation: not just \"here's the math\" but \"here's the finding --- now explore it through Four Lenses.\"\n\n## Strategic Verdict\n\n**Defer** --- Valuable for the Azure App as a power-user feature but conflicts with the PWA's educational mission. Should be implemented as a premium feature behind the paid tier, explicitly not available in the free training tool. The prerequisite is factor suggestion (a lighter-weight guided pattern) succeeding first.", + "src/content/docs/01-vision/evaluations/patterns/auto-combination-finder.md", + "e248b35b5dfdc8e8", + { "html": 12647, "metadata": 12648 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"auto-combination-finder\">Auto-Combination Finder\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#auto-combination-finder\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Auto-Combination Finder”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Use the regression engine to identify the highest-impact 2—3 filter combination automatically.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-concept\">The Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Instead of the analyst building a drill-down path manually --- one factor at a time, choosing at each step --- the system would use the existing regression engine to identify the top 2—3 factor combinations that explain the most variation. The result is presented as a starting hypothesis: “Machine C + Night Shift + Material Batch 7 explains 62% of total variation.”\u003C/p>\n\u003Cp>The analyst then validates, adjusts, or explores from this starting point. This inverts the current workflow: instead of bottom-up exploration converging on a finding, the analyst starts with a system-generated finding and drills around it to understand \u003Cem>why\u003C/em> that combination matters. The regression calculation is already available in \u003Ccode dir=\"auto\">@variscout/core\u003C/code> --- this pattern surfaces its output earlier in the workflow rather than requiring the analyst to navigate to the regression panel.\u003C/p>\n\u003Cp>The risk is twofold. First, for learning audiences, it short-circuits the entire progressive stratification methodology. The analyst never experiences the “where is the variation?” investigation that builds statistical intuition. Second, for all audiences, it may create false confidence: the system says “here’s your answer” before the analyst has developed any context about the data. A top combination that’s statistically strong but operationally meaningless (the factor can’t be changed) feels like a wrong answer from the tool, even though the statistics are correct.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tensions-addressed\">Tensions Addressed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tensions-addressed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tensions Addressed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../tensions/hierarchy-assumption.md\">Hierarchy Assumption\u003C/a> --- Regression-based detection naturally captures interaction effects that one-factor drilling misses.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/factor-ordering.md\">Factor Ordering\u003C/a> --- Bypasses factor ordering entirely by jumping to the optimal combination.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/path-dependency.md\">Path Dependency\u003C/a> --- Eliminates path dependency by starting from the endpoint rather than navigating to it.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy-alignment\">Philosophy Alignment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>EDA for process improvement\u003C/strong>: Partially conflicts. EDA is about exploration and pattern discovery. Auto-combination finding is closer to automated hypothesis generation --- useful but a different cognitive mode.\u003C/li>\n\u003Cli>\u003Cstrong>Guided frustration pedagogy\u003C/strong>: Strongly conflicts. The Sock Mystery depends on the analyst’s journey from confusion to understanding. An auto-finder skips the journey entirely. This pattern is fundamentally at odds with the learning mission of the PWA.\u003C/li>\n\u003Cli>\u003Cstrong>Four Lenses coordination\u003C/strong>: Neutral to positive. Once a combination is surfaced, the analyst can examine it through all four lenses. The coordination still works; only the entry point changes.\u003C/li>\n\u003Cli>\u003Cstrong>Two Voices\u003C/strong>: Positive. The regression engine could weight combinations by both process-voice (variation explained) and customer-voice (Cpk impact), surfacing the combinations that matter most to the customer.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Effect\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Gary wants efficiency. He can validate the system’s suggestion against his domain knowledge rather than building the analysis from scratch.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>Negative\u003C/td>\u003Ctd>Sara needs the exploration journey to learn. An auto-finder teaches her to trust the tool’s answer rather than develop her own analytical skills.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Olivia’s team gets faster, more consistent results. The auto-finder is a productivity multiplier for experienced analysts.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Negative\u003C/td>\u003Ctd>Tina would never use this in training. It undermines the pedagogical approach. She might use it personally for consulting work but would want it disabled for students.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Doesn’t affect Erik’s evaluation criteria.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Carlos wants to see “the answer” quickly. Auto-combination finding matches his attention span and delivers the dopamine hit of a clear finding.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Fit\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA (free training)\u003C/td>\u003Ctd>Poor\u003C/td>\u003Ctd>Conflicts with the PWA’s educational mission. Should not be available or should be clearly labeled as “skip exploration.”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure (paid team)\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Professional teams prioritize speed and consistency. This is a premium feature that justifies the paid tier.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel Add-in\u003C/td>\u003Ctd>N/A\u003C/td>\u003Ctd>The Excel Add-in’s slicer-based filtering doesn’t support this workflow.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-landscape\">Competitive Landscape\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-landscape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Landscape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Minitab\u003C/strong>: The Response Optimizer finds optimal factor settings but requires designed experiments with controlled factor levels — full factorial, fractional factorial, or response surface designs. This is fundamentally different from scanning observational process data for the highest-impact combination. Minitab’s DOE workflow assumes the analyst has already identified which factors to study and has run a controlled experiment. See \u003Ca href=\"../competitive/minitab-benchmark.md\">Minitab Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>JMP\u003C/strong>: The Prediction Profiler shows main effects and interactions from a fitted model, allowing the analyst to slide factor inputs and see predicted response changes. However, the model must be specified first — the analyst must choose which factors to include and fit the model before the Profiler becomes available. JMP’s approach is model-first exploration, not data-first automatic scanning. See \u003Ca href=\"../competitive/jmp-benchmark.md\">JMP Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>SigmaXL\u003C/strong>: An Excel add-in ($299/year) that provides multiple regression with stepwise variable selection — forward, backward, and stepwise algorithms that automate which predictors to include. This is the closest existing tool to automatic combination finding, but it requires the analyst to configure the analysis, understand regression assumptions, and interpret model diagnostics. It is an expert statistical tool, not a guided investigation feature. See \u003Ca href=\"../competitive/minor-competitors.md\">Minor Competitors\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>EDAScout\u003C/strong>: Does not implement automatic combination finding. Their heuristic detection is simpler --- outlier flagging and subgroup suggestions via AI Smart Cards --- without multi-factor combination scanning. Their ANOVA is single-factor only, with no interaction detection. See \u003Ca href=\"../competitive/edascout-benchmark.md\">EDAScout Benchmark\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>VariScout’s version would be unique in combining automatic combination detection with a visual drill-down validation workflow. The differentiation: not just “here’s the math” but “here’s the finding --- now explore it through Four Lenses.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-verdict\">Strategic Verdict\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-verdict\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Verdict”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Defer\u003C/strong> --- Valuable for the Azure App as a power-user feature but conflicts with the PWA’s educational mission. Should be implemented as a premium feature behind the paid tier, explicitly not available in the free training tool. The prerequisite is factor suggestion (a lighter-weight guided pattern) succeeding first.\u003C/p>", + { + "headings": 12649, + "localImagePaths": 12669, + "remoteImagePaths": 12670, + "frontmatter": 12671, + "imagePaths": 12672 + }, + [12650, 12652, 12655, 12658, 12661, 12664, 12665, 12666], + { "depth": 30, "slug": 12651, "text": 12639 }, + "auto-combination-finder", + { "depth": 33, "slug": 12653, "text": 12654 }, + "the-concept", + "The Concept", + { "depth": 33, "slug": 12656, "text": 12657 }, + "tensions-addressed", + "Tensions Addressed", + { "depth": 33, "slug": 12659, "text": 12660 }, + "philosophy-alignment", + "Philosophy Alignment", + { "depth": 33, "slug": 12662, "text": 12663 }, + "persona-impact", + "Persona Impact", + { "depth": 33, "slug": 4936, "text": 4937 }, + { "depth": 33, "slug": 2523, "text": 2524 }, + { "depth": 33, "slug": 12667, "text": 12668 }, + "strategic-verdict", + "Strategic Verdict", + [], + [], + { "title": 12639 }, + [], + "01-vision/evaluations/patterns/factor-map", + { + "id": 12673, + "data": 12675, + "body": 12680, + "filePath": 12681, + "digest": 12682, + "rendered": 12683 + }, + { + "title": 12676, + "editUrl": 16, + "head": 12677, + "template": 18, + "sidebar": 12678, + "pagefind": 16, + "draft": 20 + }, + "Factor Map", + [], + { "hidden": 20, "attrs": 12679 }, + {}, + "# Factor Map\n\n> A network visualization of the factor landscape showing factors as nodes, values as branches, and interactions as connections.\n\n## The Concept\n\nA spatial visualization where each factor is a node sized by its eta-squared contribution. Values within each factor extend as branches (or sub-nodes) colored by their contribution to variation. The analyst's current filter path highlights as a trail through the map. Factor-by-factor interactions show as connecting lines between nodes, with line thickness indicating interaction strength.\n\nThe factor map addresses several limitations simultaneously. It provides a **spatial overview** of the entire factor landscape at a glance, making interactions visible before drilling, removing the imposed sequence of one-factor-at-a-time analysis, and eliminating the screen space competition between filter state and chart content (the map opens in a separate panel or view).\n\nThe visualization draws on network graph conventions: force-directed layout positions related factors closer together, node size communicates importance, and edge thickness communicates relationship strength. The analyst can click a node to apply a filter (equivalent to clicking a boxplot bar) or click an edge to explore the interaction between two factors.\n\nThe implementation complexity is significant. Force-directed graph layouts require a physics engine (d3-force or similar), and the visual needs to be readable for both 3-factor and 8-factor datasets. The interaction edges require pre-computation of all pairwise interaction eta-squared values (the same calculation as the interaction heatmap). The resulting visualization must be intuitive to analysts who aren't familiar with network graphs.\n\n## Tensions Addressed\n\n- [Hierarchy Assumption](../tensions/hierarchy-assumption.md) --- Interaction edges make factor-pair relationships visible without sequential drilling.\n- [Discoverability](../tensions/discoverability.md) --- The map could serve as an alternative entry point to the boxplot click. A visible, spatial overview invites exploration.\n- [Factor Ordering](../tensions/factor-ordering.md) --- No imposed sequence. The analyst can click any node in any order. Node size naturally suggests where to start.\n- [Path Dependency](../tensions/path-dependency.md) --- The spatial layout shows all factors simultaneously. The analyst's path is a highlighted trail, not the only way to navigate.\n- [Mobile Screen Budget](../tensions/mobile-screen-budget.md) --- The map opens in a separate view, decoupling filter state from chart space.\n\n## Philosophy Alignment\n\n- **EDA for process improvement**: Strongly aligned. A spatial overview of the factor landscape is pure EDA --- the analyst reads visual patterns (big nodes, thick edges, clusters) to guide investigation.\n- **Guided frustration pedagogy**: Compatible. The map presents the factor landscape without solving it. The analyst still needs to decide where to drill and interpret what they find. The spatial overview adds context without providing answers.\n- **Four Lenses coordination**: Extends. The factor map could be considered a \"strategy view\" that complements the \"tactical\" lens views. Click a factor in the map, and the four charts update to show that factor's details.\n- **Two Voices**: Neutral to positive. The map could encode customer-voice information (e.g., color nodes red when the filtered Cpk drops below 1.0) alongside process-voice information (node size = eta-squared).\n\n## Persona Impact\n\n| Persona | Effect | Why |\n| --------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | Positive | Gary gains a visual overview that matches how he thinks about process factors --- as a connected system, not a flat list. |\n| Student Sara | Positive | Sara sees factor relationships spatially, which is more intuitive than numerical eta-squared values. The map is a teaching tool that shows \"the shape of the problem.\" |\n| OpEx Olivia | Positive | Olivia can use the map in presentations to show stakeholders the factor landscape and justify improvement priorities. Visual impact for non-technical audiences. |\n| Trainer Tina | Positive | Tina can project the map and guide the class through it: \"See this big node? That's where the variation is. See this thick line? Those factors interact.\" |\n| Evaluator Erik | Neutral | Adds to the feature comparison against competitors. Network visualization is a differentiating capability. |\n| Curious Carlos | Positive | Carlos finds spatial visualizations engaging. The map invites clicking and exploring, matching his curiosity-driven approach. |\n\n## Platform Fit\n\n| Platform | Fit | Notes |\n| ------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------- |\n| PWA (free training) | Good | Excellent teaching tool. Force-directed layout works well in browser. The PWA's exploration-first mission aligns with the map's spatial overview. |\n| Azure (paid team) | Good | Professional teams benefit from the strategic overview. Integration with the four-chart dashboard creates a powerful analysis workspace. |\n| Excel Add-in | Poor | The content pane's fixed dimensions and slicer-based workflow don't support network visualization. The map is fundamentally a web-native pattern. |\n\n## Competitive Landscape\n\n- **No direct competitor implements this for factor analysis.** Network graphs are used in social network analysis, dependency mapping, and knowledge graphs, but not as an entry point for variation analysis. A factor map would be a genuine innovation in the SPC/EDA tool space.\n- **JMP**: Graph Builder is chart-centric — it builds scatterplots, bar charts, and histograms, not network visualizations. There is no spatial overview of factor relationships or interaction networks. The closest JMP feature is the Scatterplot Matrix, which shows pairwise variable relationships in a grid, but this is a pairwise chart layout, not a connected network showing interaction strength. See [JMP Benchmark](../competitive/jmp-benchmark.md).\n- **Minitab**: No spatial factor overview. Minitab's navigation model is menu-and-dialog — the analyst selects an analysis type and configures it. There is no visualization that shows the entire factor landscape and its internal relationships at a glance. Multi-vari charts show factors on axes but not as a connected network. See [Minitab Benchmark](../competitive/minitab-benchmark.md).\n- **Tableau**: Network visualization requires third-party custom extensions (e.g., from the Tableau Exchange). These extensions are designed for social network and dependency mapping, not for statistical factor analysis. There is no integration between network visuals and SPC calculations. See [Tableau Benchmark](../competitive/tableau-benchmark.md).\n\nA factor map would be a genuine innovation --- a visualization pattern that no SPC or EDA tool currently offers. The risk is that it's innovative enough to be confusing for users who expect traditional chart layouts.\n\n## Strategic Verdict\n\n**Defer** --- The factor map is the most ambitious pattern in this evaluation. It addresses the most tensions simultaneously and would be a genuine differentiator. But the implementation complexity (force-directed layout, interaction pre-computation, intuitive interaction design) and the user education requirement (teaching analysts to read a network graph) make it a Phase 3 feature. Build factor suggestion and interaction heatmap first to establish the \"guided drill-down\" foundation, then introduce the factor map as an advanced overview for power users.", + "src/content/docs/01-vision/evaluations/patterns/factor-map.md", + "9c957fbc23abf1b9", + { "html": 12684, "metadata": 12685 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"factor-map\">Factor Map\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#factor-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Factor Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>A network visualization of the factor landscape showing factors as nodes, values as branches, and interactions as connections.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-concept\">The Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A spatial visualization where each factor is a node sized by its eta-squared contribution. Values within each factor extend as branches (or sub-nodes) colored by their contribution to variation. The analyst’s current filter path highlights as a trail through the map. Factor-by-factor interactions show as connecting lines between nodes, with line thickness indicating interaction strength.\u003C/p>\n\u003Cp>The factor map addresses several limitations simultaneously. It provides a \u003Cstrong>spatial overview\u003C/strong> of the entire factor landscape at a glance, making interactions visible before drilling, removing the imposed sequence of one-factor-at-a-time analysis, and eliminating the screen space competition between filter state and chart content (the map opens in a separate panel or view).\u003C/p>\n\u003Cp>The visualization draws on network graph conventions: force-directed layout positions related factors closer together, node size communicates importance, and edge thickness communicates relationship strength. The analyst can click a node to apply a filter (equivalent to clicking a boxplot bar) or click an edge to explore the interaction between two factors.\u003C/p>\n\u003Cp>The implementation complexity is significant. Force-directed graph layouts require a physics engine (d3-force or similar), and the visual needs to be readable for both 3-factor and 8-factor datasets. The interaction edges require pre-computation of all pairwise interaction eta-squared values (the same calculation as the interaction heatmap). The resulting visualization must be intuitive to analysts who aren’t familiar with network graphs.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tensions-addressed\">Tensions Addressed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tensions-addressed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tensions Addressed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../tensions/hierarchy-assumption.md\">Hierarchy Assumption\u003C/a> --- Interaction edges make factor-pair relationships visible without sequential drilling.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/discoverability.md\">Discoverability\u003C/a> --- The map could serve as an alternative entry point to the boxplot click. A visible, spatial overview invites exploration.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/factor-ordering.md\">Factor Ordering\u003C/a> --- No imposed sequence. The analyst can click any node in any order. Node size naturally suggests where to start.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/path-dependency.md\">Path Dependency\u003C/a> --- The spatial layout shows all factors simultaneously. The analyst’s path is a highlighted trail, not the only way to navigate.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/mobile-screen-budget.md\">Mobile Screen Budget\u003C/a> --- The map opens in a separate view, decoupling filter state from chart space.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy-alignment\">Philosophy Alignment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>EDA for process improvement\u003C/strong>: Strongly aligned. A spatial overview of the factor landscape is pure EDA --- the analyst reads visual patterns (big nodes, thick edges, clusters) to guide investigation.\u003C/li>\n\u003Cli>\u003Cstrong>Guided frustration pedagogy\u003C/strong>: Compatible. The map presents the factor landscape without solving it. The analyst still needs to decide where to drill and interpret what they find. The spatial overview adds context without providing answers.\u003C/li>\n\u003Cli>\u003Cstrong>Four Lenses coordination\u003C/strong>: Extends. The factor map could be considered a “strategy view” that complements the “tactical” lens views. Click a factor in the map, and the four charts update to show that factor’s details.\u003C/li>\n\u003Cli>\u003Cstrong>Two Voices\u003C/strong>: Neutral to positive. The map could encode customer-voice information (e.g., color nodes red when the filtered Cpk drops below 1.0) alongside process-voice information (node size = eta-squared).\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Effect\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Gary gains a visual overview that matches how he thinks about process factors --- as a connected system, not a flat list.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Sara sees factor relationships spatially, which is more intuitive than numerical eta-squared values. The map is a teaching tool that shows “the shape of the problem.”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Olivia can use the map in presentations to show stakeholders the factor landscape and justify improvement priorities. Visual impact for non-technical audiences.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Tina can project the map and guide the class through it: “See this big node? That’s where the variation is. See this thick line? Those factors interact.”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Adds to the feature comparison against competitors. Network visualization is a differentiating capability.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Carlos finds spatial visualizations engaging. The map invites clicking and exploring, matching his curiosity-driven approach.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Fit\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA (free training)\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Excellent teaching tool. Force-directed layout works well in browser. The PWA’s exploration-first mission aligns with the map’s spatial overview.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure (paid team)\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Professional teams benefit from the strategic overview. Integration with the four-chart dashboard creates a powerful analysis workspace.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel Add-in\u003C/td>\u003Ctd>Poor\u003C/td>\u003Ctd>The content pane’s fixed dimensions and slicer-based workflow don’t support network visualization. The map is fundamentally a web-native pattern.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-landscape\">Competitive Landscape\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-landscape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Landscape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>No direct competitor implements this for factor analysis.\u003C/strong> Network graphs are used in social network analysis, dependency mapping, and knowledge graphs, but not as an entry point for variation analysis. A factor map would be a genuine innovation in the SPC/EDA tool space.\u003C/li>\n\u003Cli>\u003Cstrong>JMP\u003C/strong>: Graph Builder is chart-centric — it builds scatterplots, bar charts, and histograms, not network visualizations. There is no spatial overview of factor relationships or interaction networks. The closest JMP feature is the Scatterplot Matrix, which shows pairwise variable relationships in a grid, but this is a pairwise chart layout, not a connected network showing interaction strength. See \u003Ca href=\"../competitive/jmp-benchmark.md\">JMP Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Minitab\u003C/strong>: No spatial factor overview. Minitab’s navigation model is menu-and-dialog — the analyst selects an analysis type and configures it. There is no visualization that shows the entire factor landscape and its internal relationships at a glance. Multi-vari charts show factors on axes but not as a connected network. See \u003Ca href=\"../competitive/minitab-benchmark.md\">Minitab Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Tableau\u003C/strong>: Network visualization requires third-party custom extensions (e.g., from the Tableau Exchange). These extensions are designed for social network and dependency mapping, not for statistical factor analysis. There is no integration between network visuals and SPC calculations. See \u003Ca href=\"../competitive/tableau-benchmark.md\">Tableau Benchmark\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>A factor map would be a genuine innovation --- a visualization pattern that no SPC or EDA tool currently offers. The risk is that it’s innovative enough to be confusing for users who expect traditional chart layouts.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-verdict\">Strategic Verdict\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-verdict\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Verdict”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Defer\u003C/strong> --- The factor map is the most ambitious pattern in this evaluation. It addresses the most tensions simultaneously and would be a genuine differentiator. But the implementation complexity (force-directed layout, interaction pre-computation, intuitive interaction design) and the user education requirement (teaching analysts to read a network graph) make it a Phase 3 feature. Build factor suggestion and interaction heatmap first to establish the “guided drill-down” foundation, then introduce the factor map as an advanced overview for power users.\u003C/p>", + { + "headings": 12686, + "localImagePaths": 12696, + "remoteImagePaths": 12697, + "frontmatter": 12698, + "imagePaths": 12699 + }, + [12687, 12689, 12690, 12691, 12692, 12693, 12694, 12695], + { "depth": 30, "slug": 12688, "text": 12676 }, + "factor-map", + { "depth": 33, "slug": 12653, "text": 12654 }, + { "depth": 33, "slug": 12656, "text": 12657 }, + { "depth": 33, "slug": 12659, "text": 12660 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + { "depth": 33, "slug": 2523, "text": 2524 }, + { "depth": 33, "slug": 12667, "text": 12668 }, + [], + [], + { "title": 12676 }, + [], + "01-vision/evaluations/patterns/factor-suggestion", + { + "id": 12700, + "data": 12702, + "body": 12707, + "filePath": 12708, + "digest": 12709, + "rendered": 12710 + }, + { + "title": 12703, + "editUrl": 16, + "head": 12704, + "template": 18, + "sidebar": 12705, + "pagefind": 16, + "draft": 20 + }, + "Factor Suggestion", + [], + { "hidden": 20, "attrs": 12706 }, + {}, + "# Factor Suggestion\n\n> After each filter, highlight the next highest-impact factor to reduce analyst guesswork.\n\n## The Concept\n\nAfter each drill-down step, the system would highlight the recommended next factor: \"Try Machine next --- explains 45% of remaining variation.\" This makes the implicit suggestion of eta-squared values into an explicit, actionable prompt. The recommendation would appear near the boxplot or in the variation funnel, positioned as a suggestion rather than a directive.\n\nThe simplest implementation is a visual emphasis on the highest-eta-squared bar in the boxplot after each filter is applied --- a subtle glow, a \"suggested\" label, or a ranking indicator. A more aggressive version would display a banner or inline prompt: \"Machine explains the most remaining variation. Drill here?\" The suggestion would update dynamically as filters change.\n\nThe core tension is between guidance and autonomy. The Sock Mystery pedagogy depends on the analyst's own curiosity driving the investigation. If the system always suggests the next step, the analyst stops thinking about which factor matters and follows prompts instead. The learning value of progressive stratification is partly in the _decision_ of what to drill next, not just the drilling itself. A factor suggestion that's too prominent converts an exploration tool into a wizard.\n\n## Tensions Addressed\n\n- [Factor Ordering](../tensions/factor-ordering.md) --- Directly resolves the \"which factor next?\" decision for novices.\n- [Discoverability](../tensions/discoverability.md) --- Suggestions could guide first-time users toward the drill-down workflow.\n- [When to Stop](../tensions/when-to-stop.md) --- Could be extended to include stopping suggestions (\"Remaining variation is dispersed --- consider acting on current findings\").\n\n## Philosophy Alignment\n\n- **EDA for process improvement**: Partially aligned. Suggestions accelerate the exploration but risk making it feel less exploratory. The analyst is still seeing patterns and making decisions, just with a recommendation overlay.\n- **Guided frustration pedagogy**: Conflicts if too prominent. The Sock Mystery works because the analyst struggles before discovering patterns. Immediate suggestions short-circuit the productive struggle. A toggle or progressive disclosure (suggestions appear after inactivity or on request) would preserve pedagogy.\n- **Four Lenses coordination**: Neutral. Suggestions don't affect how the four charts coordinate during filtering.\n- **Two Voices**: Neutral. Factor suggestions address process-voice exploration; the Value lens still provides the customer-voice check independently.\n\n## Persona Impact\n\n| Persona | Effect | Why |\n| --------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| Green Belt Gary | Positive | Gary benefits from confirmation that his factor choice is statistically sound. The suggestion validates his instinct or redirects him efficiently. |\n| Student Sara | Positive (with caution) | Sara learns faster with guidance, but risks becoming dependent on suggestions rather than developing her own analytical judgment. An optional mode is ideal. |\n| OpEx Olivia | Positive | Olivia's team gets more consistent results when guided. Less variance in analysis quality across different analysts. |\n| Trainer Tina | Neutral | Tina wants the option to disable suggestions during training exercises. If it's a toggle, she's happy; if it's always-on, it undermines her teaching. |\n| Evaluator Erik | Neutral | Doesn't affect Erik's evaluation criteria. |\n| Curious Carlos | Positive | Carlos doesn't know statistics. Suggestions help him make better choices without requiring training. |\n\n## Platform Fit\n\n| Platform | Fit | Notes |\n| ------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------- |\n| PWA (free training) | Good | Ideal for the training audience. Could be always-on for PWA since the audience is learners. |\n| Azure (paid team) | Good | Professional teams benefit from guided workflows. Should be toggleable for experienced users. |\n| Excel Add-in | Poor | The Excel Add-in uses native slicers for filtering, not the drill-down workflow. Factor suggestions don't fit the slicer interaction model. |\n\n## Competitive Landscape\n\n- **Minitab**: The Assistant feature uses a decision-tree approach to suggest which statistical test to run (e.g., \"use a 2-sample t-test\"), but it is hypothesis-driven menu guidance — the analyst must already have a question in mind. The Assistant does not suggest drill-down order or factor investigation sequence. It directs the analyst to the right menu item, not through an iterative investigation. See [Minitab Benchmark](../competitive/minitab-benchmark.md).\n- **JMP**: Graph Builder surfaces visual patterns that the analyst interprets — dragging variables onto shelves reveals correlations and distributions interactively. This is the closest major tool to EDA-style exploration guidance, but the analyst must take initiative to try different variable combinations. JMP does not suggest which factor to examine next; the Effect Summary in Fit Model ranks factors by significance, but only after a model has been fitted. See [JMP Benchmark](../competitive/jmp-benchmark.md).\n- **Tableau**: No concept of suggested filter order. Dashboards present all filters equally through sidebar controls — the analyst applies filters based on their own domain knowledge. Tableau is designed for known-structure dashboards, not investigation workflows where the tool guides the analyst toward the most impactful factor. See [Tableau Benchmark](../competitive/tableau-benchmark.md).\n- **Power BI**: Same paradigm as Tableau. Slicers present all filter options without ranking or suggestion. The Key Influencers visual performs automated factor analysis using ML, but it produces a static report visual rather than guiding an interactive investigation sequence. See [Power BI Benchmark](../competitive/powerbi-benchmark.md).\n- **EDAScout**: Smart Cards and a \"Socratic Analyst\" chatbot sidebar (Gemini 2.0 Flash) suggest next factors via AI dialogue. Added in v6, completely rolled back in v7, restored in v9. Their approach is AI-mediated (the model tells you what to try) rather than statistically transparent (showing eta-squared and letting the analyst decide). The v6-to-v7 rollback --- and subsequent v9 restoration with audit instrumentation --- suggests AI-driven factor suggestion is harder to get right than it appears. See [EDAScout Benchmark](../competitive/edascout-benchmark.md) for details.\n\nVariScout's version would be unique in suggesting factor order within an EDA workflow. The differentiation is the combination of statistical recommendation (eta-squared ranking) with the progressive stratification methodology. Unlike EDAScout's AI-mediated approach, VariScout's factor suggestion would be grounded in transparent statistics that the analyst can verify and learn from.\n\n## Strategic Verdict\n\n**Pursue** --- Factor suggestion addresses the highest-frequency pain point (factor ordering) with low implementation complexity. The key constraint is making it optional or unobtrusive enough to preserve the exploratory character. A subtle visual emphasis on the highest-eta-squared bar is a low-risk starting point; an explicit prompt is a higher-risk, higher-reward next step.", + "src/content/docs/01-vision/evaluations/patterns/factor-suggestion.md", + "c7572cd8038bbdb4", + { "html": 12711, "metadata": 12712 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"factor-suggestion\">Factor Suggestion\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#factor-suggestion\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Factor Suggestion”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>After each filter, highlight the next highest-impact factor to reduce analyst guesswork.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-concept\">The Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After each drill-down step, the system would highlight the recommended next factor: “Try Machine next --- explains 45% of remaining variation.” This makes the implicit suggestion of eta-squared values into an explicit, actionable prompt. The recommendation would appear near the boxplot or in the variation funnel, positioned as a suggestion rather than a directive.\u003C/p>\n\u003Cp>The simplest implementation is a visual emphasis on the highest-eta-squared bar in the boxplot after each filter is applied --- a subtle glow, a “suggested” label, or a ranking indicator. A more aggressive version would display a banner or inline prompt: “Machine explains the most remaining variation. Drill here?” The suggestion would update dynamically as filters change.\u003C/p>\n\u003Cp>The core tension is between guidance and autonomy. The Sock Mystery pedagogy depends on the analyst’s own curiosity driving the investigation. If the system always suggests the next step, the analyst stops thinking about which factor matters and follows prompts instead. The learning value of progressive stratification is partly in the \u003Cem>decision\u003C/em> of what to drill next, not just the drilling itself. A factor suggestion that’s too prominent converts an exploration tool into a wizard.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tensions-addressed\">Tensions Addressed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tensions-addressed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tensions Addressed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../tensions/factor-ordering.md\">Factor Ordering\u003C/a> --- Directly resolves the “which factor next?” decision for novices.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/discoverability.md\">Discoverability\u003C/a> --- Suggestions could guide first-time users toward the drill-down workflow.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/when-to-stop.md\">When to Stop\u003C/a> --- Could be extended to include stopping suggestions (“Remaining variation is dispersed --- consider acting on current findings”).\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy-alignment\">Philosophy Alignment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>EDA for process improvement\u003C/strong>: Partially aligned. Suggestions accelerate the exploration but risk making it feel less exploratory. The analyst is still seeing patterns and making decisions, just with a recommendation overlay.\u003C/li>\n\u003Cli>\u003Cstrong>Guided frustration pedagogy\u003C/strong>: Conflicts if too prominent. The Sock Mystery works because the analyst struggles before discovering patterns. Immediate suggestions short-circuit the productive struggle. A toggle or progressive disclosure (suggestions appear after inactivity or on request) would preserve pedagogy.\u003C/li>\n\u003Cli>\u003Cstrong>Four Lenses coordination\u003C/strong>: Neutral. Suggestions don’t affect how the four charts coordinate during filtering.\u003C/li>\n\u003Cli>\u003Cstrong>Two Voices\u003C/strong>: Neutral. Factor suggestions address process-voice exploration; the Value lens still provides the customer-voice check independently.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Effect\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Gary benefits from confirmation that his factor choice is statistically sound. The suggestion validates his instinct or redirects him efficiently.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>Positive (with caution)\u003C/td>\u003Ctd>Sara learns faster with guidance, but risks becoming dependent on suggestions rather than developing her own analytical judgment. An optional mode is ideal.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Olivia’s team gets more consistent results when guided. Less variance in analysis quality across different analysts.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Tina wants the option to disable suggestions during training exercises. If it’s a toggle, she’s happy; if it’s always-on, it undermines her teaching.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Doesn’t affect Erik’s evaluation criteria.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Carlos doesn’t know statistics. Suggestions help him make better choices without requiring training.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Fit\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA (free training)\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Ideal for the training audience. Could be always-on for PWA since the audience is learners.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure (paid team)\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Professional teams benefit from guided workflows. Should be toggleable for experienced users.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel Add-in\u003C/td>\u003Ctd>Poor\u003C/td>\u003Ctd>The Excel Add-in uses native slicers for filtering, not the drill-down workflow. Factor suggestions don’t fit the slicer interaction model.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-landscape\">Competitive Landscape\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-landscape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Landscape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Minitab\u003C/strong>: The Assistant feature uses a decision-tree approach to suggest which statistical test to run (e.g., “use a 2-sample t-test”), but it is hypothesis-driven menu guidance — the analyst must already have a question in mind. The Assistant does not suggest drill-down order or factor investigation sequence. It directs the analyst to the right menu item, not through an iterative investigation. See \u003Ca href=\"../competitive/minitab-benchmark.md\">Minitab Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>JMP\u003C/strong>: Graph Builder surfaces visual patterns that the analyst interprets — dragging variables onto shelves reveals correlations and distributions interactively. This is the closest major tool to EDA-style exploration guidance, but the analyst must take initiative to try different variable combinations. JMP does not suggest which factor to examine next; the Effect Summary in Fit Model ranks factors by significance, but only after a model has been fitted. See \u003Ca href=\"../competitive/jmp-benchmark.md\">JMP Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Tableau\u003C/strong>: No concept of suggested filter order. Dashboards present all filters equally through sidebar controls — the analyst applies filters based on their own domain knowledge. Tableau is designed for known-structure dashboards, not investigation workflows where the tool guides the analyst toward the most impactful factor. See \u003Ca href=\"../competitive/tableau-benchmark.md\">Tableau Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Power BI\u003C/strong>: Same paradigm as Tableau. Slicers present all filter options without ranking or suggestion. The Key Influencers visual performs automated factor analysis using ML, but it produces a static report visual rather than guiding an interactive investigation sequence. See \u003Ca href=\"../competitive/powerbi-benchmark.md\">Power BI Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>EDAScout\u003C/strong>: Smart Cards and a “Socratic Analyst” chatbot sidebar (Gemini 2.0 Flash) suggest next factors via AI dialogue. Added in v6, completely rolled back in v7, restored in v9. Their approach is AI-mediated (the model tells you what to try) rather than statistically transparent (showing eta-squared and letting the analyst decide). The v6-to-v7 rollback --- and subsequent v9 restoration with audit instrumentation --- suggests AI-driven factor suggestion is harder to get right than it appears. See \u003Ca href=\"../competitive/edascout-benchmark.md\">EDAScout Benchmark\u003C/a> for details.\u003C/li>\n\u003C/ul>\n\u003Cp>VariScout’s version would be unique in suggesting factor order within an EDA workflow. The differentiation is the combination of statistical recommendation (eta-squared ranking) with the progressive stratification methodology. Unlike EDAScout’s AI-mediated approach, VariScout’s factor suggestion would be grounded in transparent statistics that the analyst can verify and learn from.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-verdict\">Strategic Verdict\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-verdict\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Verdict”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Pursue\u003C/strong> --- Factor suggestion addresses the highest-frequency pain point (factor ordering) with low implementation complexity. The key constraint is making it optional or unobtrusive enough to preserve the exploratory character. A subtle visual emphasis on the highest-eta-squared bar is a low-risk starting point; an explicit prompt is a higher-risk, higher-reward next step.\u003C/p>", + { + "headings": 12713, + "localImagePaths": 12723, + "remoteImagePaths": 12724, + "frontmatter": 12725, + "imagePaths": 12726 + }, + [12714, 12716, 12717, 12718, 12719, 12720, 12721, 12722], + { "depth": 30, "slug": 12715, "text": 12703 }, + "factor-suggestion", + { "depth": 33, "slug": 12653, "text": 12654 }, + { "depth": 33, "slug": 12656, "text": 12657 }, + { "depth": 33, "slug": 12659, "text": 12660 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + { "depth": 33, "slug": 2523, "text": 2524 }, + { "depth": 33, "slug": 12667, "text": 12668 }, + [], + [], + { "title": 12703 }, + [], + "01-vision/evaluations/patterns/interaction-heatmap", + { + "id": 12727, + "data": 12729, + "body": 12734, + "filePath": 12735, + "digest": 12736, + "rendered": 12737 + }, + { + "title": 12730, + "editUrl": 16, + "head": 12731, + "template": 18, + "sidebar": 12732, + "pagefind": 16, + "draft": 20 + }, + "Interaction Heatmap", + [], + { "hidden": 20, "attrs": 12733 }, + {}, + "# Interaction Heatmap\n\n> A small matrix visualization showing factor-by-factor interaction strength before drilling.\n\n## The Concept\n\nA compact heatmap where rows and columns represent factors and cells are colored by interaction eta-squared (the variation explained by the combination beyond what the individual factors explain separately). The heatmap would sit alongside or below the Boxplot, providing a \"pre-flight check\" before the analyst commits to a drill path.\n\nA bright cell at the Machine x Shift intersection says: \"These two factors interact strongly --- drilling one without the other will miss the pattern.\" The analyst can then choose to explore both factors together (using multi-select) or drill one knowing that the interaction exists and should be investigated.\n\nThe implementation leverages the existing regression engine in `@variscout/core`, which already calculates interaction terms. The heatmap would request a quick interaction scan across all factor pairs when data is loaded or when a new factor filter is applied. For datasets with few factors (2--4), this is computationally trivial. For datasets with many factors (8+), it would need to be calculated on demand or limited to top-N factors by main-effect eta-squared.\n\nThe UI footprint is small: a 4x4 grid of colored cells with factor labels takes roughly the space of a single boxplot bar's height. It's supplementary information, not a replacement for the boxplot-driven drill-down. The heatmap answers \"are there interactions I should know about?\" while the boxplot answers \"which factor has the biggest main effect?\"\n\n## Tensions Addressed\n\n- [Hierarchy Assumption](../tensions/hierarchy-assumption.md) --- Directly addresses interaction blindness by making interactions visible before drilling.\n- [Factor Ordering](../tensions/factor-ordering.md) --- Strong interaction cells suggest factor pairs that should be explored together, informing drill order.\n\n## Philosophy Alignment\n\n- **EDA for process improvement**: Strongly aligned. A heatmap is a visual summary --- the analyst reads patterns from color, not p-values. It adds another lens to the investigation.\n- **Guided frustration pedagogy**: Compatible. The heatmap doesn't solve the problem for the analyst; it adds information that the analyst must interpret and act on. The \"frustration\" of interpreting interaction patterns is productive.\n- **Four Lenses coordination**: Extends naturally. The heatmap could be considered a fifth lens or a \"meta-lens\" that shows relationships between factors rather than individual factor effects.\n- **Two Voices**: Neutral. Interactions are process-voice phenomena; the customer-voice check still happens in the Capability lens.\n\n## Persona Impact\n\n| Persona | Effect | Why |\n| --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | Positive | Gary learned about interactions in training. The heatmap makes abstract concepts concrete and visible. |\n| Student Sara | Positive | Sara sees interaction patterns visually before learning the math. The heatmap teaches by showing, not explaining. |\n| OpEx Olivia | Positive | Olivia's team catches interaction effects that sequential drilling misses. More thorough analyses, better improvement projects. |\n| Trainer Tina | Positive | Tina can use the heatmap as a teaching tool: \"See this bright cell? That means Machine and Shift interact. Let's explore why.\" |\n| Evaluator Erik | Neutral | Doesn't affect Erik's evaluation criteria, but adds to the feature list for competitive comparison. |\n| Curious Carlos | Neutral | Carlos may not understand what interaction means, but the colored grid is visually engaging and may prompt curiosity. |\n\n## Platform Fit\n\n| Platform | Fit | Notes |\n| ------------------- | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| PWA (free training) | Good | Excellent teaching tool. Small UI footprint fits the training context. |\n| Azure (paid team) | Good | Professional feature for thorough analyses. Fits naturally alongside existing charts. |\n| Excel Add-in | Poor | The content pane's dark-theme chart space could accommodate a heatmap, but the slicer-based workflow doesn't create the \"before drilling\" moment where the heatmap is most useful. |\n\n## Competitive Landscape\n\n- **JMP**: The Fit Model platform supports interaction terms, and the Interaction Profiler visualizes two-factor interaction surfaces after a model is fitted. Scatterplot matrices and correlation matrices are available in separate platforms for pairwise exploration. However, none of these are integrated into an exploratory drill-down workflow — the analyst must navigate to specific platforms and specify model terms manually. Interaction detection is powerful but requires model-first analysis. See [JMP Benchmark](../competitive/jmp-benchmark.md).\n- **Minitab**: Multi-vari charts are a purpose-built chart type designed to visualize factor interactions across multiple levels simultaneously. They are accessed through menus (Quality Tools > Multi-Vari Chart) as a separate analysis step — the analyst must know to run this analysis and select the right factors. Multi-vari charts are not an inline pre-flight check before drilling; they are a standalone analysis that requires prior knowledge of which factors to examine. See [Minitab Benchmark](../competitive/minitab-benchmark.md).\n- **Tableau**: No interaction detection capability. Calculated fields using LOD (Level of Detail) expressions can approximate interaction effects, but this requires advanced Tableau expertise and produces custom measures rather than interactive visualizations. The vast majority of Tableau users have no way to detect or visualize factor interactions. See [Tableau Benchmark](../competitive/tableau-benchmark.md).\n- **Power BI**: No interaction detection capability. DAX formulas can compute interaction terms, but this requires expert authoring and produces static measures. The Key Influencers visual identifies main effects but does not detect or visualize interactions between factors. See [Power BI Benchmark](../competitive/powerbi-benchmark.md).\n- **EDAScout**: No interaction detection. Their ANOVA implementation is single-factor only --- the `SubgroupExplorerModal` examines one grouping variable at a time. The `CategoryGrid` variance coloring uses within-group SS (how noisy each group is internally), not between-group or interaction effects. An analyst investigating a Machine x Shift interaction would need to manually create the combination. See [EDAScout Benchmark](../competitive/edascout-benchmark.md).\n\nVariScout's version would be unique in integrating interaction detection directly into the drill-down workflow as a compact, visual pre-flight check. The differentiation: proactive interaction visibility rather than reactive analysis. No competitor, including EDAScout, addresses interaction effects inline during investigation.\n\n## Strategic Verdict\n\n**Pursue** --- Addresses a high-weight tension (hierarchy assumption) with moderate implementation complexity. The regression engine already exists; the work is primarily UI. The heatmap adds analytical depth without disrupting the existing workflow --- it's additive, not alternative. Ideal as a Phase 2 feature after factor suggestion establishes the \"guided drill-down\" pattern.", + "src/content/docs/01-vision/evaluations/patterns/interaction-heatmap.md", + "853443e57665b841", + { "html": 12738, "metadata": 12739 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"interaction-heatmap\">Interaction Heatmap\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#interaction-heatmap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interaction Heatmap”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>A small matrix visualization showing factor-by-factor interaction strength before drilling.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-concept\">The Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A compact heatmap where rows and columns represent factors and cells are colored by interaction eta-squared (the variation explained by the combination beyond what the individual factors explain separately). The heatmap would sit alongside or below the Boxplot, providing a “pre-flight check” before the analyst commits to a drill path.\u003C/p>\n\u003Cp>A bright cell at the Machine x Shift intersection says: “These two factors interact strongly --- drilling one without the other will miss the pattern.” The analyst can then choose to explore both factors together (using multi-select) or drill one knowing that the interaction exists and should be investigated.\u003C/p>\n\u003Cp>The implementation leverages the existing regression engine in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>, which already calculates interaction terms. The heatmap would request a quick interaction scan across all factor pairs when data is loaded or when a new factor filter is applied. For datasets with few factors (2—4), this is computationally trivial. For datasets with many factors (8+), it would need to be calculated on demand or limited to top-N factors by main-effect eta-squared.\u003C/p>\n\u003Cp>The UI footprint is small: a 4x4 grid of colored cells with factor labels takes roughly the space of a single boxplot bar’s height. It’s supplementary information, not a replacement for the boxplot-driven drill-down. The heatmap answers “are there interactions I should know about?” while the boxplot answers “which factor has the biggest main effect?”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tensions-addressed\">Tensions Addressed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tensions-addressed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tensions Addressed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../tensions/hierarchy-assumption.md\">Hierarchy Assumption\u003C/a> --- Directly addresses interaction blindness by making interactions visible before drilling.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/factor-ordering.md\">Factor Ordering\u003C/a> --- Strong interaction cells suggest factor pairs that should be explored together, informing drill order.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy-alignment\">Philosophy Alignment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>EDA for process improvement\u003C/strong>: Strongly aligned. A heatmap is a visual summary --- the analyst reads patterns from color, not p-values. It adds another lens to the investigation.\u003C/li>\n\u003Cli>\u003Cstrong>Guided frustration pedagogy\u003C/strong>: Compatible. The heatmap doesn’t solve the problem for the analyst; it adds information that the analyst must interpret and act on. The “frustration” of interpreting interaction patterns is productive.\u003C/li>\n\u003Cli>\u003Cstrong>Four Lenses coordination\u003C/strong>: Extends naturally. The heatmap could be considered a fifth lens or a “meta-lens” that shows relationships between factors rather than individual factor effects.\u003C/li>\n\u003Cli>\u003Cstrong>Two Voices\u003C/strong>: Neutral. Interactions are process-voice phenomena; the customer-voice check still happens in the Capability lens.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Effect\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Gary learned about interactions in training. The heatmap makes abstract concepts concrete and visible.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Sara sees interaction patterns visually before learning the math. The heatmap teaches by showing, not explaining.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Olivia’s team catches interaction effects that sequential drilling misses. More thorough analyses, better improvement projects.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Tina can use the heatmap as a teaching tool: “See this bright cell? That means Machine and Shift interact. Let’s explore why.”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Doesn’t affect Erik’s evaluation criteria, but adds to the feature list for competitive comparison.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Carlos may not understand what interaction means, but the colored grid is visually engaging and may prompt curiosity.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Fit\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA (free training)\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Excellent teaching tool. Small UI footprint fits the training context.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure (paid team)\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Professional feature for thorough analyses. Fits naturally alongside existing charts.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel Add-in\u003C/td>\u003Ctd>Poor\u003C/td>\u003Ctd>The content pane’s dark-theme chart space could accommodate a heatmap, but the slicer-based workflow doesn’t create the “before drilling” moment where the heatmap is most useful.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-landscape\">Competitive Landscape\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-landscape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Landscape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>JMP\u003C/strong>: The Fit Model platform supports interaction terms, and the Interaction Profiler visualizes two-factor interaction surfaces after a model is fitted. Scatterplot matrices and correlation matrices are available in separate platforms for pairwise exploration. However, none of these are integrated into an exploratory drill-down workflow — the analyst must navigate to specific platforms and specify model terms manually. Interaction detection is powerful but requires model-first analysis. See \u003Ca href=\"../competitive/jmp-benchmark.md\">JMP Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Minitab\u003C/strong>: Multi-vari charts are a purpose-built chart type designed to visualize factor interactions across multiple levels simultaneously. They are accessed through menus (Quality Tools > Multi-Vari Chart) as a separate analysis step — the analyst must know to run this analysis and select the right factors. Multi-vari charts are not an inline pre-flight check before drilling; they are a standalone analysis that requires prior knowledge of which factors to examine. See \u003Ca href=\"../competitive/minitab-benchmark.md\">Minitab Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Tableau\u003C/strong>: No interaction detection capability. Calculated fields using LOD (Level of Detail) expressions can approximate interaction effects, but this requires advanced Tableau expertise and produces custom measures rather than interactive visualizations. The vast majority of Tableau users have no way to detect or visualize factor interactions. See \u003Ca href=\"../competitive/tableau-benchmark.md\">Tableau Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Power BI\u003C/strong>: No interaction detection capability. DAX formulas can compute interaction terms, but this requires expert authoring and produces static measures. The Key Influencers visual identifies main effects but does not detect or visualize interactions between factors. See \u003Ca href=\"../competitive/powerbi-benchmark.md\">Power BI Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>EDAScout\u003C/strong>: No interaction detection. Their ANOVA implementation is single-factor only --- the \u003Ccode dir=\"auto\">SubgroupExplorerModal\u003C/code> examines one grouping variable at a time. The \u003Ccode dir=\"auto\">CategoryGrid\u003C/code> variance coloring uses within-group SS (how noisy each group is internally), not between-group or interaction effects. An analyst investigating a Machine x Shift interaction would need to manually create the combination. See \u003Ca href=\"../competitive/edascout-benchmark.md\">EDAScout Benchmark\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>VariScout’s version would be unique in integrating interaction detection directly into the drill-down workflow as a compact, visual pre-flight check. The differentiation: proactive interaction visibility rather than reactive analysis. No competitor, including EDAScout, addresses interaction effects inline during investigation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-verdict\">Strategic Verdict\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-verdict\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Verdict”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Pursue\u003C/strong> --- Addresses a high-weight tension (hierarchy assumption) with moderate implementation complexity. The regression engine already exists; the work is primarily UI. The heatmap adds analytical depth without disrupting the existing workflow --- it’s additive, not alternative. Ideal as a Phase 2 feature after factor suggestion establishes the “guided drill-down” pattern.\u003C/p>", + { + "headings": 12740, + "localImagePaths": 12750, + "remoteImagePaths": 12751, + "frontmatter": 12752, + "imagePaths": 12753 + }, + [12741, 12743, 12744, 12745, 12746, 12747, 12748, 12749], + { "depth": 30, "slug": 12742, "text": 12730 }, + "interaction-heatmap", + { "depth": 33, "slug": 12653, "text": 12654 }, + { "depth": 33, "slug": 12656, "text": 12657 }, + { "depth": 33, "slug": 12659, "text": 12660 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + { "depth": 33, "slug": 2523, "text": 2524 }, + { "depth": 33, "slug": 12667, "text": 12668 }, + [], + [], + { "title": 12730 }, + [], + "01-vision/evaluations/patterns/investigation-mindmap", + { + "id": 12754, + "data": 12756, + "body": 12761, + "filePath": 12762, + "digest": 12763, + "rendered": 12764 + }, + { + "title": 12757, + "editUrl": 16, + "head": 12758, + "template": 18, + "sidebar": 12759, + "pagefind": 16, + "draft": 20 + }, + "Investigation Mindmap", + [], + { "hidden": 20, "attrs": 12760 }, + {}, + "# Investigation Mindmap\n\n> A two-mode companion visualization — drilldown overview and interaction view — that opens on demand in a separate window or panel, showing the investigation state as an interactive node-link diagram.\n\n## The Concept\n\nA mindmap-style visualization where categorical factors are displayed as nodes arranged radially or hierarchically from a central \"start\" node. The visualization has two switchable modes — **Drilldown Mode** and **Interaction Mode** — that show different aspects of the same factor landscape using the same spatial layout.\n\nThe mindmap opens on demand as a companion view (pop-out window, split pane, or overlay) and stays synchronized with the main dashboard. It provides a persistent spatial overview of the investigation state — something the current drill-down workflow lacks because the Four Lenses show one factor at a time while the Funnel Panel is hidden by default.\n\nThis concept refines and concretizes the [Factor Map](factor-map.md) pattern (currently \"Defer\") into a lighter-weight, two-mode design that is more immediately implementable.\n\n### Drilldown Mode\n\nIn Drilldown Mode, the mindmap shows the investigation path and remaining factors:\n\n- **All categorical factors** appear as nodes, sized proportionally to their η² (the factor explaining the most variation is the largest node).\n- **Node fill/color** encodes filter state:\n - **Active filter** (e.g., Store = South): Solid fill, bright color. The filtered value appears as a label inside or below the node.\n - **Available** (not yet filtered): Outlined, neutral. Hovering previews the η² value.\n - **Exhausted** (filtered but with negligible remaining η²): Dimmed/grayed.\n- **Drill path trail**: A highlighted path connects the nodes in drill order (Start → Store → Time_Slot), showing the investigation sequence.\n- **Suggested next node**: The factor with the highest η² among remaining (unfiltered) factors has a visual emphasis — a glow, pulse, or \"suggested\" badge. This mirrors the Phase 1 Factor Suggestion chip but in spatial form.\n- **Clicking a node** opens a mini-dropdown of that factor's values (like clicking a Boxplot bar) and applies the filter. The main dashboard updates simultaneously.\n- **Cumulative indicator**: The center node or a persistent footer shows cumulative explained variation (e.g., \"58% explained\").\n\n### Interaction Mode\n\nSwitching to Interaction Mode keeps the same factor nodes in the same positions but overlays interaction information:\n\n- **Connections between nodes** appear as edges, with thickness proportional to interaction strength (ΔR² or |standardized β| from `calculateMultipleRegression`).\n- **Edge color** encodes significance: bright (p \u003C 0.05), muted (p \u003C 0.10), absent (p ≥ 0.10).\n- **Hovering an edge** shows a tooltip with the interaction details: ΔR², standardized β, p-value, and a plain-language description (\"Store and Time_Slot interact — the Dinner rush effect is stronger at Store South\").\n- **Clicking an edge** selects both connected factors for combined analysis — equivalent to multi-selecting two factors in the Boxplot or Funnel Panel.\n- **No edges visible** is itself informative: \"Your factors don't interact significantly — the sequential drill-down captured the main effects correctly.\"\n\nThe Interaction Mode data comes from running `calculateMultipleRegression` with `includeInteractions: true` on all factor pairs. For 3 factors this is 3 pairs; for 5 factors it's 10 pairs. The scan runs on demand when the analyst switches to Interaction Mode (not on data load) to avoid unnecessary computation.\n\n### Relationship to Factor Map\n\nThe [Factor Map](factor-map.md) pattern (verdict: Defer) envisioned a comprehensive network visualization with force-directed layout, sub-nodes for factor values, and edge thickness for interaction strength. The Investigation Mindmap is a **lighter-weight realization** of the same concept:\n\n| Factor Map (Deferred) | Investigation Mindmap (This Concept) |\n| ------------------------------------ | ------------------------------------------------------- |\n| Force-directed physics layout | Fixed radial/hierarchical layout (simpler, more stable) |\n| Sub-nodes for every factor value | Values shown in tooltips/dropdowns on click |\n| Always-visible in the dashboard | Companion view opened on demand |\n| Shows all information simultaneously | Two distinct modes (drilldown / interaction) |\n| Requires d3-force physics engine | Can be built with static SVG positioning |\n\nThe mindmap trades the Factor Map's visual density for simplicity and implementability. It can be built without a physics engine and with a fraction of the interaction design work, while still addressing the same core tensions.\n\n## Tensions Addressed\n\n- [Hierarchy Assumption](../tensions/hierarchy-assumption.md) — **Primary**. Interaction Mode makes factor-pair relationships visible without requiring the analyst to navigate to the Regression Panel. The mindmap shows when the one-factor-at-a-time assumption breaks down.\n- [Discoverability](../tensions/discoverability.md) — **Secondary**. The spatial overview provides an alternative entry point to the investigation. New users can see the factor landscape at a glance rather than inferring it from the Boxplot.\n- [Factor Ordering](../tensions/factor-ordering.md) — **Primary**. Node size encodes η², making the \"which factor next?\" decision visual and intuitive. The suggested-next node provides explicit guidance.\n- [Path Dependency](../tensions/path-dependency.md) — **Secondary**. The spatial layout shows all factors simultaneously. The analyst can see that the drill path is one trail through the landscape, not the only possible route. Switching to Interaction Mode may reveal that a different path (following a strong interaction) would have been equally valid.\n- [Mobile Screen Budget](../tensions/mobile-screen-budget.md) — **Improves**. Opening the mindmap in a companion view (pop-out or split pane) separates the investigation overview from the chart space. On mobile, the mindmap could be a full-screen mode that the analyst toggles.\n\n## Philosophy Alignment\n\n- **EDA for process improvement**: Strongly aligned. The mindmap is a spatial visualization of the factor landscape — the analyst reads patterns from node size, color, and connections to guide their investigation. It extends the \"show the shape of the data\" principle from individual charts to the meta-level investigation structure.\n- **Guided frustration pedagogy**: Compatible. The mindmap presents the landscape but doesn't solve the investigation. The analyst still decides where to drill, interprets what they find, and draws conclusions. The spatial overview adds context without providing answers. The \"suggested next\" node is a hint, not a directive.\n- **Four Lenses coordination**: Extends. The Four Lenses (I-Chart, Boxplot, Pareto, Stats) show the current filter state. The mindmap shows the investigation state — where the analyst has been, where they might go next, and how factors relate to each other. It's a navigation map for the Four Lenses.\n- **Two Voices**: Neutral to positive. Drilldown Mode is entirely process-voice (η² is a process metric). Interaction Mode could incorporate customer-voice by encoding Cpk changes on interaction edges: \"Store × Time_Slot interaction reduces Cpk from 1.2 to 0.6 — this interaction matters for customer outcomes.\"\n\n## Persona Impact\n\n| Persona | Effect | Why |\n| --------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | **Positive** | Gary gains a spatial overview of the factor landscape that matches his mental model of process factors as an interconnected system. The mindmap makes his investigation explicit and reviewable — useful for project documentation and Tollgate reviews. |\n| Student Sara | **Strongly positive** | Sara learns by seeing the whole picture. The mindmap shows \"the shape of the problem\" visually — big nodes mean important factors, bright connections mean interactions. The drill trail shows her investigation history, making the learning process visible. |\n| OpEx Olivia | **Positive** | Olivia can use the mindmap to standardize investigation approaches across her team. The visual record of drill paths helps in team reviews. Interaction Mode surfaces patterns that sequential analysis might miss, improving analysis thoroughness. |\n| Trainer Tina | **Strongly positive** | Tina can project the mindmap during training: \"See these three nodes? Store is the biggest — that's where we start. Now see this connection between Store and Time_Slot? Let's explore that.\" The mindmap is a teaching canvas that shows the investigation strategy. |\n| Evaluator Erik | **Positive** | The mindmap is a differentiating feature. No competitor offers a spatial investigation overview. Erik can point to it as a unique capability in competitive comparisons. |\n| Curious Carlos | **Positive** | Carlos finds spatial, interactive visualizations engaging. The mindmap invites clicking and exploring — nodes respond to hover, connections glow, the drill trail animates. This matches Carlos's curiosity-driven approach. |\n\n## Platform Fit\n\n| Platform | Fit | Notes |\n| ------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| PWA (free training) | **Good** | Excellent teaching tool. The pop-out window model already exists (`FunnelWindow.tsx`). SVG rendering works well in all browsers. The spatial overview complements the PWA's educational mission. |\n| Azure (paid team) | **Good** | Professional teams benefit from the investigation overview. The split-pane model (mindmap beside the dashboard) is more appropriate for Azure's desktop-oriented workflow than a pop-out window. Interaction Mode is particularly valuable for team investigations of complex processes. |\n| Excel Add-in | **N/A** | The Excel Add-in uses native slicers for filtering, not the drill-down workflow. The mindmap concept doesn't apply to the slicer interaction model. |\n\n## Competitive Landscape\n\nNo competitor offers a spatial investigation overview for variation analysis. This is a genuine differentiator.\n\n- **JMP**: Graph Builder is chart-centric (scatterplots, histograms). The Scatterplot Matrix shows pairwise variable relationships in a grid layout, but it's a chart grid, not an interactive node-link diagram showing investigation state. There is no concept of visualizing the investigation path or factor relationships as a network. See [JMP Benchmark](../competitive/jmp-benchmark.md).\n- **Minitab**: No spatial overview. Minitab's navigation model is menu-and-dialog — the analyst runs analyses and reviews results in the Session Window (text log) and Graph window (individual charts). Multi-vari charts show factor level combinations but in a chart format, not a spatial map. See [Minitab Benchmark](../competitive/minitab-benchmark.md).\n- **Tableau**: Network visualizations require third-party extensions and are designed for social networks or dependency mapping, not statistical factor analysis. There is no integration with filter state or SPC calculations. See [Tableau Benchmark](../competitive/tableau-benchmark.md).\n- **Power BI**: No spatial factor overview. Decomposition Tree visual allows hierarchical drill-down but is tree-structured (enforced top-down), not a free-form spatial map where the analyst can see interactions and choose their own path. See [Power BI Benchmark](../competitive/powerbi-benchmark.md).\n- **EDAScout**: Uses a Smart Card carousel and AI chatbot for factor exploration. No spatial visualization of the factor landscape or interaction network. The investigation state is tracked conversationally, not visually. See [EDAScout Benchmark](../competitive/edascout-benchmark.md).\n\nThe Investigation Mindmap would position VariScout as the only tool that provides a spatial, interactive overview of the investigation state — combining factor importance (node size), investigation progress (drill trail), and factor interactions (edge thickness) in a single synchronized view.\n\n## Two-Mode Design\n\nThe two-mode design is deliberate. Showing drilldown state and interaction information simultaneously would overload the visualization (the [Factor Map](factor-map.md) evaluation noted this as a complexity risk). Splitting into two modes lets each mode have a clear visual hierarchy:\n\n- **Drilldown Mode**: Node size + color is the primary signal. Edges are hidden. The analyst focuses on \"where am I, where should I go next?\"\n- **Interaction Mode**: Edge thickness + color is the primary signal. Node size is secondary. The analyst focuses on \"which factors interact, and how strongly?\"\n\nA mode toggle (two buttons or a switch) at the top of the mindmap switches between modes. The transition animates the edges appearing/disappearing while nodes stay fixed, reinforcing that the same factors are being viewed through a different lens.\n\n## Window Model\n\nThe mindmap opens as a **companion view** rather than replacing the main dashboard. Three implementation options:\n\n| Model | Pros | Cons | Best For |\n| ---------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------ |\n| **Pop-out window** | Independent sizing, works alongside full dashboard, precedent exists (FunnelWindow) | Window management overhead, may be blocked by pop-up blockers | PWA (matches existing pattern) |\n| **Split pane** | Always visible alongside charts, no window management | Reduces chart space, needs responsive breakpoints | Azure (desktop-oriented) |\n| **Full-screen toggle** | Maximum space for the mindmap, clean transition | Hides the charts while viewing the mindmap | Mobile, presentations |\n\nThe recommended approach: **pop-out window as default** (reusing the `FunnelWindow.tsx` pattern), with **split pane as an Azure enhancement**. The mindmap window receives filter change events from the main dashboard and sends filter apply events back — the same bidirectional sync pattern that the FunnelWindow already implements.\n\n## Strategic Verdict\n\n**Pursue (Phase 3)** — The Investigation Mindmap addresses four of six tensions with a lighter-weight approach than the full Factor Map. It builds directly on Phase 1 (Factor Suggestion provides the η² ranking) and Phase 2 (Interaction Heatmap provides the interaction data) by combining both into a spatial view. The implementation complexity is moderate — static SVG layout, no physics engine, reuse of existing window/sync patterns. The competitive differentiation is strong: no tool offers this. The primary risk is user education (analysts unfamiliar with node-link diagrams may need onboarding), mitigated by the familiar click-to-filter interaction pattern.\n\nBuild Factor Suggestion and Interaction Heatmap first. The mindmap adds spatial context to the guidance these features provide. Without the underlying η² suggestions and interaction data, the mindmap is just a pretty picture; with them, it's a navigation instrument.", + "src/content/docs/01-vision/evaluations/patterns/investigation-mindmap.md", + "933965f402d4f326", + { "html": 12765, "metadata": 12766 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"investigation-mindmap\">Investigation Mindmap\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-mindmap\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation Mindmap”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>A two-mode companion visualization — drilldown overview and interaction view — that opens on demand in a separate window or panel, showing the investigation state as an interactive node-link diagram.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-concept\">The Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A mindmap-style visualization where categorical factors are displayed as nodes arranged radially or hierarchically from a central “start” node. The visualization has two switchable modes — \u003Cstrong>Drilldown Mode\u003C/strong> and \u003Cstrong>Interaction Mode\u003C/strong> — that show different aspects of the same factor landscape using the same spatial layout.\u003C/p>\n\u003Cp>The mindmap opens on demand as a companion view (pop-out window, split pane, or overlay) and stays synchronized with the main dashboard. It provides a persistent spatial overview of the investigation state — something the current drill-down workflow lacks because the Four Lenses show one factor at a time while the Funnel Panel is hidden by default.\u003C/p>\n\u003Cp>This concept refines and concretizes the \u003Ca href=\"factor-map.md\">Factor Map\u003C/a> pattern (currently “Defer”) into a lighter-weight, two-mode design that is more immediately implementable.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"drilldown-mode\">Drilldown Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#drilldown-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Drilldown Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>In Drilldown Mode, the mindmap shows the investigation path and remaining factors:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>All categorical factors\u003C/strong> appear as nodes, sized proportionally to their η² (the factor explaining the most variation is the largest node).\u003C/li>\n\u003Cli>\u003Cstrong>Node fill/color\u003C/strong> encodes filter state:\n\u003Cul>\n\u003Cli>\u003Cstrong>Active filter\u003C/strong> (e.g., Store = South): Solid fill, bright color. The filtered value appears as a label inside or below the node.\u003C/li>\n\u003Cli>\u003Cstrong>Available\u003C/strong> (not yet filtered): Outlined, neutral. Hovering previews the η² value.\u003C/li>\n\u003Cli>\u003Cstrong>Exhausted\u003C/strong> (filtered but with negligible remaining η²): Dimmed/grayed.\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Drill path trail\u003C/strong>: A highlighted path connects the nodes in drill order (Start → Store → Time_Slot), showing the investigation sequence.\u003C/li>\n\u003Cli>\u003Cstrong>Suggested next node\u003C/strong>: The factor with the highest η² among remaining (unfiltered) factors has a visual emphasis — a glow, pulse, or “suggested” badge. This mirrors the Phase 1 Factor Suggestion chip but in spatial form.\u003C/li>\n\u003Cli>\u003Cstrong>Clicking a node\u003C/strong> opens a mini-dropdown of that factor’s values (like clicking a Boxplot bar) and applies the filter. The main dashboard updates simultaneously.\u003C/li>\n\u003Cli>\u003Cstrong>Cumulative indicator\u003C/strong>: The center node or a persistent footer shows cumulative explained variation (e.g., “58% explained”).\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"interaction-mode\">Interaction Mode\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#interaction-mode\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Interaction Mode”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Switching to Interaction Mode keeps the same factor nodes in the same positions but overlays interaction information:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Connections between nodes\u003C/strong> appear as edges, with thickness proportional to interaction strength (ΔR² or |standardized β| from \u003Ccode dir=\"auto\">calculateMultipleRegression\u003C/code>).\u003C/li>\n\u003Cli>\u003Cstrong>Edge color\u003C/strong> encodes significance: bright (p < 0.05), muted (p < 0.10), absent (p ≥ 0.10).\u003C/li>\n\u003Cli>\u003Cstrong>Hovering an edge\u003C/strong> shows a tooltip with the interaction details: ΔR², standardized β, p-value, and a plain-language description (“Store and Time_Slot interact — the Dinner rush effect is stronger at Store South”).\u003C/li>\n\u003Cli>\u003Cstrong>Clicking an edge\u003C/strong> selects both connected factors for combined analysis — equivalent to multi-selecting two factors in the Boxplot or Funnel Panel.\u003C/li>\n\u003Cli>\u003Cstrong>No edges visible\u003C/strong> is itself informative: “Your factors don’t interact significantly — the sequential drill-down captured the main effects correctly.”\u003C/li>\n\u003C/ul>\n\u003Cp>The Interaction Mode data comes from running \u003Ccode dir=\"auto\">calculateMultipleRegression\u003C/code> with \u003Ccode dir=\"auto\">includeInteractions: true\u003C/code> on all factor pairs. For 3 factors this is 3 pairs; for 5 factors it’s 10 pairs. The scan runs on demand when the analyst switches to Interaction Mode (not on data load) to avoid unnecessary computation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"relationship-to-factor-map\">Relationship to Factor Map\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#relationship-to-factor-map\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Relationship to Factor Map”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ca href=\"factor-map.md\">Factor Map\u003C/a> pattern (verdict: Defer) envisioned a comprehensive network visualization with force-directed layout, sub-nodes for factor values, and edge thickness for interaction strength. The Investigation Mindmap is a \u003Cstrong>lighter-weight realization\u003C/strong> of the same concept:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Factor Map (Deferred)\u003C/th>\u003Cth>Investigation Mindmap (This Concept)\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Force-directed physics layout\u003C/td>\u003Ctd>Fixed radial/hierarchical layout (simpler, more stable)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sub-nodes for every factor value\u003C/td>\u003Ctd>Values shown in tooltips/dropdowns on click\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Always-visible in the dashboard\u003C/td>\u003Ctd>Companion view opened on demand\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Shows all information simultaneously\u003C/td>\u003Ctd>Two distinct modes (drilldown / interaction)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Requires d3-force physics engine\u003C/td>\u003Ctd>Can be built with static SVG positioning\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The mindmap trades the Factor Map’s visual density for simplicity and implementability. It can be built without a physics engine and with a fraction of the interaction design work, while still addressing the same core tensions.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tensions-addressed\">Tensions Addressed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tensions-addressed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tensions Addressed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../tensions/hierarchy-assumption.md\">Hierarchy Assumption\u003C/a> — \u003Cstrong>Primary\u003C/strong>. Interaction Mode makes factor-pair relationships visible without requiring the analyst to navigate to the Regression Panel. The mindmap shows when the one-factor-at-a-time assumption breaks down.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/discoverability.md\">Discoverability\u003C/a> — \u003Cstrong>Secondary\u003C/strong>. The spatial overview provides an alternative entry point to the investigation. New users can see the factor landscape at a glance rather than inferring it from the Boxplot.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/factor-ordering.md\">Factor Ordering\u003C/a> — \u003Cstrong>Primary\u003C/strong>. Node size encodes η², making the “which factor next?” decision visual and intuitive. The suggested-next node provides explicit guidance.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/path-dependency.md\">Path Dependency\u003C/a> — \u003Cstrong>Secondary\u003C/strong>. The spatial layout shows all factors simultaneously. The analyst can see that the drill path is one trail through the landscape, not the only possible route. Switching to Interaction Mode may reveal that a different path (following a strong interaction) would have been equally valid.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/mobile-screen-budget.md\">Mobile Screen Budget\u003C/a> — \u003Cstrong>Improves\u003C/strong>. Opening the mindmap in a companion view (pop-out or split pane) separates the investigation overview from the chart space. On mobile, the mindmap could be a full-screen mode that the analyst toggles.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy-alignment\">Philosophy Alignment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>EDA for process improvement\u003C/strong>: Strongly aligned. The mindmap is a spatial visualization of the factor landscape — the analyst reads patterns from node size, color, and connections to guide their investigation. It extends the “show the shape of the data” principle from individual charts to the meta-level investigation structure.\u003C/li>\n\u003Cli>\u003Cstrong>Guided frustration pedagogy\u003C/strong>: Compatible. The mindmap presents the landscape but doesn’t solve the investigation. The analyst still decides where to drill, interprets what they find, and draws conclusions. The spatial overview adds context without providing answers. The “suggested next” node is a hint, not a directive.\u003C/li>\n\u003Cli>\u003Cstrong>Four Lenses coordination\u003C/strong>: Extends. The Four Lenses (I-Chart, Boxplot, Pareto, Stats) show the current filter state. The mindmap shows the investigation state — where the analyst has been, where they might go next, and how factors relate to each other. It’s a navigation map for the Four Lenses.\u003C/li>\n\u003Cli>\u003Cstrong>Two Voices\u003C/strong>: Neutral to positive. Drilldown Mode is entirely process-voice (η² is a process metric). Interaction Mode could incorporate customer-voice by encoding Cpk changes on interaction edges: “Store × Time_Slot interaction reduces Cpk from 1.2 to 0.6 — this interaction matters for customer outcomes.”\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Effect\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>\u003Cstrong>Positive\u003C/strong>\u003C/td>\u003Ctd>Gary gains a spatial overview of the factor landscape that matches his mental model of process factors as an interconnected system. The mindmap makes his investigation explicit and reviewable — useful for project documentation and Tollgate reviews.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>\u003Cstrong>Strongly positive\u003C/strong>\u003C/td>\u003Ctd>Sara learns by seeing the whole picture. The mindmap shows “the shape of the problem” visually — big nodes mean important factors, bright connections mean interactions. The drill trail shows her investigation history, making the learning process visible.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>\u003Cstrong>Positive\u003C/strong>\u003C/td>\u003Ctd>Olivia can use the mindmap to standardize investigation approaches across her team. The visual record of drill paths helps in team reviews. Interaction Mode surfaces patterns that sequential analysis might miss, improving analysis thoroughness.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>\u003Cstrong>Strongly positive\u003C/strong>\u003C/td>\u003Ctd>Tina can project the mindmap during training: “See these three nodes? Store is the biggest — that’s where we start. Now see this connection between Store and Time_Slot? Let’s explore that.” The mindmap is a teaching canvas that shows the investigation strategy.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>\u003Cstrong>Positive\u003C/strong>\u003C/td>\u003Ctd>The mindmap is a differentiating feature. No competitor offers a spatial investigation overview. Erik can point to it as a unique capability in competitive comparisons.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>\u003Cstrong>Positive\u003C/strong>\u003C/td>\u003Ctd>Carlos finds spatial, interactive visualizations engaging. The mindmap invites clicking and exploring — nodes respond to hover, connections glow, the drill trail animates. This matches Carlos’s curiosity-driven approach.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Fit\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA (free training)\u003C/td>\u003Ctd>\u003Cstrong>Good\u003C/strong>\u003C/td>\u003Ctd>Excellent teaching tool. The pop-out window model already exists (\u003Ccode dir=\"auto\">FunnelWindow.tsx\u003C/code>). SVG rendering works well in all browsers. The spatial overview complements the PWA’s educational mission.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure (paid team)\u003C/td>\u003Ctd>\u003Cstrong>Good\u003C/strong>\u003C/td>\u003Ctd>Professional teams benefit from the investigation overview. The split-pane model (mindmap beside the dashboard) is more appropriate for Azure’s desktop-oriented workflow than a pop-out window. Interaction Mode is particularly valuable for team investigations of complex processes.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel Add-in\u003C/td>\u003Ctd>\u003Cstrong>N/A\u003C/strong>\u003C/td>\u003Ctd>The Excel Add-in uses native slicers for filtering, not the drill-down workflow. The mindmap concept doesn’t apply to the slicer interaction model.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-landscape\">Competitive Landscape\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-landscape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Landscape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>No competitor offers a spatial investigation overview for variation analysis. This is a genuine differentiator.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>JMP\u003C/strong>: Graph Builder is chart-centric (scatterplots, histograms). The Scatterplot Matrix shows pairwise variable relationships in a grid layout, but it’s a chart grid, not an interactive node-link diagram showing investigation state. There is no concept of visualizing the investigation path or factor relationships as a network. See \u003Ca href=\"../competitive/jmp-benchmark.md\">JMP Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Minitab\u003C/strong>: No spatial overview. Minitab’s navigation model is menu-and-dialog — the analyst runs analyses and reviews results in the Session Window (text log) and Graph window (individual charts). Multi-vari charts show factor level combinations but in a chart format, not a spatial map. See \u003Ca href=\"../competitive/minitab-benchmark.md\">Minitab Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Tableau\u003C/strong>: Network visualizations require third-party extensions and are designed for social networks or dependency mapping, not statistical factor analysis. There is no integration with filter state or SPC calculations. See \u003Ca href=\"../competitive/tableau-benchmark.md\">Tableau Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Power BI\u003C/strong>: No spatial factor overview. Decomposition Tree visual allows hierarchical drill-down but is tree-structured (enforced top-down), not a free-form spatial map where the analyst can see interactions and choose their own path. See \u003Ca href=\"../competitive/powerbi-benchmark.md\">Power BI Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>EDAScout\u003C/strong>: Uses a Smart Card carousel and AI chatbot for factor exploration. No spatial visualization of the factor landscape or interaction network. The investigation state is tracked conversationally, not visually. See \u003Ca href=\"../competitive/edascout-benchmark.md\">EDAScout Benchmark\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>The Investigation Mindmap would position VariScout as the only tool that provides a spatial, interactive overview of the investigation state — combining factor importance (node size), investigation progress (drill trail), and factor interactions (edge thickness) in a single synchronized view.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"two-mode-design\">Two-Mode Design\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#two-mode-design\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Two-Mode Design”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The two-mode design is deliberate. Showing drilldown state and interaction information simultaneously would overload the visualization (the \u003Ca href=\"factor-map.md\">Factor Map\u003C/a> evaluation noted this as a complexity risk). Splitting into two modes lets each mode have a clear visual hierarchy:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Drilldown Mode\u003C/strong>: Node size + color is the primary signal. Edges are hidden. The analyst focuses on “where am I, where should I go next?”\u003C/li>\n\u003Cli>\u003Cstrong>Interaction Mode\u003C/strong>: Edge thickness + color is the primary signal. Node size is secondary. The analyst focuses on “which factors interact, and how strongly?”\u003C/li>\n\u003C/ul>\n\u003Cp>A mode toggle (two buttons or a switch) at the top of the mindmap switches between modes. The transition animates the edges appearing/disappearing while nodes stay fixed, reinforcing that the same factors are being viewed through a different lens.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"window-model\">Window Model\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#window-model\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Window Model”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The mindmap opens as a \u003Cstrong>companion view\u003C/strong> rather than replacing the main dashboard. Three implementation options:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Model\u003C/th>\u003Cth>Pros\u003C/th>\u003Cth>Cons\u003C/th>\u003Cth>Best For\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Pop-out window\u003C/strong>\u003C/td>\u003Ctd>Independent sizing, works alongside full dashboard, precedent exists (FunnelWindow)\u003C/td>\u003Ctd>Window management overhead, may be blocked by pop-up blockers\u003C/td>\u003Ctd>PWA (matches existing pattern)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Split pane\u003C/strong>\u003C/td>\u003Ctd>Always visible alongside charts, no window management\u003C/td>\u003Ctd>Reduces chart space, needs responsive breakpoints\u003C/td>\u003Ctd>Azure (desktop-oriented)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Full-screen toggle\u003C/strong>\u003C/td>\u003Ctd>Maximum space for the mindmap, clean transition\u003C/td>\u003Ctd>Hides the charts while viewing the mindmap\u003C/td>\u003Ctd>Mobile, presentations\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The recommended approach: \u003Cstrong>pop-out window as default\u003C/strong> (reusing the \u003Ccode dir=\"auto\">FunnelWindow.tsx\u003C/code> pattern), with \u003Cstrong>split pane as an Azure enhancement\u003C/strong>. The mindmap window receives filter change events from the main dashboard and sends filter apply events back — the same bidirectional sync pattern that the FunnelWindow already implements.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-verdict\">Strategic Verdict\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-verdict\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Verdict”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Pursue (Phase 3)\u003C/strong> — The Investigation Mindmap addresses four of six tensions with a lighter-weight approach than the full Factor Map. It builds directly on Phase 1 (Factor Suggestion provides the η² ranking) and Phase 2 (Interaction Heatmap provides the interaction data) by combining both into a spatial view. The implementation complexity is moderate — static SVG layout, no physics engine, reuse of existing window/sync patterns. The competitive differentiation is strong: no tool offers this. The primary risk is user education (analysts unfamiliar with node-link diagrams may need onboarding), mitigated by the familiar click-to-filter interaction pattern.\u003C/p>\n\u003Cp>Build Factor Suggestion and Interaction Heatmap first. The mindmap adds spatial context to the guidance these features provide. Without the underlying η² suggestions and interaction data, the mindmap is just a pretty picture; with them, it’s a navigation instrument.\u003C/p>", + { + "headings": 12767, + "localImagePaths": 12788, + "remoteImagePaths": 12789, + "frontmatter": 12790, + "imagePaths": 12791 + }, + [12768, 12770, 12771, 12772, 12773, 12776, 12777, 12778, 12779, 12780, 12781, 12784, 12787], + { "depth": 30, "slug": 12769, "text": 12757 }, + "investigation-mindmap", + { "depth": 33, "slug": 12653, "text": 12654 }, + { "depth": 79, "slug": 5499, "text": 5500 }, + { "depth": 79, "slug": 5502, "text": 5503 }, + { "depth": 79, "slug": 12774, "text": 12775 }, + "relationship-to-factor-map", + "Relationship to Factor Map", + { "depth": 33, "slug": 12656, "text": 12657 }, + { "depth": 33, "slug": 12659, "text": 12660 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + { "depth": 33, "slug": 2523, "text": 2524 }, + { "depth": 33, "slug": 12782, "text": 12783 }, + "two-mode-design", + "Two-Mode Design", + { "depth": 33, "slug": 12785, "text": 12786 }, + "window-model", + "Window Model", + { "depth": 33, "slug": 12667, "text": 12668 }, + [], + [], + { "title": 12757 }, + [], + "01-vision/evaluations/patterns/investigation-narrative", + { + "id": 12792, + "data": 12794, + "body": 12799, + "filePath": 12800, + "digest": 12801, + "rendered": 12802 + }, + { + "title": 12795, + "editUrl": 16, + "head": 12796, + "template": 18, + "sidebar": 12797, + "pagefind": 16, + "draft": 20 + }, + "Investigation Narrative", + [], + { "hidden": 20, "attrs": 12798 }, + {}, + "# Investigation Narrative\n\n> A presentation mode that transforms the investigation path into a visual story for stakeholders — showing what was found, in what order, and why it matters.\n\n## The Concept\n\nAfter completing a variation investigation, the analyst switches to Narrative mode. The [Investigation Mindmap](investigation-mindmap.md) transforms from a navigation instrument into a storytelling view:\n\n- **The drill path becomes a timeline**: Nodes appear sequentially, left-to-right or top-to-bottom, showing the investigation order. Each step is annotated with what was found: \"Step 1: Filtered to Store South — explains 45% of variation. Mean delivery time: 35 min vs. 28 min overall.\"\n- **Key findings at each step**: Each node shows the before/after statistics that the filter revealed — mean shift, Cpk change, variation reduction, or out-of-spec reduction. The numbers tell the story of progressive isolation.\n- **Interaction connections**: If the Interaction Mode scan found significant interactions, the narrative shows them as cross-connections between steps: \"Store and Time_Slot interact — the Dinner rush effect is 2× worse at Store South than at other stores.\"\n- **Cumulative progress bar**: A running indicator along the timeline shows how much variation was explained at each step, building toward the final total.\n- **Conclusion panel**: At the end of the timeline, a summary states the investigation outcome: \"Two factors explain 60% of delivery time variation. Recommended actions: (1) Standardize Store South driver routing, (2) Pre-stage Dinner rush orders.\"\n- **Export**: The narrative is exportable as a static image (PNG/SVG), a printable view, or copy-to-clipboard for pasting into slides and reports.\n\nThe narrative is not auto-generated prose — it's a structured visual layout of the investigation data that the analyst can optionally annotate with their own notes. VariScout provides the statistical scaffolding; the analyst adds the operational interpretation.\n\n### The Analyst's Workflow\n\n1. Complete an investigation through the normal drill-down workflow (apply filters, examine charts, identify drivers).\n2. Open the Investigation Mindmap companion view.\n3. Toggle to Narrative mode.\n4. The mindmap reorganizes into a linear timeline showing the drill path and findings.\n5. Optionally add annotations: \"Store South uses contract drivers\" or \"Dinner rush coincides with shift change.\"\n6. Export or present the narrative to stakeholders.\n\n### What the Narrative Contains\n\nFor each drill step:\n\n| Element | Source | Example |\n| -------------------- | ------------------------------ | ------------------------ |\n| Factor name | Current filter | \"Store\" |\n| Filtered value(s) | Filter selection | \"South\" |\n| Variation explained | η² from `useVariationTracking` | \"45% of total variation\" |\n| Key statistic change | Before/after `calculateStats` | \"Mean: 28 → 35 min\" |\n| Capability change | Before/after Cpk | \"Cpk: 0.8 → 0.4\" |\n| Cumulative explained | Running sum | \"45% → 60% → 63%\" |\n\nFor interactions (if detected):\n\n| Element | Source | Example |\n| ---------------------- | ------------------------------------ | ------------------------------------------------ |\n| Factor pair | Interaction term from regression | \"Store × Time_Slot\" |\n| Interaction strength | ΔR² or \\|standardized β\\| | \"Adds 5% explanatory power\" |\n| Plain-language finding | Generated from coefficient direction | \"Dinner rush effect is amplified at Store South\" |\n\n## Tensions Addressed\n\n- [When to Stop](../tensions/when-to-stop.md) — **Primary**. The narrative is itself the stopping signal. Constructing a coherent story of the investigation forces the analyst to assess whether the findings are sufficient. If the cumulative explained variation is low or the conclusion panel is weak, the analyst knows to continue investigating. The act of narrativizing the investigation creates a natural stopping point.\n- [Path Dependency](../tensions/path-dependency.md) — **Secondary**. The narrative records the specific path taken, making path dependency explicit. The analyst (or a reviewer) can see: \"We drilled Store first, then Time_Slot. The investigation explained 60% of variation.\" A different analyst who drilled Time_Slot first would produce a different narrative with different intermediate numbers but a similar conclusion — making the path-dependent intermediate steps transparent rather than hidden.\n- [Discoverability](../tensions/discoverability.md) — **Secondary**. The narrative format shows stakeholders what a variation investigation looks like. For organizations considering VariScout, a sample narrative demonstrates the analytical workflow — this is marketing material as much as an analytical output.\n\n## Philosophy Alignment\n\n- **EDA for process improvement**: Aligned. The narrative is the bridge from exploration to action. EDA produces findings; the narrative communicates them. This closes the loop that most EDA tools leave open — Minitab's Session Window logs commands, not stories; JMP's Journal captures analysis steps but not a narrative arc.\n- **Guided frustration pedagogy**: Compatible. The narrative doesn't short-circuit the investigation — it structures the output. The analyst still does the work of drilling, interpreting, and concluding. The narrative mode activates _after_ the investigation, not during it.\n- **Four Lenses coordination**: Extends. Each step in the narrative can include a small thumbnail of the Four Lenses state at that point — a mini I-Chart showing the pattern that led to the drill decision, a mini Boxplot showing the factor groups. This creates a visual record of the analytical reasoning.\n- **Two Voices**: Positive. The narrative naturally incorporates both voices: \"Store South explains 45% of variation (process voice) and reduces Cpk from 0.8 to 0.4 (customer voice).\" The combination of η² (process metric) and Cpk (customer metric) in the same timeline makes the Two Voices concept tangible for stakeholders.\n\n## Persona Impact\n\n| Persona | Effect | Why |\n| --------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | **Positive** | Gary needs investigation documentation for DMAIC project Tollgate reviews. The narrative replaces manual PowerPoint construction — he gets a structured visual record of his investigation that he can annotate and present. |\n| Student Sara | **Neutral to positive** | Sara's investigations are learning exercises, not project deliverables. The narrative is useful for her portfolio or for showing her instructor what she found, but it's not her primary need. She benefits more from the investigation itself. |\n| OpEx Olivia | **Strongly positive** | Olivia presents investigation findings to plant managers and stakeholders weekly. The narrative is exactly what she needs: a visual, structured summary that non-technical stakeholders can follow. \"Here's what we found, here's why it matters, here's what to do.\" This is Olivia's most common workflow bottleneck. |\n| Trainer Tina | **Strongly positive** | Tina uses the narrative as a teaching walkthrough. She can show students a completed investigation narrative and walk through each step: \"See how they started with the biggest factor? See how the Cpk changed? This is what a good investigation looks like.\" The narrative becomes a case study artifact. |\n| Evaluator Erik | **Neutral** | The narrative adds to the feature list but doesn't change Erik's primary evaluation criteria (statistical correctness, usability, pricing). It may help in demos. |\n| Curious Carlos | **Positive** | Carlos shares interesting findings with colleagues. A narrative export gives him something shareable — \"look what I found in the delivery data\" — that communicates the finding without requiring the recipient to use VariScout. |\n\n## Platform Fit\n\n| Platform | Fit | Notes |\n| ------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| PWA (free training) | **Limited** | The PWA is a training tool — investigations are learning exercises, not deliverables. A basic narrative view is useful for learning (\"this is what a complete investigation looks like\") but export/presentation features are less critical. Consider a read-only narrative view without export for the PWA. |\n| Azure (paid team) | **Primary** | The Azure app serves professional teams who need to communicate findings. The narrative is a high-value feature for Olivia's use case. Full export capabilities (PNG, PDF, copy-to-clipboard) are appropriate for the paid tier. This is a differentiating feature that justifies the Azure subscription. |\n| Excel Add-in | **N/A** | The Excel Add-in uses a slicer-based workflow without the drill-down path that the narrative visualizes. Not applicable. |\n\n## Competitive Landscape\n\nNo competitor provides a visual investigation narrative. This is a genuine gap in the quality analytics tool space.\n\n- **Minitab**: The Session Window is a chronological text log of commands and results. It captures _what was done_ but not _what was found_ or _why it matters_. Analysts copy results from the Session Window into PowerPoint manually. Minitab Workspace (the companion project management tool) supports structured project documentation but doesn't auto-generate investigation narratives from analysis sessions. See [Minitab Benchmark](../competitive/minitab-benchmark.md).\n- **JMP**: The Journal feature captures analysis steps as a clickable log — the analyst can replay their work. But the Journal is a command record, not a story. JMP also supports scripting (JSL) to automate report generation, but this requires programming. There is no visual narrative of the investigation path with annotated findings. See [JMP Benchmark](../competitive/jmp-benchmark.md).\n- **Tableau**: Dashboards are presentation-ready by design, but they show the _current state_ of the data, not the _investigation journey_. A Tableau dashboard says \"Store South has the highest delivery times\" but not \"we started with overall data, drilled into Store, found South was the driver, then examined Time_Slot.\" Tableau Story Points attempt a narrative format but are manually constructed slide sequences, not auto-generated from analytical workflow. See [Tableau Benchmark](../competitive/tableau-benchmark.md).\n- **Power BI**: Same limitation as Tableau. Reports show current state. Power BI's Smart Narrative visual auto-generates text descriptions of chart data but describes what's on screen, not how the analyst arrived there. There is no concept of an investigation path. See [Power BI Benchmark](../competitive/powerbi-benchmark.md).\n- **EDAScout**: The Socratic Analyst chatbot creates a conversational record of the investigation, but this is a chat transcript, not a structured narrative. Chat transcripts are linear, verbose, and not presentation-ready. See [EDAScout Benchmark](../competitive/edascout-benchmark.md).\n\nThe Investigation Narrative would be unique in providing a **structured, visual record** of an analytical investigation that is both auto-generated from the drill-down workflow and presentation-ready for stakeholder communication. This addresses a workflow gap that every quality professional experiences: the \"last mile\" from finding to presentation.\n\n## Strategic Verdict\n\n**Pursue (Phase 3, after Investigation Mindmap)** — The Investigation Narrative builds directly on the Investigation Mindmap by adding a linear, storytelling layout to the spatial overview. Implementation requires: (1) recording the drill-down path as a sequence of steps with before/after statistics, (2) rendering the sequence as a timeline, (3) supporting annotations and export.\n\nThe statistical recording infrastructure (which filters were applied, what the cumulative η² was at each step) can be built incrementally during Phases 1 and 2. By the time the Narrative is implemented in Phase 3, the data it needs will already be collected.\n\nThe competitive opportunity is clear: no tool auto-generates visual investigation narratives. The Narrative positions VariScout not just as an analytical tool but as a **communication tool** — helping analysts share their findings, not just discover them. This is particularly valuable for the Azure tier (Olivia's team) and training contexts (Tina's classroom).\n\nThe primary risk is scope creep: annotations, export formats, and template customization could expand indefinitely. The recommendation is to start with a read-only timeline view (no annotations, PNG export only) and iterate based on user feedback.\n\n**Export requirement**: The Narrative should support a \"slide-ready\" export that composites a selected chart (I-Chart, Boxplot, or Pareto) side-by-side with the narrative timeline. This enables: \"I-chart on one half showing the pattern, mindmap narrative on the other showing how I got there.\" Primary personas: OpEx Olivia (weekly stakeholder presentations), Green Belt Gary (DMAIC Tollgate reviews). Note: individual chart copies already include filter context via the FilterContextBar component.", + "src/content/docs/01-vision/evaluations/patterns/investigation-narrative.md", + "e5235899404bd343", + { "html": 12803, "metadata": 12804 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"investigation-narrative\">Investigation Narrative\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#investigation-narrative\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Investigation Narrative”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>A presentation mode that transforms the investigation path into a visual story for stakeholders — showing what was found, in what order, and why it matters.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-concept\">The Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After completing a variation investigation, the analyst switches to Narrative mode. The \u003Ca href=\"investigation-mindmap.md\">Investigation Mindmap\u003C/a> transforms from a navigation instrument into a storytelling view:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>The drill path becomes a timeline\u003C/strong>: Nodes appear sequentially, left-to-right or top-to-bottom, showing the investigation order. Each step is annotated with what was found: “Step 1: Filtered to Store South — explains 45% of variation. Mean delivery time: 35 min vs. 28 min overall.”\u003C/li>\n\u003Cli>\u003Cstrong>Key findings at each step\u003C/strong>: Each node shows the before/after statistics that the filter revealed — mean shift, Cpk change, variation reduction, or out-of-spec reduction. The numbers tell the story of progressive isolation.\u003C/li>\n\u003Cli>\u003Cstrong>Interaction connections\u003C/strong>: If the Interaction Mode scan found significant interactions, the narrative shows them as cross-connections between steps: “Store and Time_Slot interact — the Dinner rush effect is 2× worse at Store South than at other stores.”\u003C/li>\n\u003Cli>\u003Cstrong>Cumulative progress bar\u003C/strong>: A running indicator along the timeline shows how much variation was explained at each step, building toward the final total.\u003C/li>\n\u003Cli>\u003Cstrong>Conclusion panel\u003C/strong>: At the end of the timeline, a summary states the investigation outcome: “Two factors explain 60% of delivery time variation. Recommended actions: (1) Standardize Store South driver routing, (2) Pre-stage Dinner rush orders.”\u003C/li>\n\u003Cli>\u003Cstrong>Export\u003C/strong>: The narrative is exportable as a static image (PNG/SVG), a printable view, or copy-to-clipboard for pasting into slides and reports.\u003C/li>\n\u003C/ul>\n\u003Cp>The narrative is not auto-generated prose — it’s a structured visual layout of the investigation data that the analyst can optionally annotate with their own notes. VariScout provides the statistical scaffolding; the analyst adds the operational interpretation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"the-analysts-workflow\">The Analyst’s Workflow\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#the-analysts-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Analyst’s Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>Complete an investigation through the normal drill-down workflow (apply filters, examine charts, identify drivers).\u003C/li>\n\u003Cli>Open the Investigation Mindmap companion view.\u003C/li>\n\u003Cli>Toggle to Narrative mode.\u003C/li>\n\u003Cli>The mindmap reorganizes into a linear timeline showing the drill path and findings.\u003C/li>\n\u003Cli>Optionally add annotations: “Store South uses contract drivers” or “Dinner rush coincides with shift change.”\u003C/li>\n\u003Cli>Export or present the narrative to stakeholders.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-the-narrative-contains\">What the Narrative Contains\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-the-narrative-contains\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What the Narrative Contains”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>For each drill step:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Source\u003C/th>\u003Cth>Example\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Factor name\u003C/td>\u003Ctd>Current filter\u003C/td>\u003Ctd>”Store”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filtered value(s)\u003C/td>\u003Ctd>Filter selection\u003C/td>\u003Ctd>”South”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Variation explained\u003C/td>\u003Ctd>η² from \u003Ccode dir=\"auto\">useVariationTracking\u003C/code>\u003C/td>\u003Ctd>”45% of total variation”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Key statistic change\u003C/td>\u003Ctd>Before/after \u003Ccode dir=\"auto\">calculateStats\u003C/code>\u003C/td>\u003Ctd>”Mean: 28 → 35 min”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability change\u003C/td>\u003Ctd>Before/after Cpk\u003C/td>\u003Ctd>”Cpk: 0.8 → 0.4”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cumulative explained\u003C/td>\u003Ctd>Running sum\u003C/td>\u003Ctd>”45% → 60% → 63%”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>For interactions (if detected):\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Element\u003C/th>\u003Cth>Source\u003C/th>\u003Cth>Example\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Factor pair\u003C/td>\u003Ctd>Interaction term from regression\u003C/td>\u003Ctd>”Store × Time_Slot”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Interaction strength\u003C/td>\u003Ctd>ΔR² or |standardized β|\u003C/td>\u003Ctd>“Adds 5% explanatory power”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Plain-language finding\u003C/td>\u003Ctd>Generated from coefficient direction\u003C/td>\u003Ctd>”Dinner rush effect is amplified at Store South”\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tensions-addressed\">Tensions Addressed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tensions-addressed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tensions Addressed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../tensions/when-to-stop.md\">When to Stop\u003C/a> — \u003Cstrong>Primary\u003C/strong>. The narrative is itself the stopping signal. Constructing a coherent story of the investigation forces the analyst to assess whether the findings are sufficient. If the cumulative explained variation is low or the conclusion panel is weak, the analyst knows to continue investigating. The act of narrativizing the investigation creates a natural stopping point.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/path-dependency.md\">Path Dependency\u003C/a> — \u003Cstrong>Secondary\u003C/strong>. The narrative records the specific path taken, making path dependency explicit. The analyst (or a reviewer) can see: “We drilled Store first, then Time_Slot. The investigation explained 60% of variation.” A different analyst who drilled Time_Slot first would produce a different narrative with different intermediate numbers but a similar conclusion — making the path-dependent intermediate steps transparent rather than hidden.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/discoverability.md\">Discoverability\u003C/a> — \u003Cstrong>Secondary\u003C/strong>. The narrative format shows stakeholders what a variation investigation looks like. For organizations considering VariScout, a sample narrative demonstrates the analytical workflow — this is marketing material as much as an analytical output.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy-alignment\">Philosophy Alignment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>EDA for process improvement\u003C/strong>: Aligned. The narrative is the bridge from exploration to action. EDA produces findings; the narrative communicates them. This closes the loop that most EDA tools leave open — Minitab’s Session Window logs commands, not stories; JMP’s Journal captures analysis steps but not a narrative arc.\u003C/li>\n\u003Cli>\u003Cstrong>Guided frustration pedagogy\u003C/strong>: Compatible. The narrative doesn’t short-circuit the investigation — it structures the output. The analyst still does the work of drilling, interpreting, and concluding. The narrative mode activates \u003Cem>after\u003C/em> the investigation, not during it.\u003C/li>\n\u003Cli>\u003Cstrong>Four Lenses coordination\u003C/strong>: Extends. Each step in the narrative can include a small thumbnail of the Four Lenses state at that point — a mini I-Chart showing the pattern that led to the drill decision, a mini Boxplot showing the factor groups. This creates a visual record of the analytical reasoning.\u003C/li>\n\u003Cli>\u003Cstrong>Two Voices\u003C/strong>: Positive. The narrative naturally incorporates both voices: “Store South explains 45% of variation (process voice) and reduces Cpk from 0.8 to 0.4 (customer voice).” The combination of η² (process metric) and Cpk (customer metric) in the same timeline makes the Two Voices concept tangible for stakeholders.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Effect\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>\u003Cstrong>Positive\u003C/strong>\u003C/td>\u003Ctd>Gary needs investigation documentation for DMAIC project Tollgate reviews. The narrative replaces manual PowerPoint construction — he gets a structured visual record of his investigation that he can annotate and present.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>\u003Cstrong>Neutral to positive\u003C/strong>\u003C/td>\u003Ctd>Sara’s investigations are learning exercises, not project deliverables. The narrative is useful for her portfolio or for showing her instructor what she found, but it’s not her primary need. She benefits more from the investigation itself.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>\u003Cstrong>Strongly positive\u003C/strong>\u003C/td>\u003Ctd>Olivia presents investigation findings to plant managers and stakeholders weekly. The narrative is exactly what she needs: a visual, structured summary that non-technical stakeholders can follow. “Here’s what we found, here’s why it matters, here’s what to do.” This is Olivia’s most common workflow bottleneck.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>\u003Cstrong>Strongly positive\u003C/strong>\u003C/td>\u003Ctd>Tina uses the narrative as a teaching walkthrough. She can show students a completed investigation narrative and walk through each step: “See how they started with the biggest factor? See how the Cpk changed? This is what a good investigation looks like.” The narrative becomes a case study artifact.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>\u003Cstrong>Neutral\u003C/strong>\u003C/td>\u003Ctd>The narrative adds to the feature list but doesn’t change Erik’s primary evaluation criteria (statistical correctness, usability, pricing). It may help in demos.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>\u003Cstrong>Positive\u003C/strong>\u003C/td>\u003Ctd>Carlos shares interesting findings with colleagues. A narrative export gives him something shareable — “look what I found in the delivery data” — that communicates the finding without requiring the recipient to use VariScout.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Fit\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA (free training)\u003C/td>\u003Ctd>\u003Cstrong>Limited\u003C/strong>\u003C/td>\u003Ctd>The PWA is a training tool — investigations are learning exercises, not deliverables. A basic narrative view is useful for learning (“this is what a complete investigation looks like”) but export/presentation features are less critical. Consider a read-only narrative view without export for the PWA.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure (paid team)\u003C/td>\u003Ctd>\u003Cstrong>Primary\u003C/strong>\u003C/td>\u003Ctd>The Azure app serves professional teams who need to communicate findings. The narrative is a high-value feature for Olivia’s use case. Full export capabilities (PNG, PDF, copy-to-clipboard) are appropriate for the paid tier. This is a differentiating feature that justifies the Azure subscription.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel Add-in\u003C/td>\u003Ctd>\u003Cstrong>N/A\u003C/strong>\u003C/td>\u003Ctd>The Excel Add-in uses a slicer-based workflow without the drill-down path that the narrative visualizes. Not applicable.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-landscape\">Competitive Landscape\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-landscape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Landscape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>No competitor provides a visual investigation narrative. This is a genuine gap in the quality analytics tool space.\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Minitab\u003C/strong>: The Session Window is a chronological text log of commands and results. It captures \u003Cem>what was done\u003C/em> but not \u003Cem>what was found\u003C/em> or \u003Cem>why it matters\u003C/em>. Analysts copy results from the Session Window into PowerPoint manually. Minitab Workspace (the companion project management tool) supports structured project documentation but doesn’t auto-generate investigation narratives from analysis sessions. See \u003Ca href=\"../competitive/minitab-benchmark.md\">Minitab Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>JMP\u003C/strong>: The Journal feature captures analysis steps as a clickable log — the analyst can replay their work. But the Journal is a command record, not a story. JMP also supports scripting (JSL) to automate report generation, but this requires programming. There is no visual narrative of the investigation path with annotated findings. See \u003Ca href=\"../competitive/jmp-benchmark.md\">JMP Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Tableau\u003C/strong>: Dashboards are presentation-ready by design, but they show the \u003Cem>current state\u003C/em> of the data, not the \u003Cem>investigation journey\u003C/em>. A Tableau dashboard says “Store South has the highest delivery times” but not “we started with overall data, drilled into Store, found South was the driver, then examined Time_Slot.” Tableau Story Points attempt a narrative format but are manually constructed slide sequences, not auto-generated from analytical workflow. See \u003Ca href=\"../competitive/tableau-benchmark.md\">Tableau Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Power BI\u003C/strong>: Same limitation as Tableau. Reports show current state. Power BI’s Smart Narrative visual auto-generates text descriptions of chart data but describes what’s on screen, not how the analyst arrived there. There is no concept of an investigation path. See \u003Ca href=\"../competitive/powerbi-benchmark.md\">Power BI Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>EDAScout\u003C/strong>: The Socratic Analyst chatbot creates a conversational record of the investigation, but this is a chat transcript, not a structured narrative. Chat transcripts are linear, verbose, and not presentation-ready. See \u003Ca href=\"../competitive/edascout-benchmark.md\">EDAScout Benchmark\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>The Investigation Narrative would be unique in providing a \u003Cstrong>structured, visual record\u003C/strong> of an analytical investigation that is both auto-generated from the drill-down workflow and presentation-ready for stakeholder communication. This addresses a workflow gap that every quality professional experiences: the “last mile” from finding to presentation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-verdict\">Strategic Verdict\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-verdict\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Verdict”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Pursue (Phase 3, after Investigation Mindmap)\u003C/strong> — The Investigation Narrative builds directly on the Investigation Mindmap by adding a linear, storytelling layout to the spatial overview. Implementation requires: (1) recording the drill-down path as a sequence of steps with before/after statistics, (2) rendering the sequence as a timeline, (3) supporting annotations and export.\u003C/p>\n\u003Cp>The statistical recording infrastructure (which filters were applied, what the cumulative η² was at each step) can be built incrementally during Phases 1 and 2. By the time the Narrative is implemented in Phase 3, the data it needs will already be collected.\u003C/p>\n\u003Cp>The competitive opportunity is clear: no tool auto-generates visual investigation narratives. The Narrative positions VariScout not just as an analytical tool but as a \u003Cstrong>communication tool\u003C/strong> — helping analysts share their findings, not just discover them. This is particularly valuable for the Azure tier (Olivia’s team) and training contexts (Tina’s classroom).\u003C/p>\n\u003Cp>The primary risk is scope creep: annotations, export formats, and template customization could expand indefinitely. The recommendation is to start with a read-only timeline view (no annotations, PNG export only) and iterate based on user feedback.\u003C/p>\n\u003Cp>\u003Cstrong>Export requirement\u003C/strong>: The Narrative should support a “slide-ready” export that composites a selected chart (I-Chart, Boxplot, or Pareto) side-by-side with the narrative timeline. This enables: “I-chart on one half showing the pattern, mindmap narrative on the other showing how I got there.” Primary personas: OpEx Olivia (weekly stakeholder presentations), Green Belt Gary (DMAIC Tollgate reviews). Note: individual chart copies already include filter context via the FilterContextBar component.\u003C/p>", + { + "headings": 12805, + "localImagePaths": 12821, + "remoteImagePaths": 12822, + "frontmatter": 12823, + "imagePaths": 12824 + }, + [12806, 12808, 12809, 12812, 12815, 12816, 12817, 12818, 12819, 12820], + { "depth": 30, "slug": 12807, "text": 12795 }, + "investigation-narrative", + { "depth": 33, "slug": 12653, "text": 12654 }, + { "depth": 79, "slug": 12810, "text": 12811 }, + "the-analysts-workflow", + "The Analyst’s Workflow", + { "depth": 79, "slug": 12813, "text": 12814 }, + "what-the-narrative-contains", + "What the Narrative Contains", + { "depth": 33, "slug": 12656, "text": 12657 }, + { "depth": 33, "slug": 12659, "text": 12660 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + { "depth": 33, "slug": 2523, "text": 2524 }, + { "depth": 33, "slug": 12667, "text": 12668 }, + [], + [], + { "title": 12795 }, + [], + "01-vision/evaluations/patterns/sidebar-filter-panel", + { + "id": 12825, + "data": 12827, + "body": 12832, + "filePath": 12833, + "digest": 12834, + "rendered": 12835 + }, + { + "title": 12828, + "editUrl": 16, + "head": 12829, + "template": 18, + "sidebar": 12830, + "pagefind": 16, + "draft": 20 + }, + "Sidebar Filter Panel", + [], + { "hidden": 20, "attrs": 12831 }, + {}, + "# Sidebar Filter Panel\n\n> An always-visible panel listing all factors with checkboxes and sliders, Tableau-style.\n\n## The Concept\n\nA persistent sidebar (or bottom panel on mobile) that lists all categorical and continuous factors with checkboxes for levels, sliders for ranges, and search/filter within each factor. This is the dominant pattern in BI tools: Tableau, Power BI, Looker, and most dashboard platforms use a filter panel that's always visible alongside the visualization area.\n\nThe advantage is complete discoverability: every filter option is visible at all times, no clicking required to discover what's available. The analyst can see the full factor landscape at a glance, apply multiple filters simultaneously, and understand the complete filtering state without reading chips or navigating to a funnel view.\n\nThe trade-off is analytical flow. VariScout's current design integrates filtering into the chart interaction itself --- you click a boxplot bar because you _see_ the variation there, and the click-to-filter action is a direct response to the visual pattern. A sidebar panel separates the \"seeing\" from the \"acting\": the analyst reads patterns in the chart area and manages filters in a separate panel. This disconnect breaks the tight feedback loop that makes progressive stratification feel like investigation rather than dashboard configuration.\n\nAdditionally, a sidebar panel doesn't naturally show eta-squared or contribution percentages. It's a filter management UI, not an analysis UI. The analyst would need to read the boxplot for eta-squared information and then apply that knowledge in the sidebar, adding a cognitive transfer step that doesn't exist in the current click-to-drill design.\n\n## Tensions Addressed\n\n- [Discoverability](../tensions/discoverability.md) --- Completely resolves. All filter options are always visible.\n- [Mobile Screen Budget](../tensions/mobile-screen-budget.md) --- Worsens on mobile. A persistent sidebar consumes significant screen real estate on narrow screens.\n\n## Philosophy Alignment\n\n- **EDA for process improvement**: Partially conflicts. The sidebar treats filtering as a configuration task rather than an investigation step. The analyst manages filters instead of _investigating_ through filters.\n- **Guided frustration pedagogy**: Conflicts. A sidebar presents all options at once, removing the progressive discovery that builds understanding. The analyst doesn't need to \"find\" where variation is --- they just check boxes.\n- **Four Lenses coordination**: Weakens. The current design means filtering _is_ interacting with a lens. A sidebar decouples filtering from lens interaction, reducing the sense that the four charts are connected investigation tools.\n- **Two Voices**: Neutral. Filter management is orthogonal to the process-voice/customer-voice distinction.\n\n## Persona Impact\n\n| Persona | Effect | Why |\n| --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | Neutral | Gary is comfortable with both interaction models. He might prefer the sidebar's familiarity from Tableau/Power BI experience but would lose the analytical integration. |\n| Student Sara | Negative | Sara needs to learn progressive stratification, not dashboard filtering. A sidebar teaches a BI workflow, not an EDA methodology. |\n| OpEx Olivia | Neutral | Olivia's team may find the sidebar more familiar if they come from Tableau/Power BI backgrounds. But familiarity isn't the same as effectiveness. |\n| Trainer Tina | Negative | Tina explicitly teaches the investigation-through-charts approach. A sidebar contradicts her methodology and makes it harder to demonstrate the Sock Mystery journey. |\n| Evaluator Erik | Neutral | Erik checks for filter capability on a feature list. Both approaches satisfy the requirement; the interaction model doesn't affect his evaluation. |\n| Curious Carlos | Positive | Carlos is used to filter panels from consumer apps. A sidebar is immediately understandable, reducing the learning curve for first-time users. |\n\n## Platform Fit\n\n| Platform | Fit | Notes |\n| ------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |\n| PWA (free training) | Poor | Conflicts with the educational mission. The PWA should teach progressive stratification, not replicate Tableau. |\n| Azure (paid team) | Neutral | Could be offered as an alternative view for teams migrating from Tableau/Power BI. But it undermines the methodology that differentiates VariScout. |\n| Excel Add-in | N/A | The Excel Add-in already uses native Excel slicers, which serve the sidebar filter function. |\n\n## Competitive Landscape\n\n- **Tableau**: Sidebar filters are the defining interaction model — dropdowns, checkboxes, sliders, and date ranges alongside the visualization area. Cross-filtering between dashboard sheets provides immediate visual feedback. Quick filters update charts as selections change. This is the paradigm that millions of users know, and the paradigm that VariScout's chart-integrated filtering deliberately rejects. See [Tableau Benchmark](../competitive/tableau-benchmark.md).\n- **Power BI**: Slicers serve the same function as Tableau's sidebar filters — visual controls for filtering dimensions, with sync groups that propagate selections across pages. The responsive slicer pane collapses into a panel that expands on click, acknowledging that persistent filter controls consume too much screen space. Cross-filtering between visuals mirrors Tableau's behavior. See [Power BI Benchmark](../competitive/powerbi-benchmark.md).\n- **Looker**: Uses a filter bar at the top of dashboards with dropdowns for each filterable dimension. Filters are defined through LookML (Looker's modeling language) and exposed to dashboard consumers, adding a governance layer. The interaction pattern is consistent with Tableau and Power BI — always-visible filter controls that the analyst configures. See [Minor Competitors](../competitive/minor-competitors.md).\n- **EDAScout**: The `CategoryGrid` component inside `SubgroupExplorerModal` is their closest equivalent --- an always-visible grid of category cards with variance-derived coloring from ANOVA. Unlike a traditional sidebar, it opens as a modal overlay rather than being persistently visible. Filters are modal-scoped and do not persist across page navigation. The variance coloring uses within-group SS (how internally noisy each group is), which is conceptually misleading for variation source identification. See [EDAScout Benchmark](../competitive/edascout-benchmark.md).\n\nAdopting a sidebar would make VariScout more familiar but less distinctive. The current chart-integrated filtering is a competitive differentiator precisely because it's different from the Tableau model. EDAScout's modal-based approach demonstrates the middle ground (a dedicated filter UI that's not always visible) but still suffers from separating the \"seeing\" from the \"filtering\" step. Adopting any competitor's pattern removes the differentiation.\n\n## Strategic Verdict\n\n**Reject** --- The sidebar filter panel solves discoverability but at the cost of VariScout's core differentiator: analysis-integrated filtering. The philosophical conflict with guided frustration pedagogy and Four Lenses coordination is too deep. Better to solve discoverability through onboarding, tooltips, and factor suggestion rather than adopting a pattern that converts the tool from an investigation platform into a dashboard configurator.", + "src/content/docs/01-vision/evaluations/patterns/sidebar-filter-panel.md", + "14864414d1d715ce", + { "html": 12836, "metadata": 12837 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"sidebar-filter-panel\">Sidebar Filter Panel\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#sidebar-filter-panel\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sidebar Filter Panel”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>An always-visible panel listing all factors with checkboxes and sliders, Tableau-style.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-concept\">The Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A persistent sidebar (or bottom panel on mobile) that lists all categorical and continuous factors with checkboxes for levels, sliders for ranges, and search/filter within each factor. This is the dominant pattern in BI tools: Tableau, Power BI, Looker, and most dashboard platforms use a filter panel that’s always visible alongside the visualization area.\u003C/p>\n\u003Cp>The advantage is complete discoverability: every filter option is visible at all times, no clicking required to discover what’s available. The analyst can see the full factor landscape at a glance, apply multiple filters simultaneously, and understand the complete filtering state without reading chips or navigating to a funnel view.\u003C/p>\n\u003Cp>The trade-off is analytical flow. VariScout’s current design integrates filtering into the chart interaction itself --- you click a boxplot bar because you \u003Cem>see\u003C/em> the variation there, and the click-to-filter action is a direct response to the visual pattern. A sidebar panel separates the “seeing” from the “acting”: the analyst reads patterns in the chart area and manages filters in a separate panel. This disconnect breaks the tight feedback loop that makes progressive stratification feel like investigation rather than dashboard configuration.\u003C/p>\n\u003Cp>Additionally, a sidebar panel doesn’t naturally show eta-squared or contribution percentages. It’s a filter management UI, not an analysis UI. The analyst would need to read the boxplot for eta-squared information and then apply that knowledge in the sidebar, adding a cognitive transfer step that doesn’t exist in the current click-to-drill design.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tensions-addressed\">Tensions Addressed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tensions-addressed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tensions Addressed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../tensions/discoverability.md\">Discoverability\u003C/a> --- Completely resolves. All filter options are always visible.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/mobile-screen-budget.md\">Mobile Screen Budget\u003C/a> --- Worsens on mobile. A persistent sidebar consumes significant screen real estate on narrow screens.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy-alignment\">Philosophy Alignment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>EDA for process improvement\u003C/strong>: Partially conflicts. The sidebar treats filtering as a configuration task rather than an investigation step. The analyst manages filters instead of \u003Cem>investigating\u003C/em> through filters.\u003C/li>\n\u003Cli>\u003Cstrong>Guided frustration pedagogy\u003C/strong>: Conflicts. A sidebar presents all options at once, removing the progressive discovery that builds understanding. The analyst doesn’t need to “find” where variation is --- they just check boxes.\u003C/li>\n\u003Cli>\u003Cstrong>Four Lenses coordination\u003C/strong>: Weakens. The current design means filtering \u003Cem>is\u003C/em> interacting with a lens. A sidebar decouples filtering from lens interaction, reducing the sense that the four charts are connected investigation tools.\u003C/li>\n\u003Cli>\u003Cstrong>Two Voices\u003C/strong>: Neutral. Filter management is orthogonal to the process-voice/customer-voice distinction.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Effect\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Gary is comfortable with both interaction models. He might prefer the sidebar’s familiarity from Tableau/Power BI experience but would lose the analytical integration.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>Negative\u003C/td>\u003Ctd>Sara needs to learn progressive stratification, not dashboard filtering. A sidebar teaches a BI workflow, not an EDA methodology.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Olivia’s team may find the sidebar more familiar if they come from Tableau/Power BI backgrounds. But familiarity isn’t the same as effectiveness.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Negative\u003C/td>\u003Ctd>Tina explicitly teaches the investigation-through-charts approach. A sidebar contradicts her methodology and makes it harder to demonstrate the Sock Mystery journey.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Erik checks for filter capability on a feature list. Both approaches satisfy the requirement; the interaction model doesn’t affect his evaluation.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Carlos is used to filter panels from consumer apps. A sidebar is immediately understandable, reducing the learning curve for first-time users.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Fit\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA (free training)\u003C/td>\u003Ctd>Poor\u003C/td>\u003Ctd>Conflicts with the educational mission. The PWA should teach progressive stratification, not replicate Tableau.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure (paid team)\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Could be offered as an alternative view for teams migrating from Tableau/Power BI. But it undermines the methodology that differentiates VariScout.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel Add-in\u003C/td>\u003Ctd>N/A\u003C/td>\u003Ctd>The Excel Add-in already uses native Excel slicers, which serve the sidebar filter function.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-landscape\">Competitive Landscape\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-landscape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Landscape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Tableau\u003C/strong>: Sidebar filters are the defining interaction model — dropdowns, checkboxes, sliders, and date ranges alongside the visualization area. Cross-filtering between dashboard sheets provides immediate visual feedback. Quick filters update charts as selections change. This is the paradigm that millions of users know, and the paradigm that VariScout’s chart-integrated filtering deliberately rejects. See \u003Ca href=\"../competitive/tableau-benchmark.md\">Tableau Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Power BI\u003C/strong>: Slicers serve the same function as Tableau’s sidebar filters — visual controls for filtering dimensions, with sync groups that propagate selections across pages. The responsive slicer pane collapses into a panel that expands on click, acknowledging that persistent filter controls consume too much screen space. Cross-filtering between visuals mirrors Tableau’s behavior. See \u003Ca href=\"../competitive/powerbi-benchmark.md\">Power BI Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Looker\u003C/strong>: Uses a filter bar at the top of dashboards with dropdowns for each filterable dimension. Filters are defined through LookML (Looker’s modeling language) and exposed to dashboard consumers, adding a governance layer. The interaction pattern is consistent with Tableau and Power BI — always-visible filter controls that the analyst configures. See \u003Ca href=\"../competitive/minor-competitors.md\">Minor Competitors\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>EDAScout\u003C/strong>: The \u003Ccode dir=\"auto\">CategoryGrid\u003C/code> component inside \u003Ccode dir=\"auto\">SubgroupExplorerModal\u003C/code> is their closest equivalent --- an always-visible grid of category cards with variance-derived coloring from ANOVA. Unlike a traditional sidebar, it opens as a modal overlay rather than being persistently visible. Filters are modal-scoped and do not persist across page navigation. The variance coloring uses within-group SS (how internally noisy each group is), which is conceptually misleading for variation source identification. See \u003Ca href=\"../competitive/edascout-benchmark.md\">EDAScout Benchmark\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Adopting a sidebar would make VariScout more familiar but less distinctive. The current chart-integrated filtering is a competitive differentiator precisely because it’s different from the Tableau model. EDAScout’s modal-based approach demonstrates the middle ground (a dedicated filter UI that’s not always visible) but still suffers from separating the “seeing” from the “filtering” step. Adopting any competitor’s pattern removes the differentiation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-verdict\">Strategic Verdict\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-verdict\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Verdict”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Reject\u003C/strong> --- The sidebar filter panel solves discoverability but at the cost of VariScout’s core differentiator: analysis-integrated filtering. The philosophical conflict with guided frustration pedagogy and Four Lenses coordination is too deep. Better to solve discoverability through onboarding, tooltips, and factor suggestion rather than adopting a pattern that converts the tool from an investigation platform into a dashboard configurator.\u003C/p>", + { + "headings": 12838, + "localImagePaths": 12848, + "remoteImagePaths": 12849, + "frontmatter": 12850, + "imagePaths": 12851 + }, + [12839, 12841, 12842, 12843, 12844, 12845, 12846, 12847], + { "depth": 30, "slug": 12840, "text": 12828 }, + "sidebar-filter-panel", + { "depth": 33, "slug": 12653, "text": 12654 }, + { "depth": 33, "slug": 12656, "text": 12657 }, + { "depth": 33, "slug": 12659, "text": 12660 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + { "depth": 33, "slug": 2523, "text": 2524 }, + { "depth": 33, "slug": 12667, "text": 12668 }, + [], + [], + { "title": 12828 }, + [], + "01-vision/evaluations/patterns/parallel-path-comparison", + { + "id": 12852, + "data": 12854, + "body": 12859, + "filePath": 12860, + "digest": 12861, + "rendered": 12862 + }, + { + "title": 12855, + "editUrl": 16, + "head": 12856, + "template": 18, + "sidebar": 12857, + "pagefind": 16, + "draft": 20 + }, + "Parallel Path Comparison", + [], + { "hidden": 20, "attrs": 12858 }, + {}, + "# Parallel Path Comparison\n\n> Show alternative drill paths and whether they converge on the same finding.\n\n## The Concept\n\nAfter an analyst completes a drill-down (e.g., Shift then Machine), the system would show what would have happened with an alternative path (Machine then Shift). A comparison view displays the two paths side by side: intermediate contribution percentages, the filter stack at each step, and the final cumulative result. The key insight is whether both paths converge on the same finding or diverge --- convergence confirms the finding is robust; divergence signals that the factor structure is more complex than a sequential drill-down can capture.\n\nThe simplest implementation is a retrospective comparison: after the analyst finishes their drill-down, offer \"What if you had started with Machine instead?\" as a secondary analysis. A more ambitious version would run multiple paths in parallel during drilling, showing a branching tree of possible investigations. The most complex version would include all permutations and highlight the path that maximizes cumulative variation explained at each step.\n\nThe cost is UI complexity and potential information overload. An analyst who just completed a satisfying drill-down (\"I found it!\") may not want to see that an alternative path would have reached the same conclusion faster, or that a different path reveals a completely different pattern. The value is in building statistical confidence, but the cognitive cost is in processing multiple narratives simultaneously.\n\n## Tensions Addressed\n\n- [Path Dependency](../tensions/path-dependency.md) --- Directly addresses this by making convergence or divergence visible.\n- [Hierarchy Assumption](../tensions/hierarchy-assumption.md) --- Divergent paths can signal interaction effects that neither single path captures.\n\n## Philosophy Alignment\n\n- **EDA for process improvement**: Aligned. Showing multiple perspectives on the same data is exploratory by nature. It helps the analyst understand factor structure, not just find one answer.\n- **Guided frustration pedagogy**: Neutral. The comparison is retrospective --- the analyst has already done the exploration. It adds a \"meta-level\" reflection on the methodology itself.\n- **Four Lenses coordination**: Neutral. Path comparison is about the drill-down sequence, not about how the four charts coordinate.\n- **Two Voices**: Neutral. Path comparison doesn't interact with the process-voice/customer-voice distinction.\n\n## Persona Impact\n\n| Persona | Effect | Why |\n| --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | Positive | Gary would appreciate confirmation that his drill-down path led to the right answer. Seeing convergence builds confidence in his analysis. |\n| Student Sara | Positive | Sara learns about path dependency directly. This is a teaching tool: \"Notice how both paths reach the same conclusion? That's because the total variation explained is path-independent.\" |\n| OpEx Olivia | Neutral | Useful for quality assurance of team analyses but adds complexity to an already feature-rich tool. |\n| Trainer Tina | Positive | Tina could use this as a teaching exercise: \"Try both paths and compare.\" It reinforces understanding of conditional decomposition. |\n| Evaluator Erik | Neutral | Doesn't affect Erik's evaluation criteria. |\n| Curious Carlos | Negative | Carlos wants simple answers. Showing that there are multiple paths to the same answer adds confusion rather than clarity for a novice explorer. |\n\n## Platform Fit\n\n| Platform | Fit | Notes |\n| ------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------- |\n| PWA (free training) | Good | Excellent teaching tool for understanding path dependency. Low implementation complexity if done as a retrospective comparison. |\n| Azure (paid team) | Good | Quality assurance feature for team analyses. Helps analysts verify their findings are robust. |\n| Excel Add-in | N/A | The Excel Add-in uses slicers, not the drill-down workflow. |\n\n## Competitive Landscape\n\n- **No direct competitor implements this.** Path comparison in drill-down analysis is a novel concept. No SPC or BI tool frames data exploration as a sequential path through factor space, so there is no precedent for comparing alternative paths.\n- **JMP**: The \"What If\" Prediction Profiler varies model inputs to show predicted response changes, but this is model-based sensitivity analysis, not comparison of alternative analysis paths. The analyst adjusts factor sliders within a single fitted model — the concept of \"what if I had investigated factors in a different order?\" does not exist in JMP's paradigm. See [JMP Benchmark](../competitive/jmp-benchmark.md).\n- **Tableau**: No concept of filter sequence or investigation path. Dashboard filters are stateless — applying Machine=A then Shift=Night produces the same view as Shift=Night then Machine=A. There is no sequential narrative to compare because Tableau's interaction model is commutative configuration, not progressive investigation. See [Tableau Benchmark](../competitive/tableau-benchmark.md).\n- **Power BI**: Same as Tableau. Slicer selections are commutative and produce the same result regardless of application order. There is no concept of a drill-down path and therefore no concept of an alternative path. See [Power BI Benchmark](../competitive/powerbi-benchmark.md).\n\nThis would be a genuine differentiator --- a feature that no competitor offers because no competitor frames data exploration as a sequential path through factor space.\n\n## Strategic Verdict\n\n**Defer** --- Intellectually compelling and pedagogically valuable, but addresses a low-frequency pain point (path dependency is strategic weight: Low). Build this after factor suggestion and interaction heatmap, which address higher-impact tensions. A retrospective \"what if?\" comparison is the lowest-cost entry point when the time comes.", + "src/content/docs/01-vision/evaluations/patterns/parallel-path-comparison.md", + "ec075fec76262436", + { "html": 12863, "metadata": 12864 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"parallel-path-comparison\">Parallel Path Comparison\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#parallel-path-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Parallel Path Comparison”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Show alternative drill paths and whether they converge on the same finding.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-concept\">The Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>After an analyst completes a drill-down (e.g., Shift then Machine), the system would show what would have happened with an alternative path (Machine then Shift). A comparison view displays the two paths side by side: intermediate contribution percentages, the filter stack at each step, and the final cumulative result. The key insight is whether both paths converge on the same finding or diverge --- convergence confirms the finding is robust; divergence signals that the factor structure is more complex than a sequential drill-down can capture.\u003C/p>\n\u003Cp>The simplest implementation is a retrospective comparison: after the analyst finishes their drill-down, offer “What if you had started with Machine instead?” as a secondary analysis. A more ambitious version would run multiple paths in parallel during drilling, showing a branching tree of possible investigations. The most complex version would include all permutations and highlight the path that maximizes cumulative variation explained at each step.\u003C/p>\n\u003Cp>The cost is UI complexity and potential information overload. An analyst who just completed a satisfying drill-down (“I found it!”) may not want to see that an alternative path would have reached the same conclusion faster, or that a different path reveals a completely different pattern. The value is in building statistical confidence, but the cognitive cost is in processing multiple narratives simultaneously.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tensions-addressed\">Tensions Addressed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tensions-addressed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tensions Addressed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../tensions/path-dependency.md\">Path Dependency\u003C/a> --- Directly addresses this by making convergence or divergence visible.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/hierarchy-assumption.md\">Hierarchy Assumption\u003C/a> --- Divergent paths can signal interaction effects that neither single path captures.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy-alignment\">Philosophy Alignment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>EDA for process improvement\u003C/strong>: Aligned. Showing multiple perspectives on the same data is exploratory by nature. It helps the analyst understand factor structure, not just find one answer.\u003C/li>\n\u003Cli>\u003Cstrong>Guided frustration pedagogy\u003C/strong>: Neutral. The comparison is retrospective --- the analyst has already done the exploration. It adds a “meta-level” reflection on the methodology itself.\u003C/li>\n\u003Cli>\u003Cstrong>Four Lenses coordination\u003C/strong>: Neutral. Path comparison is about the drill-down sequence, not about how the four charts coordinate.\u003C/li>\n\u003Cli>\u003Cstrong>Two Voices\u003C/strong>: Neutral. Path comparison doesn’t interact with the process-voice/customer-voice distinction.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Effect\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Gary would appreciate confirmation that his drill-down path led to the right answer. Seeing convergence builds confidence in his analysis.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Sara learns about path dependency directly. This is a teaching tool: “Notice how both paths reach the same conclusion? That’s because the total variation explained is path-independent.”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Useful for quality assurance of team analyses but adds complexity to an already feature-rich tool.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Tina could use this as a teaching exercise: “Try both paths and compare.” It reinforces understanding of conditional decomposition.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Doesn’t affect Erik’s evaluation criteria.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Negative\u003C/td>\u003Ctd>Carlos wants simple answers. Showing that there are multiple paths to the same answer adds confusion rather than clarity for a novice explorer.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Fit\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA (free training)\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Excellent teaching tool for understanding path dependency. Low implementation complexity if done as a retrospective comparison.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure (paid team)\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Quality assurance feature for team analyses. Helps analysts verify their findings are robust.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel Add-in\u003C/td>\u003Ctd>N/A\u003C/td>\u003Ctd>The Excel Add-in uses slicers, not the drill-down workflow.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-landscape\">Competitive Landscape\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-landscape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Landscape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>No direct competitor implements this.\u003C/strong> Path comparison in drill-down analysis is a novel concept. No SPC or BI tool frames data exploration as a sequential path through factor space, so there is no precedent for comparing alternative paths.\u003C/li>\n\u003Cli>\u003Cstrong>JMP\u003C/strong>: The “What If” Prediction Profiler varies model inputs to show predicted response changes, but this is model-based sensitivity analysis, not comparison of alternative analysis paths. The analyst adjusts factor sliders within a single fitted model — the concept of “what if I had investigated factors in a different order?” does not exist in JMP’s paradigm. See \u003Ca href=\"../competitive/jmp-benchmark.md\">JMP Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Tableau\u003C/strong>: No concept of filter sequence or investigation path. Dashboard filters are stateless — applying Machine=A then Shift=Night produces the same view as Shift=Night then Machine=A. There is no sequential narrative to compare because Tableau’s interaction model is commutative configuration, not progressive investigation. See \u003Ca href=\"../competitive/tableau-benchmark.md\">Tableau Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Power BI\u003C/strong>: Same as Tableau. Slicer selections are commutative and produce the same result regardless of application order. There is no concept of a drill-down path and therefore no concept of an alternative path. See \u003Ca href=\"../competitive/powerbi-benchmark.md\">Power BI Benchmark\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>This would be a genuine differentiator --- a feature that no competitor offers because no competitor frames data exploration as a sequential path through factor space.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-verdict\">Strategic Verdict\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-verdict\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Verdict”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Defer\u003C/strong> --- Intellectually compelling and pedagogically valuable, but addresses a low-frequency pain point (path dependency is strategic weight: Low). Build this after factor suggestion and interaction heatmap, which address higher-impact tensions. A retrospective “what if?” comparison is the lowest-cost entry point when the time comes.\u003C/p>", + { + "headings": 12865, + "localImagePaths": 12875, + "remoteImagePaths": 12876, + "frontmatter": 12877, + "imagePaths": 12878 + }, + [12866, 12868, 12869, 12870, 12871, 12872, 12873, 12874], + { "depth": 30, "slug": 12867, "text": 12855 }, + "parallel-path-comparison", + { "depth": 33, "slug": 12653, "text": 12654 }, + { "depth": 33, "slug": 12656, "text": 12657 }, + { "depth": 33, "slug": 12659, "text": 12660 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + { "depth": 33, "slug": 2523, "text": 2524 }, + { "depth": 33, "slug": 12667, "text": 12668 }, + [], + [], + { "title": 12855 }, + [], + "01-vision/evaluations/patterns/small-multiples", + { + "id": 12879, + "data": 12881, + "body": 12886, + "filePath": 12887, + "digest": 12888, + "rendered": 12889 + }, + { + "title": 12882, + "editUrl": 16, + "head": 12883, + "template": 18, + "sidebar": 12884, + "pagefind": 16, + "draft": 20 + }, + "Small Multiples", + [], + { "hidden": 20, "attrs": 12885 }, + {}, + "# Small Multiples\n\n> Show all factor-by-value combinations as a grid of mini-charts.\n\n## The Concept\n\nA grid of small charts --- one per factor level --- showing the same metric (e.g., measurement values, I-Chart, boxplot) across all levels simultaneously. For a factor with 5 machines, the display shows 5 mini-charts side by side. The analyst reads the grid visually: which chart looks different? Where is the spread wider? Where does the center shift?\n\nSmall multiples are a Tufte-endorsed pattern for visual comparison. They leverage the human visual system's ability to spot pattern breaks across a grid. The analyst doesn't need to click or filter --- the comparison is immediate and spatial. Each mini-chart is too small for detailed reading but perfect for spotting outliers and trends.\n\nThe scaling problem is quadratic. A single factor with 5 levels produces 5 mini-charts --- manageable. Two factors with 5 levels each produce 25 mini-charts (5x5 grid) --- still readable on a large screen. Three factors or more produce hundreds of cells --- overwhelming and unreadable. For the 2--4 factor datasets common in quality analysis, small multiples work well. For datasets with many factors or many levels per factor, they collapse under their own combinatorial weight.\n\nAn additional challenge is mobile display. A grid of mini-charts is inherently hostile to narrow screens. Each chart needs minimum dimensions to be readable, and a 5-column grid on a phone screen produces charts too small to convey meaning.\n\n## Tensions Addressed\n\n- [Factor Ordering](../tensions/factor-ordering.md) --- Partially addressed. All factor levels are visible simultaneously, so the analyst doesn't need to choose a drill order. But the analyst still needs to choose _which factor_ to display as the grid dimension.\n- [Path Dependency](../tensions/path-dependency.md) --- Partially addressed. Small multiples show all levels at once, removing the sequential narrative that creates path dependency for a single factor.\n- [Mobile Screen Budget](../tensions/mobile-screen-budget.md) --- Worsens significantly. Grids are the most screen-hungry visualization pattern.\n\n## Philosophy Alignment\n\n- **EDA for process improvement**: Aligned. Small multiples are a classic EDA technique. Visual comparison across levels is pure exploratory analysis --- the analyst reads patterns, not numbers.\n- **Guided frustration pedagogy**: Compatible. The grid doesn't solve the problem; it presents all the data for the analyst to find the pattern. The \"frustration\" is still present --- the analyst must identify which mini-chart is different.\n- **Four Lenses coordination**: Extends naturally. Small multiples could show I-Charts, Boxplots, or Capability histograms across factor levels. The question is which lens to use for the grid.\n- **Two Voices**: Neutral. The grid pattern is agnostic to whether the metric is process-voice or customer-voice.\n\n## Persona Impact\n\n| Persona | Effect | Why |\n| --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | Positive | Gary finds visual comparison intuitive. Small multiples match how he thinks about machine-to-machine or shift-to-shift comparisons. |\n| Student Sara | Positive | Sara sees all the data at once and can practice pattern recognition. The grid is a natural teaching format for \"spot the difference.\" |\n| OpEx Olivia | Neutral | Useful for presentations and team discussions where everyone can see the comparison, but may require large screens for readability. |\n| Trainer Tina | Positive | Tina can project the grid in class and ask \"which chart is the outlier?\" as an exercise. Excellent teaching tool for low-factor datasets. |\n| Evaluator Erik | Neutral | Adds to the feature list but doesn't affect security or deployment evaluation. |\n| Curious Carlos | Neutral | Carlos may find the grid visually engaging but might not know how to interpret it without guidance. |\n\n## Platform Fit\n\n| Platform | Fit | Notes |\n| ------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |\n| PWA (free training) | Good (with limits) | Excellent for 2--3 factor datasets used in training. Should be limited to low-dimensional data with a clear \"too many levels\" fallback. |\n| Azure (paid team) | Good | Professional teams work on large screens where grids are readable. Should handle higher factor counts gracefully. |\n| Excel Add-in | Poor | The content pane's fixed dimensions make grids impractical. The slicer-based workflow already provides factor-level filtering. |\n\n## Competitive Landscape\n\n- **Tableau**: Small multiples are natively supported through the rows and columns shelves. Dragging a dimension to rows creates a grid of charts — one per dimension value. Any chart type can be faceted. This is one of Tableau's strongest features for visual comparison, and the benchmark implementation for small multiples in analytics tools. See [Tableau Benchmark](../competitive/tableau-benchmark.md).\n- **JMP**: Graph Builder supports faceting through the Wrap and Overlay roles. Dragging a variable to Wrap creates a grid of charts across variable levels. Combined with the Group role, JMP can create multi-dimensional faceted displays. The implementation is flexible but requires the analyst to understand Graph Builder's role system. See [JMP Benchmark](../competitive/jmp-benchmark.md).\n- **Minitab**: Multi-vari charts are a purpose-built small multiples visualization with statistical overlays — factor levels on the X axis, with nested grouping variables shown as connected lines. The chart is specifically designed for comparing variation patterns across factors, making it the most statistically focused small multiples implementation among competitors. However, it's accessed as a separate analysis, not integrated into a drill-down workflow. See [Minitab Benchmark](../competitive/minitab-benchmark.md).\n- **Power BI**: Small multiples were added in 2021 as a standard visual option. The analyst drags a dimension to the \"Small multiples\" field well, and the selected chart type replicates across dimension values in a grid layout. The implementation is functional but less flexible than Tableau's shelf approach — grid layout options are more constrained. See [Power BI Benchmark](../competitive/powerbi-benchmark.md).\n\nSmall multiples are an established pattern in the industry. VariScout's version would integrate them with the progressive stratification workflow --- the grid would show mini-versions of the Four Lenses charts, coordinated with the drill-down state.\n\n## Strategic Verdict\n\n**Defer** --- Small multiples are valuable for low-dimensional datasets and teaching contexts. However, they don't address the highest-priority tensions (hierarchy assumption, discoverability) and scale poorly with factor count. Build this as a supplementary view after the core drill-down improvements (factor suggestion, interaction heatmap) are in place. Limit initial implementation to single-factor grids with a maximum of 8 levels.", + "src/content/docs/01-vision/evaluations/patterns/small-multiples.md", + "9a187ac425bb870b", + { "html": 12890, "metadata": 12891 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"small-multiples\">Small Multiples\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#small-multiples\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Small Multiples”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Show all factor-by-value combinations as a grid of mini-charts.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-concept\">The Concept\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-concept\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Concept”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>A grid of small charts --- one per factor level --- showing the same metric (e.g., measurement values, I-Chart, boxplot) across all levels simultaneously. For a factor with 5 machines, the display shows 5 mini-charts side by side. The analyst reads the grid visually: which chart looks different? Where is the spread wider? Where does the center shift?\u003C/p>\n\u003Cp>Small multiples are a Tufte-endorsed pattern for visual comparison. They leverage the human visual system’s ability to spot pattern breaks across a grid. The analyst doesn’t need to click or filter --- the comparison is immediate and spatial. Each mini-chart is too small for detailed reading but perfect for spotting outliers and trends.\u003C/p>\n\u003Cp>The scaling problem is quadratic. A single factor with 5 levels produces 5 mini-charts --- manageable. Two factors with 5 levels each produce 25 mini-charts (5x5 grid) --- still readable on a large screen. Three factors or more produce hundreds of cells --- overwhelming and unreadable. For the 2—4 factor datasets common in quality analysis, small multiples work well. For datasets with many factors or many levels per factor, they collapse under their own combinatorial weight.\u003C/p>\n\u003Cp>An additional challenge is mobile display. A grid of mini-charts is inherently hostile to narrow screens. Each chart needs minimum dimensions to be readable, and a 5-column grid on a phone screen produces charts too small to convey meaning.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"tensions-addressed\">Tensions Addressed\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#tensions-addressed\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tensions Addressed”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../tensions/factor-ordering.md\">Factor Ordering\u003C/a> --- Partially addressed. All factor levels are visible simultaneously, so the analyst doesn’t need to choose a drill order. But the analyst still needs to choose \u003Cem>which factor\u003C/em> to display as the grid dimension.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/path-dependency.md\">Path Dependency\u003C/a> --- Partially addressed. Small multiples show all levels at once, removing the sequential narrative that creates path dependency for a single factor.\u003C/li>\n\u003Cli>\u003Ca href=\"../tensions/mobile-screen-budget.md\">Mobile Screen Budget\u003C/a> --- Worsens significantly. Grids are the most screen-hungry visualization pattern.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"philosophy-alignment\">Philosophy Alignment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#philosophy-alignment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Philosophy Alignment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>EDA for process improvement\u003C/strong>: Aligned. Small multiples are a classic EDA technique. Visual comparison across levels is pure exploratory analysis --- the analyst reads patterns, not numbers.\u003C/li>\n\u003Cli>\u003Cstrong>Guided frustration pedagogy\u003C/strong>: Compatible. The grid doesn’t solve the problem; it presents all the data for the analyst to find the pattern. The “frustration” is still present --- the analyst must identify which mini-chart is different.\u003C/li>\n\u003Cli>\u003Cstrong>Four Lenses coordination\u003C/strong>: Extends naturally. Small multiples could show I-Charts, Boxplots, or Capability histograms across factor levels. The question is which lens to use for the grid.\u003C/li>\n\u003Cli>\u003Cstrong>Two Voices\u003C/strong>: Neutral. The grid pattern is agnostic to whether the metric is process-voice or customer-voice.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Effect\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Gary finds visual comparison intuitive. Small multiples match how he thinks about machine-to-machine or shift-to-shift comparisons.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Sara sees all the data at once and can practice pattern recognition. The grid is a natural teaching format for “spot the difference.”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Useful for presentations and team discussions where everyone can see the comparison, but may require large screens for readability.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Positive\u003C/td>\u003Ctd>Tina can project the grid in class and ask “which chart is the outlier?” as an exercise. Excellent teaching tool for low-factor datasets.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Adds to the feature list but doesn’t affect security or deployment evaluation.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Neutral\u003C/td>\u003Ctd>Carlos may find the grid visually engaging but might not know how to interpret it without guidance.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"platform-fit\">Platform Fit\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#platform-fit\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Platform Fit”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Platform\u003C/th>\u003Cth>Fit\u003C/th>\u003Cth>Notes\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>PWA (free training)\u003C/td>\u003Ctd>Good (with limits)\u003C/td>\u003Ctd>Excellent for 2—3 factor datasets used in training. Should be limited to low-dimensional data with a clear “too many levels” fallback.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Azure (paid team)\u003C/td>\u003Ctd>Good\u003C/td>\u003Ctd>Professional teams work on large screens where grids are readable. Should handle higher factor counts gracefully.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel Add-in\u003C/td>\u003Ctd>Poor\u003C/td>\u003Ctd>The content pane’s fixed dimensions make grids impractical. The slicer-based workflow already provides factor-level filtering.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"competitive-landscape\">Competitive Landscape\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#competitive-landscape\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Competitive Landscape”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Tableau\u003C/strong>: Small multiples are natively supported through the rows and columns shelves. Dragging a dimension to rows creates a grid of charts — one per dimension value. Any chart type can be faceted. This is one of Tableau’s strongest features for visual comparison, and the benchmark implementation for small multiples in analytics tools. See \u003Ca href=\"../competitive/tableau-benchmark.md\">Tableau Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>JMP\u003C/strong>: Graph Builder supports faceting through the Wrap and Overlay roles. Dragging a variable to Wrap creates a grid of charts across variable levels. Combined with the Group role, JMP can create multi-dimensional faceted displays. The implementation is flexible but requires the analyst to understand Graph Builder’s role system. See \u003Ca href=\"../competitive/jmp-benchmark.md\">JMP Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Minitab\u003C/strong>: Multi-vari charts are a purpose-built small multiples visualization with statistical overlays — factor levels on the X axis, with nested grouping variables shown as connected lines. The chart is specifically designed for comparing variation patterns across factors, making it the most statistically focused small multiples implementation among competitors. However, it’s accessed as a separate analysis, not integrated into a drill-down workflow. See \u003Ca href=\"../competitive/minitab-benchmark.md\">Minitab Benchmark\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Power BI\u003C/strong>: Small multiples were added in 2021 as a standard visual option. The analyst drags a dimension to the “Small multiples” field well, and the selected chart type replicates across dimension values in a grid layout. The implementation is functional but less flexible than Tableau’s shelf approach — grid layout options are more constrained. See \u003Ca href=\"../competitive/powerbi-benchmark.md\">Power BI Benchmark\u003C/a>.\u003C/li>\n\u003C/ul>\n\u003Cp>Small multiples are an established pattern in the industry. VariScout’s version would integrate them with the progressive stratification workflow --- the grid would show mini-versions of the Four Lenses charts, coordinated with the drill-down state.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-verdict\">Strategic Verdict\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-verdict\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Verdict”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Defer\u003C/strong> --- Small multiples are valuable for low-dimensional datasets and teaching contexts. However, they don’t address the highest-priority tensions (hierarchy assumption, discoverability) and scale poorly with factor count. Build this as a supplementary view after the core drill-down improvements (factor suggestion, interaction heatmap) are in place. Limit initial implementation to single-factor grids with a maximum of 8 levels.\u003C/p>", + { + "headings": 12892, + "localImagePaths": 12902, + "remoteImagePaths": 12903, + "frontmatter": 12904, + "imagePaths": 12905 + }, + [12893, 12895, 12896, 12897, 12898, 12899, 12900, 12901], + { "depth": 30, "slug": 12894, "text": 12882 }, + "small-multiples", + { "depth": 33, "slug": 12653, "text": 12654 }, + { "depth": 33, "slug": 12656, "text": 12657 }, + { "depth": 33, "slug": 12659, "text": 12660 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 4936, "text": 4937 }, + { "depth": 33, "slug": 2523, "text": 2524 }, + { "depth": 33, "slug": 12667, "text": 12668 }, + [], + [], + { "title": 12882 }, + [], + "01-vision/evaluations/tensions/discoverability", + { + "id": 12906, + "data": 12908, + "body": 12913, + "filePath": 12914, + "digest": 12915, + "rendered": 12916 + }, + { + "title": 12909, + "editUrl": 16, + "head": 12910, + "template": 18, + "sidebar": 12911, + "pagefind": 16, + "draft": 20 + }, + "Discoverability", + [], + { "hidden": 20, "attrs": 12912 }, + {}, + "# Discoverability\n\n> The entire progressive stratification system starts with clicking a boxplot bar --- if the analyst doesn't know to click, the most powerful feature is invisible.\n\n## The Tension\n\nVariScout's drill-down is triggered by interacting with chart elements: clicking a boxplot bar, selecting a Pareto category, or using the filter chip dropdown. This design choice is intentional --- it integrates filtering into the analytical flow rather than separating it into a control panel. The analyst discovers patterns _and_ acts on them in the same visual space.\n\nBut this integration comes at a discoverability cost. A first-time user sees four static charts and may never realize they're interactive. The boxplot bars don't visually signal \"click me\" in the way a button or menu would. The variation funnel exists as an alternative entry point and progress tracker, but it's behind an icon in the toolbar --- itself a discoverable-only-if-you-look feature. The result is that VariScout's most powerful capability is also its most hidden.\n\nThis is particularly acute because the drill-down is what differentiates VariScout from simpler charting tools. Without discovering it, the user sees a competent but unremarkable SPC dashboard. With it, they have a systematic variation investigation methodology. The gap between \"never discovered drill-down\" and \"uses drill-down fluently\" is the gap between a user who churns and a user who becomes an advocate.\n\n## Persona Impact\n\n| Persona | Impact | Why |\n| --------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | High | Gary is evaluating tools. If he doesn't discover the drill-down in his first session, he may conclude VariScout is \"just another chart tool\" and move on. |\n| Student Sara | Medium | Sara often arrives via instructor guidance, which may include explicit instructions to click the boxplot. Her discovery path is mediated by course materials. |\n| OpEx Olivia | Medium | Olivia evaluates based on team capability, not personal exploration. If one team member discovers the drill-down and demonstrates it, the discovery gap is bridged socially. |\n| Trainer Tina | Low | Tina is an expert who explores tools thoroughly. She'll discover the drill-down quickly --- but she may worry about her students' ability to find it independently. |\n| Evaluator Erik | Low | Erik evaluates security and deployment, not interaction patterns. However, a demo that fails to showcase the drill-down would weaken the case he's evaluating. |\n| Curious Carlos | High | Carlos arrives from social media with short attention. If the case study demo doesn't guide him to click, he'll see static charts and bounce. |\n\n## Current Mitigation\n\n- The variation funnel icon in the toolbar provides an alternative entry point.\n- Case study demos on the website walk through the drill-down step by step.\n- Sample datasets load with pre-configured views that hint at interactivity.\n- Tooltips appear on hover over boxplot bars (desktop only).\n\n## Strategic Weight\n\n**High** --- Discoverability directly impacts conversion and retention. The drill-down is both the primary differentiator and the hardest feature to find. Every user who doesn't discover it represents a missed opportunity for the product to demonstrate its value.\n\n## Related Patterns\n\n- [Sidebar Filter Panel](../patterns/sidebar-filter-panel.md) --- Always-visible filters solve discoverability entirely but sacrifice analytical flow integration.\n- [Factor Suggestion](../patterns/factor-suggestion.md) --- An explicit prompt (\"Try clicking Machine next\") could guide first-time users.\n- [Factor Map](../patterns/factor-map.md) --- A spatial overview could serve as a more discoverable entry point than chart-embedded interactions.", + "src/content/docs/01-vision/evaluations/tensions/discoverability.md", + "bd431868d4273d4c", + { "html": 12917, "metadata": 12918 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"discoverability\">Discoverability\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#discoverability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Discoverability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>The entire progressive stratification system starts with clicking a boxplot bar --- if the analyst doesn’t know to click, the most powerful feature is invisible.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-tension\">The Tension\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-tension\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Tension”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s drill-down is triggered by interacting with chart elements: clicking a boxplot bar, selecting a Pareto category, or using the filter chip dropdown. This design choice is intentional --- it integrates filtering into the analytical flow rather than separating it into a control panel. The analyst discovers patterns \u003Cem>and\u003C/em> acts on them in the same visual space.\u003C/p>\n\u003Cp>But this integration comes at a discoverability cost. A first-time user sees four static charts and may never realize they’re interactive. The boxplot bars don’t visually signal “click me” in the way a button or menu would. The variation funnel exists as an alternative entry point and progress tracker, but it’s behind an icon in the toolbar --- itself a discoverable-only-if-you-look feature. The result is that VariScout’s most powerful capability is also its most hidden.\u003C/p>\n\u003Cp>This is particularly acute because the drill-down is what differentiates VariScout from simpler charting tools. Without discovering it, the user sees a competent but unremarkable SPC dashboard. With it, they have a systematic variation investigation methodology. The gap between “never discovered drill-down” and “uses drill-down fluently” is the gap between a user who churns and a user who becomes an advocate.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Impact\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Gary is evaluating tools. If he doesn’t discover the drill-down in his first session, he may conclude VariScout is “just another chart tool” and move on.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Sara often arrives via instructor guidance, which may include explicit instructions to click the boxplot. Her discovery path is mediated by course materials.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Olivia evaluates based on team capability, not personal exploration. If one team member discovers the drill-down and demonstrates it, the discovery gap is bridged socially.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Tina is an expert who explores tools thoroughly. She’ll discover the drill-down quickly --- but she may worry about her students’ ability to find it independently.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Erik evaluates security and deployment, not interaction patterns. However, a demo that fails to showcase the drill-down would weaken the case he’s evaluating.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Carlos arrives from social media with short attention. If the case study demo doesn’t guide him to click, he’ll see static charts and bounce.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"current-mitigation\">Current Mitigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#current-mitigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Current Mitigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>The variation funnel icon in the toolbar provides an alternative entry point.\u003C/li>\n\u003Cli>Case study demos on the website walk through the drill-down step by step.\u003C/li>\n\u003Cli>Sample datasets load with pre-configured views that hint at interactivity.\u003C/li>\n\u003Cli>Tooltips appear on hover over boxplot bars (desktop only).\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-weight\">Strategic Weight\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-weight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Weight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>High\u003C/strong> --- Discoverability directly impacts conversion and retention. The drill-down is both the primary differentiator and the hardest feature to find. Every user who doesn’t discover it represents a missed opportunity for the product to demonstrate its value.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-patterns\">Related Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../patterns/sidebar-filter-panel.md\">Sidebar Filter Panel\u003C/a> --- Always-visible filters solve discoverability entirely but sacrifice analytical flow integration.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/factor-suggestion.md\">Factor Suggestion\u003C/a> --- An explicit prompt (“Try clicking Machine next”) could guide first-time users.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/factor-map.md\">Factor Map\u003C/a> --- A spatial overview could serve as a more discoverable entry point than chart-embedded interactions.\u003C/li>\n\u003C/ul>", + { + "headings": 12919, + "localImagePaths": 12935, + "remoteImagePaths": 12936, + "frontmatter": 12937, + "imagePaths": 12938 + }, + [12920, 12922, 12925, 12926, 12929, 12932], + { "depth": 30, "slug": 12921, "text": 12909 }, + "discoverability", + { "depth": 33, "slug": 12923, "text": 12924 }, + "the-tension", + "The Tension", + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 12927, "text": 12928 }, + "current-mitigation", + "Current Mitigation", + { "depth": 33, "slug": 12930, "text": 12931 }, + "strategic-weight", + "Strategic Weight", + { "depth": 33, "slug": 12933, "text": 12934 }, + "related-patterns", + "Related Patterns", + [], + [], + { "title": 12909 }, + [], + "01-vision/evaluations/tensions/factor-ordering", + { + "id": 12939, + "data": 12941, + "body": 12946, + "filePath": 12947, + "digest": 12948, + "rendered": 12949 + }, + { + "title": 12942, + "editUrl": 16, + "head": 12943, + "template": 18, + "sidebar": 12944, + "pagefind": 16, + "draft": 20 + }, + "Factor Ordering", + [], + { "hidden": 20, "attrs": 12945 }, + {}, + "# Factor Ordering\n\n> The analyst chooses which factor to drill next --- there's a tension between guided and exploratory interaction.\n\n## The Tension\n\nThe Boxplot shows eta-squared for each factor, which implicitly suggests the highest-eta-squared factor is the best next drill target. But \"implicitly suggests\" is doing a lot of work. The analyst may not read eta-squared values fluently. They may have domain knowledge that makes a different factor more interesting (\"I know we changed suppliers last month --- let me check Material first\"). Or they may simply click whatever catches their eye.\n\nThis creates a tension between two valid design philosophies. A **guided** approach would highlight the recommended next factor: \"Machine explains 45% of remaining variation --- drill here.\" This reduces analyst guesswork and helps novices make statistically sound choices. An **exploratory** approach leaves the decision entirely to the analyst, trusting their domain knowledge and curiosity to drive the investigation.\n\nThe current design leans exploratory: eta-squared is displayed but no explicit recommendation is made. This aligns with the EDA philosophy --- the analyst is the investigator, not the tool. But it also means that an analyst who doesn't understand eta-squared (or doesn't notice it) may drill suboptimal factors, reach weak conclusions, and blame the tool rather than their approach.\n\n## Persona Impact\n\n| Persona | Impact | Why |\n| --------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | High | Gary understands eta-squared from training but may not instinctively use it as a navigation guide. He'd benefit from a gentle nudge without losing his sense of agency. |\n| Student Sara | High | Sara is learning the methodology. Without guidance, she may drill randomly and not understand why her results are weak. Explicit suggestions would accelerate her learning. |\n| OpEx Olivia | Medium | Olivia's team members vary in skill. Guided ordering would make the tool more consistent across different analysts in her organization. |\n| Trainer Tina | Medium | Tina wants students to think about factor selection, not just follow prompts. Too much guidance undermines the Sock Mystery pedagogy. She'd prefer guidance that's optional. |\n| Evaluator Erik | Low | Factor ordering is an analytical workflow detail that doesn't affect Erik's evaluation criteria. |\n| Curious Carlos | Medium | Carlos has domain knowledge but no statistical training. Guidance would help him make better choices, but he also trusts his gut about \"what matters\" in his process. |\n\n## Current Mitigation\n\n- Eta-squared values are displayed numerically on boxplot bars.\n- The variation funnel shows cumulative progress, indirectly indicating whether current drilling is effective.\n- The help tooltip system provides explanations of eta-squared on hover.\n\n## Strategic Weight\n\n**Medium** --- Factor ordering affects analysis quality but not fundamental tool usability. The current design works well for trained users and fails gracefully for novices (they still get results, just less optimal ones). The risk is reputational: a novice who drills poorly may conclude the methodology doesn't work.\n\n## Related Patterns\n\n- [Factor Suggestion](../patterns/factor-suggestion.md) --- Directly addresses this by highlighting the recommended next factor.\n- [Auto-Combination Finder](../patterns/auto-combination-finder.md) --- Bypasses factor ordering entirely by starting from the optimal combination.\n- [Factor Map](../patterns/factor-map.md) --- Visual factor sizing by eta-squared makes the recommendation spatial and intuitive rather than numerical.", + "src/content/docs/01-vision/evaluations/tensions/factor-ordering.md", + "4d044ccbd8afd574", + { "html": 12950, "metadata": 12951 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"factor-ordering\">Factor Ordering\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#factor-ordering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Factor Ordering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>The analyst chooses which factor to drill next --- there’s a tension between guided and exploratory interaction.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-tension\">The Tension\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-tension\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Tension”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The Boxplot shows eta-squared for each factor, which implicitly suggests the highest-eta-squared factor is the best next drill target. But “implicitly suggests” is doing a lot of work. The analyst may not read eta-squared values fluently. They may have domain knowledge that makes a different factor more interesting (“I know we changed suppliers last month --- let me check Material first”). Or they may simply click whatever catches their eye.\u003C/p>\n\u003Cp>This creates a tension between two valid design philosophies. A \u003Cstrong>guided\u003C/strong> approach would highlight the recommended next factor: “Machine explains 45% of remaining variation --- drill here.” This reduces analyst guesswork and helps novices make statistically sound choices. An \u003Cstrong>exploratory\u003C/strong> approach leaves the decision entirely to the analyst, trusting their domain knowledge and curiosity to drive the investigation.\u003C/p>\n\u003Cp>The current design leans exploratory: eta-squared is displayed but no explicit recommendation is made. This aligns with the EDA philosophy --- the analyst is the investigator, not the tool. But it also means that an analyst who doesn’t understand eta-squared (or doesn’t notice it) may drill suboptimal factors, reach weak conclusions, and blame the tool rather than their approach.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Impact\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Gary understands eta-squared from training but may not instinctively use it as a navigation guide. He’d benefit from a gentle nudge without losing his sense of agency.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Sara is learning the methodology. Without guidance, she may drill randomly and not understand why her results are weak. Explicit suggestions would accelerate her learning.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Olivia’s team members vary in skill. Guided ordering would make the tool more consistent across different analysts in her organization.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Tina wants students to think about factor selection, not just follow prompts. Too much guidance undermines the Sock Mystery pedagogy. She’d prefer guidance that’s optional.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Factor ordering is an analytical workflow detail that doesn’t affect Erik’s evaluation criteria.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Carlos has domain knowledge but no statistical training. Guidance would help him make better choices, but he also trusts his gut about “what matters” in his process.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"current-mitigation\">Current Mitigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#current-mitigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Current Mitigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Eta-squared values are displayed numerically on boxplot bars.\u003C/li>\n\u003Cli>The variation funnel shows cumulative progress, indirectly indicating whether current drilling is effective.\u003C/li>\n\u003Cli>The help tooltip system provides explanations of eta-squared on hover.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-weight\">Strategic Weight\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-weight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Weight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Medium\u003C/strong> --- Factor ordering affects analysis quality but not fundamental tool usability. The current design works well for trained users and fails gracefully for novices (they still get results, just less optimal ones). The risk is reputational: a novice who drills poorly may conclude the methodology doesn’t work.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-patterns\">Related Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../patterns/factor-suggestion.md\">Factor Suggestion\u003C/a> --- Directly addresses this by highlighting the recommended next factor.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/auto-combination-finder.md\">Auto-Combination Finder\u003C/a> --- Bypasses factor ordering entirely by starting from the optimal combination.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/factor-map.md\">Factor Map\u003C/a> --- Visual factor sizing by eta-squared makes the recommendation spatial and intuitive rather than numerical.\u003C/li>\n\u003C/ul>", + { + "headings": 12952, + "localImagePaths": 12960, + "remoteImagePaths": 12961, + "frontmatter": 12962, + "imagePaths": 12963 + }, + [12953, 12955, 12956, 12957, 12958, 12959], + { "depth": 30, "slug": 12954, "text": 12942 }, + "factor-ordering", + { "depth": 33, "slug": 12923, "text": 12924 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 12927, "text": 12928 }, + { "depth": 33, "slug": 12930, "text": 12931 }, + { "depth": 33, "slug": 12933, "text": 12934 }, + [], + [], + { "title": 12942 }, + [], + "01-vision/evaluations/tensions/hierarchy-assumption", + { + "id": 12964, + "data": 12966, + "body": 12971, + "filePath": 12972, + "digest": 12973, + "rendered": 12974 + }, + { + "title": 12967, + "editUrl": 16, + "head": 12968, + "template": 18, + "sidebar": 12969, + "pagefind": 16, + "draft": 20 + }, + "Hierarchy Assumption", + [], + { "hidden": 20, "attrs": 12970 }, + {}, + "# Hierarchy Assumption\n\n> The sequential one-factor-at-a-time drill-down captures main effects but may miss interaction effects between factors.\n\n## The Tension\n\nProgressive stratification works by drilling into the highest-impact factor at each step, treating each factor as an independent contributor to total variation. This is analogous to a greedy search: pick the largest signal, filter, repeat. For main effects --- where a single factor independently drives variation --- this converges reliably on the right answer.\n\nBut factors can interact. \"Machine C is only problematic on Night Shift\" is an interaction effect that the one-factor-at-a-time approach may miss entirely. If Machine C looks average across all shifts, the drill-down would never highlight it. The problem only surfaces when you look at Machine C _within_ Night Shift, or Night Shift _within_ Machine C. The sequential approach can't see this unless the analyst happens to drill both factors in the right order and notices the pattern in the intermediate step.\n\nVariScout's regression panel handles interaction analysis. The Investigation Mindmap's Interaction mode visually surfaces factor-by-factor interaction edges (with delta-R², p-value, and standardized beta) when 2+ factors are in the drill stack, bridging the gap between the drill-down's main-effects focus and the regression panel's interaction capability. Action buttons in both the ConclusionPanel (\"Refine in Regression\") and the EdgeTooltip (\"Model in Regression\") navigate directly to the Regression Panel with investigated factors pre-populated.\n\n## Persona Impact\n\n| Persona | Impact | Why |\n| --------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | High | Gary knows about interactions from training but may not think to check for them during an exploratory drill-down. He could reach a confident but incomplete conclusion. |\n| Student Sara | Medium | Sara is learning the methodology and may not understand interaction effects yet. The drill-down teaches one-factor thinking, which is pedagogically correct as a starting point. |\n| OpEx Olivia | High | Olivia needs comprehensive answers for improvement projects. Missing an interaction means deploying resources to the wrong root cause. |\n| Trainer Tina | Medium | Tina understands the limitation and can teach around it, but she'd prefer the tool to surface interactions more naturally rather than requiring a separate workflow. |\n| Evaluator Erik | Low | Erik evaluates security and deployment, not analytical depth. This tension doesn't affect his evaluation criteria. |\n| Curious Carlos | Low | Carlos is exploring and discovering patterns. Interaction effects are too advanced for his current journey --- finding main effects is already valuable. |\n\n## Current Mitigation\n\n- The Investigation Mindmap's **Interaction mode** (available when 2+ factors are drilled) visually shows interaction edges between factors with delta-R², p-value, and standardized beta.\n- The **ConclusionPanel** \"Refine in Regression\" button navigates to the Regression Panel with investigated factors pre-populated as predictors.\n- The **EdgeTooltip** \"Model in Regression\" button (in Interaction mode) navigates to the Regression Panel with the specific interaction pair pre-populated.\n- The Regression Panel's **AdvancedRegressionView** shows a \"Project in What-If\" button when all terms are significant, completing the investigation-to-action chain.\n- Multi-select in filter chips allows the analyst to manually explore two-factor combinations.\n\n## Strategic Weight\n\n**Medium** --- Interaction effects are common in real manufacturing and service processes. The Investigation Mindmap's Interaction mode now provides visual detection and direct navigation to regression, reducing the reliance on analyst initiative. The remaining gap is that the analyst must still switch to Interaction mode rather than being automatically alerted.\n\n## Related Patterns\n\n- [Interaction Heatmap](../patterns/interaction-heatmap.md) --- Directly addresses this by showing factor-by-factor interaction strength before drilling.\n- [Auto-Combination Finder](../patterns/auto-combination-finder.md) --- The regression engine could surface interaction-driven combinations automatically.\n- [Factor Map](../patterns/factor-map.md) --- Network visualization could show interaction links between factors.", + "src/content/docs/01-vision/evaluations/tensions/hierarchy-assumption.md", + "a2b034a35c1caa58", + { "html": 12975, "metadata": 12976 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"hierarchy-assumption\">Hierarchy Assumption\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#hierarchy-assumption\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Hierarchy Assumption”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>The sequential one-factor-at-a-time drill-down captures main effects but may miss interaction effects between factors.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-tension\">The Tension\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-tension\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Tension”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Progressive stratification works by drilling into the highest-impact factor at each step, treating each factor as an independent contributor to total variation. This is analogous to a greedy search: pick the largest signal, filter, repeat. For main effects --- where a single factor independently drives variation --- this converges reliably on the right answer.\u003C/p>\n\u003Cp>But factors can interact. “Machine C is only problematic on Night Shift” is an interaction effect that the one-factor-at-a-time approach may miss entirely. If Machine C looks average across all shifts, the drill-down would never highlight it. The problem only surfaces when you look at Machine C \u003Cem>within\u003C/em> Night Shift, or Night Shift \u003Cem>within\u003C/em> Machine C. The sequential approach can’t see this unless the analyst happens to drill both factors in the right order and notices the pattern in the intermediate step.\u003C/p>\n\u003Cp>VariScout’s regression panel handles interaction analysis. The Investigation Mindmap’s Interaction mode visually surfaces factor-by-factor interaction edges (with delta-R², p-value, and standardized beta) when 2+ factors are in the drill stack, bridging the gap between the drill-down’s main-effects focus and the regression panel’s interaction capability. Action buttons in both the ConclusionPanel (“Refine in Regression”) and the EdgeTooltip (“Model in Regression”) navigate directly to the Regression Panel with investigated factors pre-populated.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Impact\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Gary knows about interactions from training but may not think to check for them during an exploratory drill-down. He could reach a confident but incomplete conclusion.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Sara is learning the methodology and may not understand interaction effects yet. The drill-down teaches one-factor thinking, which is pedagogically correct as a starting point.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Olivia needs comprehensive answers for improvement projects. Missing an interaction means deploying resources to the wrong root cause.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Tina understands the limitation and can teach around it, but she’d prefer the tool to surface interactions more naturally rather than requiring a separate workflow.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Erik evaluates security and deployment, not analytical depth. This tension doesn’t affect his evaluation criteria.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Carlos is exploring and discovering patterns. Interaction effects are too advanced for his current journey --- finding main effects is already valuable.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"current-mitigation\">Current Mitigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#current-mitigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Current Mitigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>The Investigation Mindmap’s \u003Cstrong>Interaction mode\u003C/strong> (available when 2+ factors are drilled) visually shows interaction edges between factors with delta-R², p-value, and standardized beta.\u003C/li>\n\u003Cli>The \u003Cstrong>ConclusionPanel\u003C/strong> “Refine in Regression” button navigates to the Regression Panel with investigated factors pre-populated as predictors.\u003C/li>\n\u003Cli>The \u003Cstrong>EdgeTooltip\u003C/strong> “Model in Regression” button (in Interaction mode) navigates to the Regression Panel with the specific interaction pair pre-populated.\u003C/li>\n\u003Cli>The Regression Panel’s \u003Cstrong>AdvancedRegressionView\u003C/strong> shows a “Project in What-If” button when all terms are significant, completing the investigation-to-action chain.\u003C/li>\n\u003Cli>Multi-select in filter chips allows the analyst to manually explore two-factor combinations.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-weight\">Strategic Weight\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-weight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Weight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Medium\u003C/strong> --- Interaction effects are common in real manufacturing and service processes. The Investigation Mindmap’s Interaction mode now provides visual detection and direct navigation to regression, reducing the reliance on analyst initiative. The remaining gap is that the analyst must still switch to Interaction mode rather than being automatically alerted.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-patterns\">Related Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../patterns/interaction-heatmap.md\">Interaction Heatmap\u003C/a> --- Directly addresses this by showing factor-by-factor interaction strength before drilling.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/auto-combination-finder.md\">Auto-Combination Finder\u003C/a> --- The regression engine could surface interaction-driven combinations automatically.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/factor-map.md\">Factor Map\u003C/a> --- Network visualization could show interaction links between factors.\u003C/li>\n\u003C/ul>", + { + "headings": 12977, + "localImagePaths": 12985, + "remoteImagePaths": 12986, + "frontmatter": 12987, + "imagePaths": 12988 + }, + [12978, 12980, 12981, 12982, 12983, 12984], + { "depth": 30, "slug": 12979, "text": 12967 }, + "hierarchy-assumption", + { "depth": 33, "slug": 12923, "text": 12924 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 12927, "text": 12928 }, + { "depth": 33, "slug": 12930, "text": 12931 }, + { "depth": 33, "slug": 12933, "text": 12934 }, + [], + [], + { "title": 12967 }, + [], + "01-vision/evaluations/tensions/mobile-screen-budget", + { + "id": 12989, + "data": 12991, + "body": 12996, + "filePath": 12997, + "digest": 12998, + "rendered": 12999 + }, + { + "title": 12992, + "editUrl": 16, + "head": 12993, + "template": 18, + "sidebar": 12994, + "pagefind": 16, + "draft": 20 + }, + "Mobile Screen Budget", + [], + { "hidden": 20, "attrs": 12995 }, + {}, + "# Mobile Screen Budget\n\n> Filter chips, the variation bar, and four charts all compete for screen space on mobile.\n\n## The Tension\n\nVariScout's drill-down creates a growing UI state: each filter adds a chip, the variation bar updates, and the analyst needs to see both the filtering state and the chart content to make their next decision. On desktop, this is manageable --- chips sit above the charts with room to spare. On mobile, every pixel of filtering UI is a pixel taken from the charts that make filtering meaningful.\n\nThe current design handles this with responsive margins and collapsible sections, but there's an inherent tension between showing the analytical state (active filters, cumulative progress) and showing the analytical content (the charts themselves). A deep drill-down with 3--4 active filter chips, a variation bar, and the factor dropdown can consume a significant portion of the mobile viewport before the chart even appears.\n\nThis tension is compounded by VariScout's four-chart layout. On desktop, four linked charts provide simultaneous multi-lens analysis. On mobile, they stack vertically, requiring scrolling. The analyst can see one chart at a time while the filter state is either always visible (consuming space) or scrolled off-screen (losing context). Neither option fully serves the linked-filtering workflow that makes the drill-down powerful.\n\n## Persona Impact\n\n| Persona | Impact | Why |\n| --------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | Medium | Gary primarily uses desktop at work but may check analyses on his phone. The degraded mobile experience is annoying but not deal-breaking. |\n| Student Sara | High | Sara often uses her phone or a tablet. If the mobile experience is awkward, she may struggle to complete assignments or practice outside the classroom. |\n| OpEx Olivia | Low | Olivia's team uses the Azure App on desktop workstations. Mobile usage is not a primary deployment scenario for enterprise teams. |\n| Trainer Tina | Medium | Tina demos on projectors (desktop) but her students may follow along on phones or tablets. She needs the mobile experience to be functional for classroom use. |\n| Evaluator Erik | Low | Erik evaluates on desktop. Mobile responsiveness is a checkbox item, not a critical evaluation factor. |\n| Curious Carlos | High | Carlos first encounters VariScout on his phone via social media links. If the PWA demo doesn't work well on mobile, he bounces immediately. |\n\n## Current Mitigation\n\n- Responsive chart margins via `useResponsiveChartMargins` hook.\n- Collapsible filter section on mobile.\n- Mobile menu (`MobileMenu.tsx`) consolidates navigation.\n- `useIsMobile` hook enables conditional rendering for screen-constrained layouts.\n\n## Strategic Weight\n\n**Medium** --- Mobile is important for student and social-discovery audiences (Sara, Carlos) but secondary for the primary paid product (Azure App on desktop). The current responsive design is functional but not optimized. Investment should be proportional to the mobile audience's contribution to conversion and retention.\n\n## Related Patterns\n\n- [Sidebar Filter Panel](../patterns/sidebar-filter-panel.md) --- Would make the screen budget problem worse on mobile by adding a persistent panel.\n- [Small Multiples](../patterns/small-multiples.md) --- Grid layouts are inherently hostile to narrow screens.\n- [Factor Map](../patterns/factor-map.md) --- A separate spatial view could decouple the filter state display from chart space, potentially improving mobile by opening filters in a dedicated screen.", + "src/content/docs/01-vision/evaluations/tensions/mobile-screen-budget.md", + "cfe82aa3757a21f8", + { "html": 13000, "metadata": 13001 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"mobile-screen-budget\">Mobile Screen Budget\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#mobile-screen-budget\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Mobile Screen Budget”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Filter chips, the variation bar, and four charts all compete for screen space on mobile.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-tension\">The Tension\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-tension\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Tension”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s drill-down creates a growing UI state: each filter adds a chip, the variation bar updates, and the analyst needs to see both the filtering state and the chart content to make their next decision. On desktop, this is manageable --- chips sit above the charts with room to spare. On mobile, every pixel of filtering UI is a pixel taken from the charts that make filtering meaningful.\u003C/p>\n\u003Cp>The current design handles this with responsive margins and collapsible sections, but there’s an inherent tension between showing the analytical state (active filters, cumulative progress) and showing the analytical content (the charts themselves). A deep drill-down with 3—4 active filter chips, a variation bar, and the factor dropdown can consume a significant portion of the mobile viewport before the chart even appears.\u003C/p>\n\u003Cp>This tension is compounded by VariScout’s four-chart layout. On desktop, four linked charts provide simultaneous multi-lens analysis. On mobile, they stack vertically, requiring scrolling. The analyst can see one chart at a time while the filter state is either always visible (consuming space) or scrolled off-screen (losing context). Neither option fully serves the linked-filtering workflow that makes the drill-down powerful.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Impact\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Gary primarily uses desktop at work but may check analyses on his phone. The degraded mobile experience is annoying but not deal-breaking.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Sara often uses her phone or a tablet. If the mobile experience is awkward, she may struggle to complete assignments or practice outside the classroom.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Olivia’s team uses the Azure App on desktop workstations. Mobile usage is not a primary deployment scenario for enterprise teams.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Tina demos on projectors (desktop) but her students may follow along on phones or tablets. She needs the mobile experience to be functional for classroom use.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Erik evaluates on desktop. Mobile responsiveness is a checkbox item, not a critical evaluation factor.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Carlos first encounters VariScout on his phone via social media links. If the PWA demo doesn’t work well on mobile, he bounces immediately.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"current-mitigation\">Current Mitigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#current-mitigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Current Mitigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Responsive chart margins via \u003Ccode dir=\"auto\">useResponsiveChartMargins\u003C/code> hook.\u003C/li>\n\u003Cli>Collapsible filter section on mobile.\u003C/li>\n\u003Cli>Mobile menu (\u003Ccode dir=\"auto\">MobileMenu.tsx\u003C/code>) consolidates navigation.\u003C/li>\n\u003Cli>\u003Ccode dir=\"auto\">useIsMobile\u003C/code> hook enables conditional rendering for screen-constrained layouts.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-weight\">Strategic Weight\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-weight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Weight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Medium\u003C/strong> --- Mobile is important for student and social-discovery audiences (Sara, Carlos) but secondary for the primary paid product (Azure App on desktop). The current responsive design is functional but not optimized. Investment should be proportional to the mobile audience’s contribution to conversion and retention.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-patterns\">Related Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../patterns/sidebar-filter-panel.md\">Sidebar Filter Panel\u003C/a> --- Would make the screen budget problem worse on mobile by adding a persistent panel.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/small-multiples.md\">Small Multiples\u003C/a> --- Grid layouts are inherently hostile to narrow screens.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/factor-map.md\">Factor Map\u003C/a> --- A separate spatial view could decouple the filter state display from chart space, potentially improving mobile by opening filters in a dedicated screen.\u003C/li>\n\u003C/ul>", + { + "headings": 13002, + "localImagePaths": 13010, + "remoteImagePaths": 13011, + "frontmatter": 13012, + "imagePaths": 13013 + }, + [13003, 13005, 13006, 13007, 13008, 13009], + { "depth": 30, "slug": 13004, "text": 12992 }, + "mobile-screen-budget", + { "depth": 33, "slug": 12923, "text": 12924 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 12927, "text": 12928 }, + { "depth": 33, "slug": 12930, "text": 12931 }, + { "depth": 33, "slug": 12933, "text": 12934 }, + [], + [], + { "title": 12992 }, + [], + "01-vision/evaluations/tensions/path-dependency", + { + "id": 13014, + "data": 13016, + "body": 13021, + "filePath": 13022, + "digest": 13023, + "rendered": 13024 + }, + { + "title": 13017, + "editUrl": 16, + "head": 13018, + "template": 18, + "sidebar": 13019, + "pagefind": 16, + "draft": 20 + }, + "Path Dependency", + [], + { "hidden": 20, "attrs": 13020 }, + {}, + "# Path Dependency\n\n> The order you drill matters for intermediate contribution percentages, even though final results converge.\n\n## The Tension\n\nFiltering by Shift first then Machine gives different intermediate numbers than Machine first then Shift. An analyst who drills Shift first sees \"Shift explains 67%\" and may conclude Shift is the dominant factor. An analyst who drills Machine first sees \"Machine explains 42%\" and draws a different intermediate conclusion. Both reach roughly the same endpoint (the total variation explained by the Shift + Machine combination is similar regardless of order), but the narrative along the way differs.\n\nThis is mathematically correct --- eta-squared is calculated on the current dataset, and filtering changes the dataset. It's the same reason that correlation doesn't imply causation: the order of conditioning matters for conditional probabilities even when the joint probability is the same. But most analysts don't think in terms of conditional decomposition. They think in narratives: \"Shift is the big driver, and within Shift, Machine matters too\" versus \"Machine is the main factor, and within Machine, Shift separates the good from the bad.\"\n\nWhether this is confusing or simply an accurate reflection of how factor contribution depends on context is an open question. For trained analysts, path dependency is expected and informative --- the different intermediate numbers reveal something about the factor structure. For novices, it can feel like the tool is giving inconsistent answers depending on the order they click.\n\n## Persona Impact\n\n| Persona | Impact | Why |\n| --------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| Green Belt Gary | Medium | Gary may notice the order dependency and be confused by it, or he may accept it as inherent to sequential analysis. His reaction depends on how well his training covered conditional decomposition. |\n| Student Sara | High | Sara is learning the methodology and may interpret different intermediate numbers from different paths as the tool being \"wrong\" or unreliable. This could undermine her trust in the analysis. |\n| OpEx Olivia | Medium | If two analysts on Olivia's team reach different intermediate conclusions, it creates alignment problems in team meetings. The final convergence helps but the journey confusion is real. |\n| Trainer Tina | Low | Tina understands path dependency and can use it as a teaching moment: \"Notice how the numbers change depending on order? That's because each factor's contribution depends on what you've already controlled for.\" |\n| Evaluator Erik | Low | Path dependency is an analytical subtlety that doesn't affect Erik's security and deployment evaluation. |\n| Curious Carlos | Medium | Carlos follows his intuition about factor importance. If the tool shows different numbers when he clicks in a different order, he may lose confidence in the results. |\n\n## Current Mitigation\n\n- Contribution percentages are labeled \"% of total variation\" to anchor to the original dataset.\n- The cumulative variation bar shows total progress regardless of path, emphasizing convergence.\n- The variation funnel displays the full drill stack, making the path explicit.\n\n## Strategic Weight\n\n**Low** --- Path dependency is mathematically correct behavior, not a bug. The final results converge, and the intermediate differences are informative for skilled analysts. The risk is primarily pedagogical: novices may be confused. This is better addressed through learning content (glossary, help tooltips) than through UI changes that would mask correct statistical behavior.\n\n## Related Patterns\n\n- [Parallel Path Comparison](../patterns/parallel-path-comparison.md) --- Directly addresses this by showing alternative paths and their convergence or divergence.\n- [Auto-Combination Finder](../patterns/auto-combination-finder.md) --- Bypasses path dependency entirely by jumping straight to the optimal combination.\n- [Factor Map](../patterns/factor-map.md) --- Shows all factors simultaneously without imposing a sequence, making path dependency irrelevant for the initial overview.", + "src/content/docs/01-vision/evaluations/tensions/path-dependency.md", + "586fefba65c92bb8", + { "html": 13025, "metadata": 13026 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"path-dependency\">Path Dependency\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#path-dependency\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Path Dependency”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>The order you drill matters for intermediate contribution percentages, even though final results converge.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-tension\">The Tension\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-tension\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Tension”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Filtering by Shift first then Machine gives different intermediate numbers than Machine first then Shift. An analyst who drills Shift first sees “Shift explains 67%” and may conclude Shift is the dominant factor. An analyst who drills Machine first sees “Machine explains 42%” and draws a different intermediate conclusion. Both reach roughly the same endpoint (the total variation explained by the Shift + Machine combination is similar regardless of order), but the narrative along the way differs.\u003C/p>\n\u003Cp>This is mathematically correct --- eta-squared is calculated on the current dataset, and filtering changes the dataset. It’s the same reason that correlation doesn’t imply causation: the order of conditioning matters for conditional probabilities even when the joint probability is the same. But most analysts don’t think in terms of conditional decomposition. They think in narratives: “Shift is the big driver, and within Shift, Machine matters too” versus “Machine is the main factor, and within Machine, Shift separates the good from the bad.”\u003C/p>\n\u003Cp>Whether this is confusing or simply an accurate reflection of how factor contribution depends on context is an open question. For trained analysts, path dependency is expected and informative --- the different intermediate numbers reveal something about the factor structure. For novices, it can feel like the tool is giving inconsistent answers depending on the order they click.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Impact\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Gary may notice the order dependency and be confused by it, or he may accept it as inherent to sequential analysis. His reaction depends on how well his training covered conditional decomposition.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Sara is learning the methodology and may interpret different intermediate numbers from different paths as the tool being “wrong” or unreliable. This could undermine her trust in the analysis.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>If two analysts on Olivia’s team reach different intermediate conclusions, it creates alignment problems in team meetings. The final convergence helps but the journey confusion is real.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Tina understands path dependency and can use it as a teaching moment: “Notice how the numbers change depending on order? That’s because each factor’s contribution depends on what you’ve already controlled for.”\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Path dependency is an analytical subtlety that doesn’t affect Erik’s security and deployment evaluation.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Carlos follows his intuition about factor importance. If the tool shows different numbers when he clicks in a different order, he may lose confidence in the results.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"current-mitigation\">Current Mitigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#current-mitigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Current Mitigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>Contribution percentages are labeled ”% of total variation” to anchor to the original dataset.\u003C/li>\n\u003Cli>The cumulative variation bar shows total progress regardless of path, emphasizing convergence.\u003C/li>\n\u003Cli>The variation funnel displays the full drill stack, making the path explicit.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-weight\">Strategic Weight\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-weight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Weight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Low\u003C/strong> --- Path dependency is mathematically correct behavior, not a bug. The final results converge, and the intermediate differences are informative for skilled analysts. The risk is primarily pedagogical: novices may be confused. This is better addressed through learning content (glossary, help tooltips) than through UI changes that would mask correct statistical behavior.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-patterns\">Related Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../patterns/parallel-path-comparison.md\">Parallel Path Comparison\u003C/a> --- Directly addresses this by showing alternative paths and their convergence or divergence.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/auto-combination-finder.md\">Auto-Combination Finder\u003C/a> --- Bypasses path dependency entirely by jumping straight to the optimal combination.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/factor-map.md\">Factor Map\u003C/a> --- Shows all factors simultaneously without imposing a sequence, making path dependency irrelevant for the initial overview.\u003C/li>\n\u003C/ul>", + { + "headings": 13027, + "localImagePaths": 13034, + "remoteImagePaths": 13035, + "frontmatter": 13036, + "imagePaths": 13037 + }, + [13028, 13029, 13030, 13031, 13032, 13033], + { "depth": 30, "slug": 6826, "text": 13017 }, + { "depth": 33, "slug": 12923, "text": 12924 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 12927, "text": 12928 }, + { "depth": 33, "slug": 12930, "text": 12931 }, + { "depth": 33, "slug": 12933, "text": 12934 }, + [], + [], + { "title": 13017 }, + [], + "01-vision/evaluations/tensions/when-to-stop", + { + "id": 13038, + "data": 13040, + "body": 13045, + "filePath": 13046, + "digest": 13047, + "rendered": 13048 + }, + { + "title": 13041, + "editUrl": 16, + "head": 13042, + "template": 18, + "sidebar": 13043, + "pagefind": 16, + "draft": 20 + }, + "When to Stop", + [], + { "hidden": 20, "attrs": 13044 }, + {}, + "# When to Stop\n\n> Statistical explanation and actionability aren't the same thing --- isolating variation doesn't mean you can fix it.\n\n## The Tension\n\nThe color-coded variation bar provides a clear signal for statistical progress: green at 50%+ cumulative variation explained, amber at 30--50%, blue below 30%. This helps the analyst judge when they've captured \"enough\" of the problem. But statistical explanatory power and operational actionability are different things.\n\nIsolating 46% of variation to \"Machine C on Night Shift\" is only useful if someone can actually change something about Machine C on Night Shift. If Machine C is the only machine available and Night Shift can't be eliminated, the finding is descriptively accurate but operationally useless. The analyst has successfully answered \"where is the variation?\" but the answer doesn't lead to \"what can I do about it?\"\n\nThe tool quantifies variation sources but can't assess whether those sources are controllable. This is fundamentally a domain knowledge problem --- the tool doesn't know that Machine C is the only option, or that Night Shift is contractually required. But the lack of any \"actionability check\" means the tool can guide an analyst to a statistically satisfying but practically worthless conclusion. The green variation bar says \"you found it!\" when it should perhaps say \"you found where it is --- now assess whether you can act on it.\"\n\n## Persona Impact\n\n| Persona | Impact | Why |\n| --------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Green Belt Gary | Medium | Gary has enough training to recognize the distinction between finding and fixing, but the tool's satisfaction signals (green bar) may create premature closure. |\n| Student Sara | High | Sara is learning and may equate \"found the variation source\" with \"solved the problem.\" The tool reinforces this by celebrating statistical progress without questioning actionability. |\n| OpEx Olivia | High | Olivia allocates resources based on findings. A statistically impressive but unactionable finding wastes project budget and team credibility. |\n| Trainer Tina | Medium | Tina teaches this distinction explicitly (\"Finding is step 1, fixing is step 2\") but would appreciate if the tool reinforced the message rather than contradicting it. |\n| Evaluator Erik | Low | This tension is about analytical methodology, not tool deployment or security. |\n| Curious Carlos | Low | Carlos is in discovery mode. The distinction between finding and fixing is a later-stage concern that doesn't affect his initial exploration value. |\n\n## Current Mitigation\n\n- The variation bar uses color thresholds, not binary pass/fail, which avoids a hard \"done\" signal.\n- The philosophy documentation explicitly states \"VariScout finds WHERE to focus. Apply Lean thinking to find WHY.\"\n- Case studies show the full journey from finding to action, modeling the correct workflow.\n\n## Strategic Weight\n\n**Medium** --- This is a methodology limitation more than a product limitation. The tool correctly finds variation sources; it's the analyst's job to assess actionability. However, the satisfaction signals (green bar, contribution percentages) could be misread as \"problem solved\" signals. A lightweight nudge at the end of a drill-down (\"What will you do with this finding?\") could bridge the gap without adding complexity.\n\n## Related Patterns\n\n- [Factor Suggestion](../patterns/factor-suggestion.md) --- Could include actionability hints alongside statistical suggestions, though this requires domain knowledge the tool doesn't have.\n- [Auto-Combination Finder](../patterns/auto-combination-finder.md) --- Faster path to findings, but amplifies the \"now what?\" gap by making the statistical part trivially easy.", + "src/content/docs/01-vision/evaluations/tensions/when-to-stop.md", + "5032f808527f8eef", + { "html": 13049, "metadata": 13050 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"when-to-stop\">When to Stop\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#when-to-stop\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “When to Stop”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Statistical explanation and actionability aren’t the same thing --- isolating variation doesn’t mean you can fix it.\u003C/p>\n\u003C/blockquote>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"the-tension\">The Tension\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#the-tension\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “The Tension”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The color-coded variation bar provides a clear signal for statistical progress: green at 50%+ cumulative variation explained, amber at 30—50%, blue below 30%. This helps the analyst judge when they’ve captured “enough” of the problem. But statistical explanatory power and operational actionability are different things.\u003C/p>\n\u003Cp>Isolating 46% of variation to “Machine C on Night Shift” is only useful if someone can actually change something about Machine C on Night Shift. If Machine C is the only machine available and Night Shift can’t be eliminated, the finding is descriptively accurate but operationally useless. The analyst has successfully answered “where is the variation?” but the answer doesn’t lead to “what can I do about it?”\u003C/p>\n\u003Cp>The tool quantifies variation sources but can’t assess whether those sources are controllable. This is fundamentally a domain knowledge problem --- the tool doesn’t know that Machine C is the only option, or that Night Shift is contractually required. But the lack of any “actionability check” means the tool can guide an analyst to a statistically satisfying but practically worthless conclusion. The green variation bar says “you found it!” when it should perhaps say “you found where it is --- now assess whether you can act on it.”\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"persona-impact\">Persona Impact\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#persona-impact\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Persona Impact”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persona\u003C/th>\u003Cth>Impact\u003C/th>\u003Cth>Why\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Green Belt Gary\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Gary has enough training to recognize the distinction between finding and fixing, but the tool’s satisfaction signals (green bar) may create premature closure.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Student Sara\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Sara is learning and may equate “found the variation source” with “solved the problem.” The tool reinforces this by celebrating statistical progress without questioning actionability.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>OpEx Olivia\u003C/td>\u003Ctd>High\u003C/td>\u003Ctd>Olivia allocates resources based on findings. A statistically impressive but unactionable finding wastes project budget and team credibility.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Trainer Tina\u003C/td>\u003Ctd>Medium\u003C/td>\u003Ctd>Tina teaches this distinction explicitly (“Finding is step 1, fixing is step 2”) but would appreciate if the tool reinforced the message rather than contradicting it.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Evaluator Erik\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>This tension is about analytical methodology, not tool deployment or security.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Curious Carlos\u003C/td>\u003Ctd>Low\u003C/td>\u003Ctd>Carlos is in discovery mode. The distinction between finding and fixing is a later-stage concern that doesn’t affect his initial exploration value.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"current-mitigation\">Current Mitigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#current-mitigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Current Mitigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>The variation bar uses color thresholds, not binary pass/fail, which avoids a hard “done” signal.\u003C/li>\n\u003Cli>The philosophy documentation explicitly states “VariScout finds WHERE to focus. Apply Lean thinking to find WHY.”\u003C/li>\n\u003Cli>Case studies show the full journey from finding to action, modeling the correct workflow.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-weight\">Strategic Weight\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-weight\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Weight”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>Medium\u003C/strong> --- This is a methodology limitation more than a product limitation. The tool correctly finds variation sources; it’s the analyst’s job to assess actionability. However, the satisfaction signals (green bar, contribution percentages) could be misread as “problem solved” signals. A lightweight nudge at the end of a drill-down (“What will you do with this finding?”) could bridge the gap without adding complexity.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"related-patterns\">Related Patterns\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#related-patterns\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Related Patterns”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Ca href=\"../patterns/factor-suggestion.md\">Factor Suggestion\u003C/a> --- Could include actionability hints alongside statistical suggestions, though this requires domain knowledge the tool doesn’t have.\u003C/li>\n\u003Cli>\u003Ca href=\"../patterns/auto-combination-finder.md\">Auto-Combination Finder\u003C/a> --- Faster path to findings, but amplifies the “now what?” gap by making the statistical part trivially easy.\u003C/li>\n\u003C/ul>", + { + "headings": 13051, + "localImagePaths": 13059, + "remoteImagePaths": 13060, + "frontmatter": 13061, + "imagePaths": 13062 + }, + [13052, 13054, 13055, 13056, 13057, 13058], + { "depth": 30, "slug": 13053, "text": 13041 }, + "when-to-stop", + { "depth": 33, "slug": 12923, "text": 12924 }, + { "depth": 33, "slug": 12662, "text": 12663 }, + { "depth": 33, "slug": 12927, "text": 12928 }, + { "depth": 33, "slug": 12930, "text": 12931 }, + { "depth": 33, "slug": 12933, "text": 12934 }, + [], + [], + { "title": 13041 }, + [], + "01-vision/evaluations/competitive/edascout-benchmark", + { + "id": 13063, + "data": 13065, + "body": 13070, + "filePath": 13071, + "digest": 13072, + "rendered": 13073 + }, + { + "title": 13066, + "editUrl": 16, + "head": 13067, + "template": 18, + "sidebar": 13068, + "pagefind": 16, + "draft": 20 + }, + "EDAScout Competitive Benchmark", + [], + { "hidden": 20, "attrs": 13069 }, + {}, + "# EDAScout Competitive Benchmark\n\n> Competitive intelligence from analysis of EDAScout v4, v6, v7, and v9 codebases.\n\nThis document provides a technical assessment of EDAScout's architecture, features, and evolution based on direct codebase analysis. EDAScout is the closest conceptual competitor to VariScout --- both target variation analysis for quality professionals using browser-based EDA tools. The analysis covers four released versions spanning a full product arc.\n\n---\n\n## Product Profile\n\n| Dimension | EDAScout | VariScout |\n| ------------------ | ------------------------------------------------------------------ | ------------------------------------------ |\n| **Tech stack** | React 18, Plotly.js + Recharts, Express + SQLite/Drizzle, Electron | React 18, Visx, browser-only, Vite |\n| **Architecture** | Client-server (Express backend, SQLite persistence) | Offline-first (IndexedDB + localStorage) |\n| **Distribution** | Electron desktop app (built on Replit) | PWA + Azure Managed App + Excel Add-in |\n| **Charting** | Plotly.js (high-level declarative) | Visx (low-level SVG primitives) |\n| **AI integration** | Gemini 2.0 Flash (added v6, removed v7, restored v9) | None (methodology-driven documentation) |\n| **UI framework** | Tailwind + shadcn/ui | Tailwind (PWA/Azure), Fluent UI (Excel) |\n| **Analysis model** | One analysis type per page | Four Lenses (4 charts simultaneously) |\n| **Navigation** | Page-based routes between analysis types | Linked filtering across coordinated charts |\n\n---\n\n## Version Evolution\n\nEDAScout's version history reveals a significant product strategy arc:\n\n### v4 --- Basic SPC Tool\n\n8-page application with simple page-based navigation: Exploratory, Capability, Pareto, Flow, Output, RTY, WIP. No AI features. No guided workflow. Each analysis type lives on its own route. Data loaded into a shared `DataContext` and consumed independently by each page.\n\n### v6 --- Major AI Expansion\n\nIntroduced Gemini 2.0 Flash integration with a \"Socratic Analyst\" chatbot sidebar. Added a guided 5-step workflow: Stability, Distribution, Subgroups, Capability, Prime Suspect, RCA. New features included a Detective's Notebook, Smart Cards (AI-generated insight summaries), and a full `ai-core/` library (10 modules). The AI layer attempted to guide analysts through a structured investigation sequence.\n\n### v7 --- Complete AI Rollback\n\n**All AI features deleted.** The `ai-core/` directory was removed. Guided pages were removed. `AppContext` (which managed AI state) was removed. The application reverted to a v4-like architecture. This is the most strategically informative version --- a team that invested heavily in AI guidance concluded it wasn't working and stripped everything out.\n\n### v9 --- AI Restoration with Refinements\n\nAI features restored. Full guided workflow returned. Investigation page re-added. A notable addition: a heuristic audit CSV for self-evaluation of UX quality, suggesting the team was measuring whether the AI guidance actually improved user outcomes this time.\n\n### What the arc tells us\n\nThe v6-to-v7 rollback is the central lesson. Adding AI-driven guidance to an analytical tool is not straightforwardly positive. The rollback suggests one or more of: (a) the AI suggestions were not reliably useful, (b) the latency of API calls disrupted the analytical flow, (c) users preferred direct interaction over mediated guidance, or (d) the maintenance burden of the AI layer exceeded its value. The v9 restoration with audit instrumentation suggests the team is approaching AI integration more carefully the second time, measuring impact rather than assuming it.\n\nThis arc validates VariScout's current approach of methodology-driven guidance (documentation, glossary, contribution percentages) over AI-driven guidance. It also suggests that if VariScout adds AI features in the future, they should be instrumented for impact measurement from day one.\n\n---\n\n## Data Upload & Column Classification\n\n### EDAScout's parsing pipeline\n\n`UnifiedDataInput` handles both paste and file upload with sanitization (CSV injection prevention via `=`, `+`, `-`, `@` prefix stripping). The parsing flow:\n\n1. **European decimal detection**: Recognizes `1,88` as `1.88` --- the same problem VariScout's `parser.ts` handles.\n2. **Automatic header suggestion**: When headers are missing, AI-powered naming suggests column headers based on data patterns.\n3. **Column type detection algorithm**:\n - Timestamp columns detected first (date/time patterns)\n - Numeric: >80% of values parse as valid numbers\n - Categorical: keyword matching (`machine`, `equipment`, `line`, `station`) + low unique count\n4. **Machine identifier reclassification**: Columns that are numerically valid but match machine keywords with low unique count are reclassified from numeric to categorical.\n5. **`ColumnSpecification` model**: Stores performance direction (bigger-is-better / smaller-is-better / nominal-is-best) and spec limits per column. Set by the user before analysis begins.\n\n### Comparison to VariScout\n\nVariScout's `parser.ts` handles European decimal detection and column classification without AI dependency. The key differences:\n\n| Capability | EDAScout | VariScout |\n| ---------------------------- | -------------------------------------- | --------------------------------------------------- |\n| European decimals | Yes | Yes |\n| CSV injection prevention | Yes (prefix stripping) | Not explicitly (browser-only context is lower risk) |\n| Auto-header suggestion | AI-powered (Gemini API call) | Not implemented |\n| Column type detection | Threshold-based (80% numeric) | Keyword + pattern matching |\n| Machine identifier detection | Keyword + low unique count | Column classification heuristics |\n| Performance direction | `ColumnSpecification` model (user-set) | Not implemented (spec limits only) |\n| Spec limit entry | Per-column before analysis | Per-column, integrated into workflow |\n\nThe `ColumnSpecification` model with performance direction (bigger-is-better / smaller-is-better / nominal-is-best) is a design worth noting. VariScout currently infers this from spec limits but doesn't make it an explicit user-facing concept.\n\n---\n\n## Filtering & Drill-Down Architecture\n\n### SubgroupExplorerModal\n\nThe `SubgroupExplorerModal` is EDAScout's central filtering UI. It opens as a **modal overlay** on the data page:\n\n- **Left panel**: `CategoryGrid` showing all categorical and time columns. Each category card displays values with variance-derived coloring from ANOVA results.\n- **Right panel**: 4 tabs (Boxplot, I-Chart, Analysis Insights, Variance Analysis) for examining the selected grouping.\n- **Filter scope**: Filters are modal-local --- `activeFilters: { category: string; value: string }[]` applied within the modal context.\n- **Filter logic**: AND across different categories, OR within the same category. This matches VariScout's filter logic exactly.\n\n### CategoryGrid variance coloring\n\nCategory values in the grid are colored by their ANOVA-derived `percentOfTotal`. However, this metric represents **within-group SS / total SS per group** --- how much variation exists _inside_ each group level. This is the statistical opposite of between-group contribution (eta-squared), which measures how much variation the grouping factor _explains_.\n\nThe practical effect: red cells indicate high internal variation (noisy groups), green cells indicate low internal variation (consistent groups). This is useful information but is **not** the same as \"this factor explains a lot of variation.\" An analyst looking for the biggest source of variation would be misled by this coloring --- a factor with all-red cells might still have very low between-group variation.\n\n### Filter persistence\n\nFilters **do not persist** across page navigation. Cross-page column transfer uses localStorage keys (`paretoSelectedColumn`, `preselected_[type]_column`), which is fragile and limited to single-column preselection rather than full filter state.\n\n### Comparison to VariScout\n\n| Capability | EDAScout | VariScout |\n| ------------------- | ------------------------------------- | -------------------------------------------- |\n| Filter UI | Modal (SubgroupExplorerModal) | Inline chips with contribution % |\n| Filter persistence | Modal-scoped, lost on page navigation | Persistent across all four lenses |\n| Filter logic | AND across categories, OR within | AND across categories, OR within (identical) |\n| Variance indication | Within-group SS coloring (misleading) | Between-group eta-squared (correct) |\n| Cumulative tracking | None | Variation funnel with cumulative eta-squared |\n| Filter context | Separate from charts (modal) | Integrated into chart interaction |\n\nVariScout's filter architecture is fundamentally stronger: filters are integrated into the chart interaction (click-to-drill), persist across all four lenses, and display correct between-group contribution percentages. EDAScout's modal-based approach separates the \"seeing variation\" step from the \"filtering\" step, requiring a cognitive transfer that VariScout eliminates.\n\n---\n\n## Brush Selection (Unique Feature)\n\nEDAScout implements a distinctive interaction pattern: **I-Chart brush selection**.\n\nThe user drags to select a range of points on the I-Chart. The selected points create a derived categorical column (`\"Selected\"` / `\"Not Selected\"`) that is persisted in `DataContext`. This derived column is then available as a grouping variable in all future analyses.\n\nThis is a creative pattern that VariScout does not implement. It allows the analyst to define ad-hoc subgroups based on observed patterns rather than predefined categorical columns. For example, an analyst noticing a cluster of out-of-control points could select them, then use the derived column to investigate what those points have in common across other factors.\n\n### Evaluation for VariScout\n\nThe brush selection pattern is worth studying but has important caveats:\n\n- **Confirmation bias risk**: Selecting points _because_ they look unusual and then finding factors that correlate is statistically circular. The analyst is effectively defining the outcome they want to explain.\n- **VariScout alternative**: The linked Four Lenses already let the analyst see what happens to all charts when filtering by any factor. The I-Chart highlights out-of-control points automatically via Nelson rules. The investigation path is reversed: instead of \"select unusual points, find factors,\" it's \"select a factor level, see if the I-Chart improves.\"\n- **Potential adaptation**: A lighter version --- highlighting time periods on the I-Chart and showing which factor levels were active during those periods --- could complement the existing drill-down without the circular reasoning risk.\n\n---\n\n## Cross-Analysis Navigation\n\n### Page-per-analysis architecture\n\nEach analysis type lives on its own route: `/pareto`, `/process-capability`, `/flow-analysis`, etc. Navigation between analyses uses:\n\n- **Quick Start buttons**: Cards on the data page link to specific analysis pages.\n- **`CrossAnalysisNavigator`**: Shows available/unavailable analyses based on column types present in the dataset.\n- **`AnalysisBreadcrumb`**: Tracks recent analyses with timestamps, transferred variables, and AI-suggested next steps.\n\n### Data transfer between pages\n\nData flows through a shared `DataContext` (headers, rows, column classifications). However, filters and selections are **not** part of this shared context. Column preselection uses localStorage keys, which is fragile and limited.\n\n### Comparison to VariScout\n\n| Capability | EDAScout | VariScout |\n| ---------------------------- | ------------------------------------ | --------------------------------------------------- |\n| Chart coordination | One chart per page | Four Lenses (4 charts simultaneously) |\n| Filter across analyses | Not supported (filters are per-page) | Linked filtering across all charts |\n| Analysis sequencing | AI-suggested next steps (breadcrumb) | Methodology-driven (documentation + contribution %) |\n| Available analysis detection | Column-type based | Column-type based (similar) |\n| Navigation model | Route-based (SPA pages) | In-page (filter chips + chart updates) |\n\nVariScout's Four Lenses approach is architecturally superior for variation investigation because the analyst sees the impact of each filter across all analysis types simultaneously. EDAScout's page-per-analysis model requires the analyst to mentally carry findings between pages, losing the simultaneous context that makes pattern recognition effective.\n\n---\n\n## Statistical Quality Assessment\n\nTwo critical statistical issues were identified in the EDAScout codebase:\n\n### P-value bucket approximation\n\nThe p-value calculation uses a hardcoded bucket approximation rather than a proper F-distribution:\n\n```\nif (fStat \u003C 6) return 0.05\n```\n\nThis means all F-statistics below 6 return a fixed p-value of 0.05, regardless of degrees of freedom. In a proper F-distribution, the p-value depends on both the F-statistic and the degrees of freedom of the numerator and denominator. This approximation can produce incorrect significance conclusions, particularly for datasets with few groups or many observations.\n\n### `percentOfTotal` calculation error\n\nThe `percentOfTotal` metric shows **within-group SS / total SS per group**, not between-group contribution. This means the value represents how much variation _exists inside_ each group level, not how much variation the grouping factor _explains_.\n\nThe practical consequence: the metric answers \"which group is internally noisy?\" rather than \"which factor explains the most variation?\" These are different questions with different implications for improvement action. An analyst using `percentOfTotal` to prioritize investigation factors would be misled.\n\n### Implications\n\nThese statistical issues are significant because:\n\n1. **User trust**: Quality professionals depend on correct statistics for improvement decisions. Incorrect p-values or misleading contribution metrics lead to wrong conclusions about where to focus.\n2. **Competitive differentiation**: VariScout's correct implementation of eta-squared contribution percentages and proper statistical calculations is a genuine technical advantage, not just a feature difference.\n3. **Validation lesson**: The presence of these errors in a shipped product underscores the importance of VariScout's test suite (484 tests in `@variscout/core`) for statistical correctness.\n\n---\n\n## Feature Comparison Matrix\n\n| Feature | EDAScout v9 | VariScout |\n| ------------------------------- | ------------------------- | ----------------------------------- |\n| **I-Chart** | Yes (Recharts) | Yes (Visx) |\n| **Boxplot** | Yes (Plotly.js) | Yes (Visx) |\n| **Pareto** | Yes | Yes |\n| **Capability analysis** | Yes | Yes (Cp, Cpk, Pp, Ppk) |\n| **Regression** | No | Yes |\n| **Gage R&R** | No | No |\n| **ANOVA** | Yes (flawed p-value) | Yes (proper F-distribution) |\n| **Nelson rules** | Limited | Full 8-rule implementation |\n| **Multi-measure (Performance)** | No | Yes (Azure/Excel) |\n| **Simultaneous chart views** | 1 per page | 4 (Four Lenses) |\n| **Linked filtering** | No (per-page filters) | Yes (cross-chart) |\n| **Contribution %** | Within-group SS (flawed) | Between-group eta-squared (correct) |\n| **Cumulative tracking** | No | Variation funnel |\n| **Brush selection** | Yes (I-Chart) | No |\n| **AI guidance** | Gemini 2.0 Flash | None (methodology-driven) |\n| **Offline operation** | Requires server | Full offline (PWA) |\n| **Spec limits** | Yes | Yes |\n| **Performance direction** | Yes (ColumnSpecification) | No (inferred from spec limits) |\n| **Dark theme** | No | Yes (charts + Excel content pane) |\n| **Mobile support** | Responsive grid | Responsive + mobile-first hooks |\n| **European decimal handling** | Yes | Yes |\n| **Case studies / sample data** | No | Yes (7 case studies) |\n| **Glossary / help tooltips** | No | Yes (20+ terms) |\n| **Export (CSV/clipboard)** | Limited | Yes |\n\n---\n\n## How EDAScout Addresses Our 6 Tensions\n\nMapping EDAScout's features against the tension/pattern evaluation framework from [Progressive Stratification](../../progressive-stratification.md):\n\n### 1. Hierarchy Assumption\n\n**EDAScout's approach**: No interaction detection. Single-factor variance analysis only. The `SubgroupExplorerModal` examines one factor at a time.\n\n**Assessment**: Does not address this tension. An analyst investigating a Machine x Shift interaction would need to manually create the combination and analyze it separately. The ANOVA implementation only handles one-way analysis.\n\n### 2. Discoverability\n\n**EDAScout's approach**: Smart Cards (AI-generated) suggest next analysis steps. \"Continue with Pareto Analysis\" banners appear based on context. The `SubgroupExplorerModal` is the main investigation entry point but must be explicitly opened by the user.\n\n**Assessment**: Partially addresses through AI suggestions. The Smart Cards provide explicit guidance but depend on AI API availability (Gemini 2.0 Flash). The modal-based approach requires the analyst to know to open the explorer, creating a discoverability gap for the explorer itself.\n\n### 3. Factor Ordering\n\n**EDAScout's approach**: AI suggests factors via Socratic dialogue in the chatbot sidebar. Heuristic-based Smart Card generation highlights factors worth investigating. The variance coloring in `CategoryGrid` visually differentiates groups, though the underlying metric (within-group SS) is misleading for factor prioritization.\n\n**Assessment**: Addresses through AI mediation rather than statistical transparency. The analyst is told which factor to try, not shown the statistical basis for the recommendation. This is the opposite of VariScout's approach (show eta-squared contribution, let the analyst decide).\n\n### 4. When to Stop\n\n**EDAScout's approach**: Investigation guidance with \"next steps\" suggestions in the `AnalysisBreadcrumb`. A 7-step Detective's Notebook framework provides structure. AI suggests when an investigation is \"complete.\"\n\n**Assessment**: Addresses through prescriptive workflow (7 steps) rather than statistical convergence. The analyst follows a checklist rather than monitoring variation explained. No equivalent to VariScout's variation funnel showing cumulative progress.\n\n### 5. Mobile Screen Budget\n\n**EDAScout's approach**: Responsive grid columns (1--4 based on viewport width). However, the `SubgroupExplorerModal` with its two-panel layout (category grid + tabbed analysis) is desktop-centric and would be cramped on mobile.\n\n**Assessment**: Basic responsive layout without mobile-specific UX adaptation. No equivalent to VariScout's `useIsMobile` and `useResponsiveChartMargins` hooks for mobile-optimized chart rendering.\n\n### 6. Path Dependency\n\n**EDAScout's approach**: No awareness. Single-factor analysis per page with no cumulative tracking. No concept of \"variation already explained by previous filters.\" No contribution-to-total anchoring.\n\n**Assessment**: Does not address. The page-per-analysis architecture and non-persistent filters mean the analyst cannot even observe path dependency effects, let alone manage them.\n\n---\n\n## Strategic Implications for VariScout\n\n### What to learn\n\n1. **Brush selection interaction pattern**: The I-Chart point selection creating a derived categorical column is a creative interaction pattern. A VariScout adaptation --- highlighting time periods and showing which factor levels were active --- could complement the existing drill-down without the confirmation bias risk.\n\n2. **ColumnSpecification with performance direction**: The explicit bigger-is-better / smaller-is-better / nominal-is-best classification per column is a useful concept that VariScout could adopt. Currently VariScout infers directionality from spec limits, but an explicit setting would handle edge cases better.\n\n3. **Heuristic audit instrumentation**: EDAScout v9's addition of a heuristic audit CSV for self-evaluation of UX quality is a mature practice. If VariScout adds guided features (factor suggestion), instrumenting their impact from the start would prevent the \"add then rollback\" cycle EDAScout experienced.\n\n### What to avoid\n\n1. **AI-driven guidance without measurement**: The v6-to-v7 rollback is the clearest cautionary tale. Adding AI features without impact measurement led to a complete reversal. VariScout should instrument any AI features before deploying them.\n\n2. **Flawed statistics shipped to production**: EDAScout's p-value bucket approximation and misleading `percentOfTotal` metric would erode trust with quality professionals who understand these calculations. VariScout's investment in correct statistics (484 tests in `@variscout/core`) is a genuine competitive moat.\n\n3. **Modal-based filtering**: Separating the filter UI from the chart interaction adds cognitive overhead. VariScout's inline filter chips integrated into the chart experience are architecturally superior.\n\n4. **Non-persistent filter state**: EDAScout's filters being scoped to individual pages/modals means the analyst loses context when navigating. VariScout's persistent filter state across all four lenses is a fundamental advantage.\n\n### What to differentiate on\n\n1. **Linked filtering with contribution percentages**: No competitor, including EDAScout, provides inline eta-squared contribution percentages on filter chips. This is VariScout's most distinctive feature.\n\n2. **Four Lenses simultaneous view**: EDAScout's one-chart-per-page model is the industry default. VariScout's four simultaneous charts with linked filtering is a genuine differentiator.\n\n3. **Correct statistics**: Proper F-distribution p-values, correct between-group eta-squared, and comprehensive test coverage are competitive advantages that matter deeply to quality professionals.\n\n4. **Offline-first architecture**: EDAScout requires a server (Express + SQLite). VariScout's browser-only operation means data never leaves the user's device --- a significant advantage for manufacturing environments with data sensitivity requirements.\n\n5. **Methodology over AI**: EDAScout's AI rollback arc validates VariScout's approach of teaching methodology through documentation, glossary, and visual cues rather than depending on AI-mediated guidance. The methodology approach is more reliable, doesn't require API connectivity, and builds analyst capability rather than tool dependency.", + "src/content/docs/01-vision/evaluations/competitive/edascout-benchmark.md", + "c656cbc92d478ed9", + { "html": 13074, "metadata": 13075 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"edascout-competitive-benchmark\">EDAScout Competitive Benchmark\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#edascout-competitive-benchmark\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “EDAScout Competitive Benchmark”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Competitive intelligence from analysis of EDAScout v4, v6, v7, and v9 codebases.\u003C/p>\n\u003C/blockquote>\n\u003Cp>This document provides a technical assessment of EDAScout’s architecture, features, and evolution based on direct codebase analysis. EDAScout is the closest conceptual competitor to VariScout --- both target variation analysis for quality professionals using browser-based EDA tools. The analysis covers four released versions spanning a full product arc.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"product-profile\">Product Profile\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#product-profile\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Profile”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>EDAScout\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Tech stack\u003C/strong>\u003C/td>\u003Ctd>React 18, Plotly.js + Recharts, Express + SQLite/Drizzle, Electron\u003C/td>\u003Ctd>React 18, Visx, browser-only, Vite\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Architecture\u003C/strong>\u003C/td>\u003Ctd>Client-server (Express backend, SQLite persistence)\u003C/td>\u003Ctd>Offline-first (IndexedDB + localStorage)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Distribution\u003C/strong>\u003C/td>\u003Ctd>Electron desktop app (built on Replit)\u003C/td>\u003Ctd>PWA + Azure Managed App + Excel Add-in\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Charting\u003C/strong>\u003C/td>\u003Ctd>Plotly.js (high-level declarative)\u003C/td>\u003Ctd>Visx (low-level SVG primitives)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>AI integration\u003C/strong>\u003C/td>\u003Ctd>Gemini 2.0 Flash (added v6, removed v7, restored v9)\u003C/td>\u003Ctd>None (methodology-driven documentation)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>UI framework\u003C/strong>\u003C/td>\u003Ctd>Tailwind + shadcn/ui\u003C/td>\u003Ctd>Tailwind (PWA/Azure), Fluent UI (Excel)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Analysis model\u003C/strong>\u003C/td>\u003Ctd>One analysis type per page\u003C/td>\u003Ctd>Four Lenses (4 charts simultaneously)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Navigation\u003C/strong>\u003C/td>\u003Ctd>Page-based routes between analysis types\u003C/td>\u003Ctd>Linked filtering across coordinated charts\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"version-evolution\">Version Evolution\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#version-evolution\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Version Evolution”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>EDAScout’s version history reveals a significant product strategy arc:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"v4-----basic-spc-tool\">v4 --- Basic SPC Tool\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#v4-----basic-spc-tool\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “v4 --- Basic SPC Tool”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>8-page application with simple page-based navigation: Exploratory, Capability, Pareto, Flow, Output, RTY, WIP. No AI features. No guided workflow. Each analysis type lives on its own route. Data loaded into a shared \u003Ccode dir=\"auto\">DataContext\u003C/code> and consumed independently by each page.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"v6-----major-ai-expansion\">v6 --- Major AI Expansion\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#v6-----major-ai-expansion\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “v6 --- Major AI Expansion”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Introduced Gemini 2.0 Flash integration with a “Socratic Analyst” chatbot sidebar. Added a guided 5-step workflow: Stability, Distribution, Subgroups, Capability, Prime Suspect, RCA. New features included a Detective’s Notebook, Smart Cards (AI-generated insight summaries), and a full \u003Ccode dir=\"auto\">ai-core/\u003C/code> library (10 modules). The AI layer attempted to guide analysts through a structured investigation sequence.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"v7-----complete-ai-rollback\">v7 --- Complete AI Rollback\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#v7-----complete-ai-rollback\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “v7 --- Complete AI Rollback”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>All AI features deleted.\u003C/strong> The \u003Ccode dir=\"auto\">ai-core/\u003C/code> directory was removed. Guided pages were removed. \u003Ccode dir=\"auto\">AppContext\u003C/code> (which managed AI state) was removed. The application reverted to a v4-like architecture. This is the most strategically informative version --- a team that invested heavily in AI guidance concluded it wasn’t working and stripped everything out.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"v9-----ai-restoration-with-refinements\">v9 --- AI Restoration with Refinements\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#v9-----ai-restoration-with-refinements\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “v9 --- AI Restoration with Refinements”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>AI features restored. Full guided workflow returned. Investigation page re-added. A notable addition: a heuristic audit CSV for self-evaluation of UX quality, suggesting the team was measuring whether the AI guidance actually improved user outcomes this time.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-the-arc-tells-us\">What the arc tells us\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-the-arc-tells-us\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What the arc tells us”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The v6-to-v7 rollback is the central lesson. Adding AI-driven guidance to an analytical tool is not straightforwardly positive. The rollback suggests one or more of: (a) the AI suggestions were not reliably useful, (b) the latency of API calls disrupted the analytical flow, (c) users preferred direct interaction over mediated guidance, or (d) the maintenance burden of the AI layer exceeded its value. The v9 restoration with audit instrumentation suggests the team is approaching AI integration more carefully the second time, measuring impact rather than assuming it.\u003C/p>\n\u003Cp>This arc validates VariScout’s current approach of methodology-driven guidance (documentation, glossary, contribution percentages) over AI-driven guidance. It also suggests that if VariScout adds AI features in the future, they should be instrumented for impact measurement from day one.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"data-upload--column-classification\">Data Upload & Column Classification\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#data-upload--column-classification\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data Upload & Column Classification”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"edascouts-parsing-pipeline\">EDAScout’s parsing pipeline\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#edascouts-parsing-pipeline\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “EDAScout’s parsing pipeline”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Ccode dir=\"auto\">UnifiedDataInput\u003C/code> handles both paste and file upload with sanitization (CSV injection prevention via \u003Ccode dir=\"auto\">=\u003C/code>, \u003Ccode dir=\"auto\">+\u003C/code>, \u003Ccode dir=\"auto\">-\u003C/code>, \u003Ccode dir=\"auto\">@\u003C/code> prefix stripping). The parsing flow:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>European decimal detection\u003C/strong>: Recognizes \u003Ccode dir=\"auto\">1,88\u003C/code> as \u003Ccode dir=\"auto\">1.88\u003C/code> --- the same problem VariScout’s \u003Ccode dir=\"auto\">parser.ts\u003C/code> handles.\u003C/li>\n\u003Cli>\u003Cstrong>Automatic header suggestion\u003C/strong>: When headers are missing, AI-powered naming suggests column headers based on data patterns.\u003C/li>\n\u003Cli>\u003Cstrong>Column type detection algorithm\u003C/strong>:\n\u003Cul>\n\u003Cli>Timestamp columns detected first (date/time patterns)\u003C/li>\n\u003Cli>Numeric: >80% of values parse as valid numbers\u003C/li>\n\u003Cli>Categorical: keyword matching (\u003Ccode dir=\"auto\">machine\u003C/code>, \u003Ccode dir=\"auto\">equipment\u003C/code>, \u003Ccode dir=\"auto\">line\u003C/code>, \u003Ccode dir=\"auto\">station\u003C/code>) + low unique count\u003C/li>\n\u003C/ul>\n\u003C/li>\n\u003Cli>\u003Cstrong>Machine identifier reclassification\u003C/strong>: Columns that are numerically valid but match machine keywords with low unique count are reclassified from numeric to categorical.\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode dir=\"auto\">ColumnSpecification\u003C/code> model\u003C/strong>: Stores performance direction (bigger-is-better / smaller-is-better / nominal-is-best) and spec limits per column. Set by the user before analysis begins.\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"comparison-to-variscout\">Comparison to VariScout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#comparison-to-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Comparison to VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>VariScout’s \u003Ccode dir=\"auto\">parser.ts\u003C/code> handles European decimal detection and column classification without AI dependency. The key differences:\u003C/p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>EDAScout\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>European decimals\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>CSV injection prevention\u003C/td>\u003Ctd>Yes (prefix stripping)\u003C/td>\u003Ctd>Not explicitly (browser-only context is lower risk)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Auto-header suggestion\u003C/td>\u003Ctd>AI-powered (Gemini API call)\u003C/td>\u003Ctd>Not implemented\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Column type detection\u003C/td>\u003Ctd>Threshold-based (80% numeric)\u003C/td>\u003Ctd>Keyword + pattern matching\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Machine identifier detection\u003C/td>\u003Ctd>Keyword + low unique count\u003C/td>\u003Ctd>Column classification heuristics\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Performance direction\u003C/td>\u003Ctd>\u003Ccode dir=\"auto\">ColumnSpecification\u003C/code> model (user-set)\u003C/td>\u003Ctd>Not implemented (spec limits only)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Spec limit entry\u003C/td>\u003Ctd>Per-column before analysis\u003C/td>\u003Ctd>Per-column, integrated into workflow\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>The \u003Ccode dir=\"auto\">ColumnSpecification\u003C/code> model with performance direction (bigger-is-better / smaller-is-better / nominal-is-best) is a design worth noting. VariScout currently infers this from spec limits but doesn’t make it an explicit user-facing concept.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"filtering--drill-down-architecture\">Filtering & Drill-Down Architecture\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#filtering--drill-down-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filtering & Drill-Down Architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"subgroupexplorermodal\">SubgroupExplorerModal\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#subgroupexplorermodal\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SubgroupExplorerModal”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">SubgroupExplorerModal\u003C/code> is EDAScout’s central filtering UI. It opens as a \u003Cstrong>modal overlay\u003C/strong> on the data page:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Left panel\u003C/strong>: \u003Ccode dir=\"auto\">CategoryGrid\u003C/code> showing all categorical and time columns. Each category card displays values with variance-derived coloring from ANOVA results.\u003C/li>\n\u003Cli>\u003Cstrong>Right panel\u003C/strong>: 4 tabs (Boxplot, I-Chart, Analysis Insights, Variance Analysis) for examining the selected grouping.\u003C/li>\n\u003Cli>\u003Cstrong>Filter scope\u003C/strong>: Filters are modal-local --- \u003Ccode dir=\"auto\">activeFilters: { category: string; value: string }[]\u003C/code> applied within the modal context.\u003C/li>\n\u003Cli>\u003Cstrong>Filter logic\u003C/strong>: AND across different categories, OR within the same category. This matches VariScout’s filter logic exactly.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"categorygrid-variance-coloring\">CategoryGrid variance coloring\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#categorygrid-variance-coloring\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “CategoryGrid variance coloring”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Category values in the grid are colored by their ANOVA-derived \u003Ccode dir=\"auto\">percentOfTotal\u003C/code>. However, this metric represents \u003Cstrong>within-group SS / total SS per group\u003C/strong> --- how much variation exists \u003Cem>inside\u003C/em> each group level. This is the statistical opposite of between-group contribution (eta-squared), which measures how much variation the grouping factor \u003Cem>explains\u003C/em>.\u003C/p>\n\u003Cp>The practical effect: red cells indicate high internal variation (noisy groups), green cells indicate low internal variation (consistent groups). This is useful information but is \u003Cstrong>not\u003C/strong> the same as “this factor explains a lot of variation.” An analyst looking for the biggest source of variation would be misled by this coloring --- a factor with all-red cells might still have very low between-group variation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"filter-persistence\">Filter persistence\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#filter-persistence\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Filter persistence”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Filters \u003Cstrong>do not persist\u003C/strong> across page navigation. Cross-page column transfer uses localStorage keys (\u003Ccode dir=\"auto\">paretoSelectedColumn\u003C/code>, \u003Ccode dir=\"auto\">preselected_[type]_column\u003C/code>), which is fragile and limited to single-column preselection rather than full filter state.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"comparison-to-variscout-1\">Comparison to VariScout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#comparison-to-variscout-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Comparison to VariScout”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>EDAScout\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Filter UI\u003C/td>\u003Ctd>Modal (SubgroupExplorerModal)\u003C/td>\u003Ctd>Inline chips with contribution %\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filter persistence\u003C/td>\u003Ctd>Modal-scoped, lost on page navigation\u003C/td>\u003Ctd>Persistent across all four lenses\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filter logic\u003C/td>\u003Ctd>AND across categories, OR within\u003C/td>\u003Ctd>AND across categories, OR within (identical)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Variance indication\u003C/td>\u003Ctd>Within-group SS coloring (misleading)\u003C/td>\u003Ctd>Between-group eta-squared (correct)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cumulative tracking\u003C/td>\u003Ctd>None\u003C/td>\u003Ctd>Variation funnel with cumulative eta-squared\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filter context\u003C/td>\u003Ctd>Separate from charts (modal)\u003C/td>\u003Ctd>Integrated into chart interaction\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>VariScout’s filter architecture is fundamentally stronger: filters are integrated into the chart interaction (click-to-drill), persist across all four lenses, and display correct between-group contribution percentages. EDAScout’s modal-based approach separates the “seeing variation” step from the “filtering” step, requiring a cognitive transfer that VariScout eliminates.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"brush-selection-unique-feature\">Brush Selection (Unique Feature)\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#brush-selection-unique-feature\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Brush Selection (Unique Feature)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>EDAScout implements a distinctive interaction pattern: \u003Cstrong>I-Chart brush selection\u003C/strong>.\u003C/p>\n\u003Cp>The user drags to select a range of points on the I-Chart. The selected points create a derived categorical column (\u003Ccode dir=\"auto\">\"Selected\"\u003C/code> / \u003Ccode dir=\"auto\">\"Not Selected\"\u003C/code>) that is persisted in \u003Ccode dir=\"auto\">DataContext\u003C/code>. This derived column is then available as a grouping variable in all future analyses.\u003C/p>\n\u003Cp>This is a creative pattern that VariScout does not implement. It allows the analyst to define ad-hoc subgroups based on observed patterns rather than predefined categorical columns. For example, an analyst noticing a cluster of out-of-control points could select them, then use the derived column to investigate what those points have in common across other factors.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"evaluation-for-variscout\">Evaluation for VariScout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#evaluation-for-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Evaluation for VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The brush selection pattern is worth studying but has important caveats:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Confirmation bias risk\u003C/strong>: Selecting points \u003Cem>because\u003C/em> they look unusual and then finding factors that correlate is statistically circular. The analyst is effectively defining the outcome they want to explain.\u003C/li>\n\u003Cli>\u003Cstrong>VariScout alternative\u003C/strong>: The linked Four Lenses already let the analyst see what happens to all charts when filtering by any factor. The I-Chart highlights out-of-control points automatically via Nelson rules. The investigation path is reversed: instead of “select unusual points, find factors,” it’s “select a factor level, see if the I-Chart improves.”\u003C/li>\n\u003Cli>\u003Cstrong>Potential adaptation\u003C/strong>: A lighter version --- highlighting time periods on the I-Chart and showing which factor levels were active during those periods --- could complement the existing drill-down without the circular reasoning risk.\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"cross-analysis-navigation\">Cross-Analysis Navigation\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#cross-analysis-navigation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Analysis Navigation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"page-per-analysis-architecture\">Page-per-analysis architecture\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#page-per-analysis-architecture\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Page-per-analysis architecture”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Each analysis type lives on its own route: \u003Ccode dir=\"auto\">/pareto\u003C/code>, \u003Ccode dir=\"auto\">/process-capability\u003C/code>, \u003Ccode dir=\"auto\">/flow-analysis\u003C/code>, etc. Navigation between analyses uses:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Quick Start buttons\u003C/strong>: Cards on the data page link to specific analysis pages.\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode dir=\"auto\">CrossAnalysisNavigator\u003C/code>\u003C/strong>: Shows available/unavailable analyses based on column types present in the dataset.\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode dir=\"auto\">AnalysisBreadcrumb\u003C/code>\u003C/strong>: Tracks recent analyses with timestamps, transferred variables, and AI-suggested next steps.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"data-transfer-between-pages\">Data transfer between pages\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#data-transfer-between-pages\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Data transfer between pages”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Data flows through a shared \u003Ccode dir=\"auto\">DataContext\u003C/code> (headers, rows, column classifications). However, filters and selections are \u003Cstrong>not\u003C/strong> part of this shared context. Column preselection uses localStorage keys, which is fragile and limited.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"comparison-to-variscout-2\">Comparison to VariScout\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#comparison-to-variscout-2\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Comparison to VariScout”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>EDAScout\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Chart coordination\u003C/td>\u003Ctd>One chart per page\u003C/td>\u003Ctd>Four Lenses (4 charts simultaneously)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Filter across analyses\u003C/td>\u003Ctd>Not supported (filters are per-page)\u003C/td>\u003Ctd>Linked filtering across all charts\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Analysis sequencing\u003C/td>\u003Ctd>AI-suggested next steps (breadcrumb)\u003C/td>\u003Ctd>Methodology-driven (documentation + contribution %)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Available analysis detection\u003C/td>\u003Ctd>Column-type based\u003C/td>\u003Ctd>Column-type based (similar)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Navigation model\u003C/td>\u003Ctd>Route-based (SPA pages)\u003C/td>\u003Ctd>In-page (filter chips + chart updates)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cp>VariScout’s Four Lenses approach is architecturally superior for variation investigation because the analyst sees the impact of each filter across all analysis types simultaneously. EDAScout’s page-per-analysis model requires the analyst to mentally carry findings between pages, losing the simultaneous context that makes pattern recognition effective.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"statistical-quality-assessment\">Statistical Quality Assessment\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#statistical-quality-assessment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Statistical Quality Assessment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Two critical statistical issues were identified in the EDAScout codebase:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"p-value-bucket-approximation\">P-value bucket approximation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#p-value-bucket-approximation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “P-value bucket approximation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The p-value calculation uses a hardcoded bucket approximation rather than a proper F-distribution:\u003C/p>\n\u003Cdiv class=\"expressive-code\">\u003Clink rel=\"stylesheet\" href=\"/_astro/ec.v4551.css\">\u003Cscript type=\"module\" src=\"/_astro/ec.0vx5m.js\">\u003C/script>\u003Cfigure class=\"frame not-content\">\u003Cfigcaption class=\"header\">\u003C/figcaption>\u003Cpre data-language=\"plaintext\">\u003Ccode>\u003Cdiv class=\"ec-line\">\u003Cdiv class=\"code\">\u003Cspan style=\"--0:#d6deeb;--1:#403f53\">if (fStat < 6) return 0.05\u003C/span>\u003C/div>\u003C/div>\u003C/code>\u003C/pre>\u003Cdiv class=\"copy\">\u003Cdiv aria-live=\"polite\">\u003C/div>\u003Cbutton title=\"Copy to clipboard\" data-copied=\"Copied!\" data-code=\"if (fStat \u003C 6) return 0.05\">\u003Cdiv>\u003C/div>\u003C/button>\u003C/div>\u003C/figure>\u003C/div>\n\u003Cp>This means all F-statistics below 6 return a fixed p-value of 0.05, regardless of degrees of freedom. In a proper F-distribution, the p-value depends on both the F-statistic and the degrees of freedom of the numerator and denominator. This approximation can produce incorrect significance conclusions, particularly for datasets with few groups or many observations.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"percentoftotal-calculation-error\">\u003Ccode dir=\"auto\">percentOfTotal\u003C/code> calculation error\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#percentoftotal-calculation-error\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “percentOfTotal calculation error”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>The \u003Ccode dir=\"auto\">percentOfTotal\u003C/code> metric shows \u003Cstrong>within-group SS / total SS per group\u003C/strong>, not between-group contribution. This means the value represents how much variation \u003Cem>exists inside\u003C/em> each group level, not how much variation the grouping factor \u003Cem>explains\u003C/em>.\u003C/p>\n\u003Cp>The practical consequence: the metric answers “which group is internally noisy?” rather than “which factor explains the most variation?” These are different questions with different implications for improvement action. An analyst using \u003Ccode dir=\"auto\">percentOfTotal\u003C/code> to prioritize investigation factors would be misled.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"implications\">Implications\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#implications\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Implications”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>These statistical issues are significant because:\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>User trust\u003C/strong>: Quality professionals depend on correct statistics for improvement decisions. Incorrect p-values or misleading contribution metrics lead to wrong conclusions about where to focus.\u003C/li>\n\u003Cli>\u003Cstrong>Competitive differentiation\u003C/strong>: VariScout’s correct implementation of eta-squared contribution percentages and proper statistical calculations is a genuine technical advantage, not just a feature difference.\u003C/li>\n\u003Cli>\u003Cstrong>Validation lesson\u003C/strong>: The presence of these errors in a shipped product underscores the importance of VariScout’s test suite (484 tests in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>) for statistical correctness.\u003C/li>\n\u003C/ol>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-comparison-matrix\">Feature Comparison Matrix\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-comparison-matrix\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Comparison Matrix”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Feature\u003C/th>\u003Cth>EDAScout v9\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>I-Chart\u003C/strong>\u003C/td>\u003Ctd>Yes (Recharts)\u003C/td>\u003Ctd>Yes (Visx)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Boxplot\u003C/strong>\u003C/td>\u003Ctd>Yes (Plotly.js)\u003C/td>\u003Ctd>Yes (Visx)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pareto\u003C/strong>\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Capability analysis\u003C/strong>\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes (Cp, Cpk, Pp, Ppk)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Regression\u003C/strong>\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Gage R&R\u003C/strong>\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>ANOVA\u003C/strong>\u003C/td>\u003Ctd>Yes (flawed p-value)\u003C/td>\u003Ctd>Yes (proper F-distribution)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Nelson rules\u003C/strong>\u003C/td>\u003Ctd>Limited\u003C/td>\u003Ctd>Full 8-rule implementation\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Multi-measure (Performance)\u003C/strong>\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Yes (Azure/Excel)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Simultaneous chart views\u003C/strong>\u003C/td>\u003Ctd>1 per page\u003C/td>\u003Ctd>4 (Four Lenses)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Linked filtering\u003C/strong>\u003C/td>\u003Ctd>No (per-page filters)\u003C/td>\u003Ctd>Yes (cross-chart)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Contribution %\u003C/strong>\u003C/td>\u003Ctd>Within-group SS (flawed)\u003C/td>\u003Ctd>Between-group eta-squared (correct)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Cumulative tracking\u003C/strong>\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Variation funnel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Brush selection\u003C/strong>\u003C/td>\u003Ctd>Yes (I-Chart)\u003C/td>\u003Ctd>No\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>AI guidance\u003C/strong>\u003C/td>\u003Ctd>Gemini 2.0 Flash\u003C/td>\u003Ctd>None (methodology-driven)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Offline operation\u003C/strong>\u003C/td>\u003Ctd>Requires server\u003C/td>\u003Ctd>Full offline (PWA)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Spec limits\u003C/strong>\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Performance direction\u003C/strong>\u003C/td>\u003Ctd>Yes (ColumnSpecification)\u003C/td>\u003Ctd>No (inferred from spec limits)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Dark theme\u003C/strong>\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Yes (charts + Excel content pane)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mobile support\u003C/strong>\u003C/td>\u003Ctd>Responsive grid\u003C/td>\u003Ctd>Responsive + mobile-first hooks\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>European decimal handling\u003C/strong>\u003C/td>\u003Ctd>Yes\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Case studies / sample data\u003C/strong>\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Yes (7 case studies)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Glossary / help tooltips\u003C/strong>\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Yes (20+ terms)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Export (CSV/clipboard)\u003C/strong>\u003C/td>\u003Ctd>Limited\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-edascout-addresses-our-6-tensions\">How EDAScout Addresses Our 6 Tensions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-edascout-addresses-our-6-tensions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How EDAScout Addresses Our 6 Tensions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Mapping EDAScout’s features against the tension/pattern evaluation framework from \u003Ca href=\"../../progressive-stratification.md\">Progressive Stratification\u003C/a>:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"1-hierarchy-assumption\">1. Hierarchy Assumption\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#1-hierarchy-assumption\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “1. Hierarchy Assumption”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>EDAScout’s approach\u003C/strong>: No interaction detection. Single-factor variance analysis only. The \u003Ccode dir=\"auto\">SubgroupExplorerModal\u003C/code> examines one factor at a time.\u003C/p>\n\u003Cp>\u003Cstrong>Assessment\u003C/strong>: Does not address this tension. An analyst investigating a Machine x Shift interaction would need to manually create the combination and analyze it separately. The ANOVA implementation only handles one-way analysis.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"2-discoverability\">2. Discoverability\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#2-discoverability\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “2. Discoverability”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>EDAScout’s approach\u003C/strong>: Smart Cards (AI-generated) suggest next analysis steps. “Continue with Pareto Analysis” banners appear based on context. The \u003Ccode dir=\"auto\">SubgroupExplorerModal\u003C/code> is the main investigation entry point but must be explicitly opened by the user.\u003C/p>\n\u003Cp>\u003Cstrong>Assessment\u003C/strong>: Partially addresses through AI suggestions. The Smart Cards provide explicit guidance but depend on AI API availability (Gemini 2.0 Flash). The modal-based approach requires the analyst to know to open the explorer, creating a discoverability gap for the explorer itself.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"3-factor-ordering\">3. Factor Ordering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#3-factor-ordering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “3. Factor Ordering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>EDAScout’s approach\u003C/strong>: AI suggests factors via Socratic dialogue in the chatbot sidebar. Heuristic-based Smart Card generation highlights factors worth investigating. The variance coloring in \u003Ccode dir=\"auto\">CategoryGrid\u003C/code> visually differentiates groups, though the underlying metric (within-group SS) is misleading for factor prioritization.\u003C/p>\n\u003Cp>\u003Cstrong>Assessment\u003C/strong>: Addresses through AI mediation rather than statistical transparency. The analyst is told which factor to try, not shown the statistical basis for the recommendation. This is the opposite of VariScout’s approach (show eta-squared contribution, let the analyst decide).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"4-when-to-stop\">4. When to Stop\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#4-when-to-stop\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “4. When to Stop”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>EDAScout’s approach\u003C/strong>: Investigation guidance with “next steps” suggestions in the \u003Ccode dir=\"auto\">AnalysisBreadcrumb\u003C/code>. A 7-step Detective’s Notebook framework provides structure. AI suggests when an investigation is “complete.”\u003C/p>\n\u003Cp>\u003Cstrong>Assessment\u003C/strong>: Addresses through prescriptive workflow (7 steps) rather than statistical convergence. The analyst follows a checklist rather than monitoring variation explained. No equivalent to VariScout’s variation funnel showing cumulative progress.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"5-mobile-screen-budget\">5. Mobile Screen Budget\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#5-mobile-screen-budget\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “5. Mobile Screen Budget”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>EDAScout’s approach\u003C/strong>: Responsive grid columns (1—4 based on viewport width). However, the \u003Ccode dir=\"auto\">SubgroupExplorerModal\u003C/code> with its two-panel layout (category grid + tabbed analysis) is desktop-centric and would be cramped on mobile.\u003C/p>\n\u003Cp>\u003Cstrong>Assessment\u003C/strong>: Basic responsive layout without mobile-specific UX adaptation. No equivalent to VariScout’s \u003Ccode dir=\"auto\">useIsMobile\u003C/code> and \u003Ccode dir=\"auto\">useResponsiveChartMargins\u003C/code> hooks for mobile-optimized chart rendering.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"6-path-dependency\">6. Path Dependency\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#6-path-dependency\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “6. Path Dependency”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>\u003Cstrong>EDAScout’s approach\u003C/strong>: No awareness. Single-factor analysis per page with no cumulative tracking. No concept of “variation already explained by previous filters.” No contribution-to-total anchoring.\u003C/p>\n\u003Cp>\u003Cstrong>Assessment\u003C/strong>: Does not address. The page-per-analysis architecture and non-persistent filters mean the analyst cannot even observe path dependency effects, let alone manage them.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-implications-for-variscout\">Strategic Implications for VariScout\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-implications-for-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Implications for VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-to-learn\">What to learn\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-to-learn\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What to learn”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Brush selection interaction pattern\u003C/strong>: The I-Chart point selection creating a derived categorical column is a creative interaction pattern. A VariScout adaptation --- highlighting time periods and showing which factor levels were active --- could complement the existing drill-down without the confirmation bias risk.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>ColumnSpecification with performance direction\u003C/strong>: The explicit bigger-is-better / smaller-is-better / nominal-is-best classification per column is a useful concept that VariScout could adopt. Currently VariScout infers directionality from spec limits, but an explicit setting would handle edge cases better.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Heuristic audit instrumentation\u003C/strong>: EDAScout v9’s addition of a heuristic audit CSV for self-evaluation of UX quality is a mature practice. If VariScout adds guided features (factor suggestion), instrumenting their impact from the start would prevent the “add then rollback” cycle EDAScout experienced.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-to-avoid\">What to avoid\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-to-avoid\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What to avoid”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>AI-driven guidance without measurement\u003C/strong>: The v6-to-v7 rollback is the clearest cautionary tale. Adding AI features without impact measurement led to a complete reversal. VariScout should instrument any AI features before deploying them.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Flawed statistics shipped to production\u003C/strong>: EDAScout’s p-value bucket approximation and misleading \u003Ccode dir=\"auto\">percentOfTotal\u003C/code> metric would erode trust with quality professionals who understand these calculations. VariScout’s investment in correct statistics (484 tests in \u003Ccode dir=\"auto\">@variscout/core\u003C/code>) is a genuine competitive moat.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Modal-based filtering\u003C/strong>: Separating the filter UI from the chart interaction adds cognitive overhead. VariScout’s inline filter chips integrated into the chart experience are architecturally superior.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Non-persistent filter state\u003C/strong>: EDAScout’s filters being scoped to individual pages/modals means the analyst loses context when navigating. VariScout’s persistent filter state across all four lenses is a fundamental advantage.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-to-differentiate-on\">What to differentiate on\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-to-differentiate-on\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What to differentiate on”\u003C/span>\u003C/a>\u003C/div>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Linked filtering with contribution percentages\u003C/strong>: No competitor, including EDAScout, provides inline eta-squared contribution percentages on filter chips. This is VariScout’s most distinctive feature.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Four Lenses simultaneous view\u003C/strong>: EDAScout’s one-chart-per-page model is the industry default. VariScout’s four simultaneous charts with linked filtering is a genuine differentiator.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Correct statistics\u003C/strong>: Proper F-distribution p-values, correct between-group eta-squared, and comprehensive test coverage are competitive advantages that matter deeply to quality professionals.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Offline-first architecture\u003C/strong>: EDAScout requires a server (Express + SQLite). VariScout’s browser-only operation means data never leaves the user’s device --- a significant advantage for manufacturing environments with data sensitivity requirements.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Methodology over AI\u003C/strong>: EDAScout’s AI rollback arc validates VariScout’s approach of teaching methodology through documentation, glossary, and visual cues rather than depending on AI-mediated guidance. The methodology approach is more reliable, doesn’t require API connectivity, and builds analyst capability rather than tool dependency.\u003C/p>\n\u003C/li>\n\u003C/ol>", + { + "headings": 13076, + "localImagePaths": 13188, + "remoteImagePaths": 13189, + "frontmatter": 13190, + "imagePaths": 13191 + }, + [ + 13077, 13079, 13082, 13085, 13088, 13091, 13094, 13097, 13100, 13103, 13106, 13109, 13112, + 13115, 13118, 13121, 13123, 13126, 13129, 13132, 13135, 13138, 13140, 13143, 13146, 13149, + 13152, 13155, 13158, 13161, 13164, 13167, 13170, 13173, 13176, 13179, 13182, 13185 + ], + { "depth": 30, "slug": 13078, "text": 13066 }, + "edascout-competitive-benchmark", + { "depth": 33, "slug": 13080, "text": 13081 }, + "product-profile", + "Product Profile", + { "depth": 33, "slug": 13083, "text": 13084 }, + "version-evolution", + "Version Evolution", + { "depth": 79, "slug": 13086, "text": 13087 }, + "v4-----basic-spc-tool", + "v4 --- Basic SPC Tool", + { "depth": 79, "slug": 13089, "text": 13090 }, + "v6-----major-ai-expansion", + "v6 --- Major AI Expansion", + { "depth": 79, "slug": 13092, "text": 13093 }, + "v7-----complete-ai-rollback", + "v7 --- Complete AI Rollback", + { "depth": 79, "slug": 13095, "text": 13096 }, + "v9-----ai-restoration-with-refinements", + "v9 --- AI Restoration with Refinements", + { "depth": 79, "slug": 13098, "text": 13099 }, + "what-the-arc-tells-us", + "What the arc tells us", + { "depth": 33, "slug": 13101, "text": 13102 }, + "data-upload--column-classification", + "Data Upload & Column Classification", + { "depth": 79, "slug": 13104, "text": 13105 }, + "edascouts-parsing-pipeline", + "EDAScout’s parsing pipeline", + { "depth": 79, "slug": 13107, "text": 13108 }, + "comparison-to-variscout", + "Comparison to VariScout", + { "depth": 33, "slug": 13110, "text": 13111 }, + "filtering--drill-down-architecture", + "Filtering & Drill-Down Architecture", + { "depth": 79, "slug": 13113, "text": 13114 }, + "subgroupexplorermodal", + "SubgroupExplorerModal", + { "depth": 79, "slug": 13116, "text": 13117 }, + "categorygrid-variance-coloring", + "CategoryGrid variance coloring", + { "depth": 79, "slug": 13119, "text": 13120 }, + "filter-persistence", + "Filter persistence", + { "depth": 79, "slug": 13122, "text": 13108 }, + "comparison-to-variscout-1", + { "depth": 33, "slug": 13124, "text": 13125 }, + "brush-selection-unique-feature", + "Brush Selection (Unique Feature)", + { "depth": 79, "slug": 13127, "text": 13128 }, + "evaluation-for-variscout", + "Evaluation for VariScout", + { "depth": 33, "slug": 13130, "text": 13131 }, + "cross-analysis-navigation", + "Cross-Analysis Navigation", + { "depth": 79, "slug": 13133, "text": 13134 }, + "page-per-analysis-architecture", + "Page-per-analysis architecture", + { "depth": 79, "slug": 13136, "text": 13137 }, + "data-transfer-between-pages", + "Data transfer between pages", + { "depth": 79, "slug": 13139, "text": 13108 }, + "comparison-to-variscout-2", + { "depth": 33, "slug": 13141, "text": 13142 }, + "statistical-quality-assessment", + "Statistical Quality Assessment", + { "depth": 79, "slug": 13144, "text": 13145 }, + "p-value-bucket-approximation", + "P-value bucket approximation", + { "depth": 79, "slug": 13147, "text": 13148 }, + "percentoftotal-calculation-error", + "percentOfTotal calculation error", + { "depth": 79, "slug": 13150, "text": 13151 }, + "implications", + "Implications", + { "depth": 33, "slug": 13153, "text": 13154 }, + "feature-comparison-matrix", + "Feature Comparison Matrix", + { "depth": 33, "slug": 13156, "text": 13157 }, + "how-edascout-addresses-our-6-tensions", + "How EDAScout Addresses Our 6 Tensions", + { "depth": 79, "slug": 13159, "text": 13160 }, + "1-hierarchy-assumption", + "1. Hierarchy Assumption", + { "depth": 79, "slug": 13162, "text": 13163 }, + "2-discoverability", + "2. Discoverability", + { "depth": 79, "slug": 13165, "text": 13166 }, + "3-factor-ordering", + "3. Factor Ordering", + { "depth": 79, "slug": 13168, "text": 13169 }, + "4-when-to-stop", + "4. When to Stop", + { "depth": 79, "slug": 13171, "text": 13172 }, + "5-mobile-screen-budget", + "5. Mobile Screen Budget", + { "depth": 79, "slug": 13174, "text": 13175 }, + "6-path-dependency", + "6. Path Dependency", + { "depth": 33, "slug": 13177, "text": 13178 }, + "strategic-implications-for-variscout", + "Strategic Implications for VariScout", + { "depth": 79, "slug": 13180, "text": 13181 }, + "what-to-learn", + "What to learn", + { "depth": 79, "slug": 13183, "text": 13184 }, + "what-to-avoid", + "What to avoid", + { "depth": 79, "slug": 13186, "text": 13187 }, + "what-to-differentiate-on", + "What to differentiate on", + [], + [], + { "title": 13066 }, + [], + "01-vision/evaluations/competitive/jmp-benchmark", + { + "id": 13192, + "data": 13194, + "body": 13199, + "filePath": 13200, + "digest": 13201, + "rendered": 13202 + }, + { + "title": 13195, + "editUrl": 16, + "head": 13196, + "template": 18, + "sidebar": 13197, + "pagefind": 16, + "draft": 20 + }, + "JMP Competitive Benchmark", + [], + { "hidden": 20, "attrs": 13198 }, + {}, + "# JMP Competitive Benchmark\n\n> Based on public documentation, published feature sets, and market positioning knowledge. Unlike the [EDAScout Benchmark](edascout-benchmark.md), this assessment does not include direct codebase analysis.\n\n---\n\n## Product Profile\n\n| Dimension | JMP | VariScout |\n| ------------------- | --------------------------------------------------------------- | ------------------------------------------------------- |\n| **Platform** | Desktop application (macOS, Windows) | Browser-based (PWA, Azure, Excel Add-in) |\n| **Pricing** | $1,785+/year (Pro: $14,900+/year) | From €99/month (Azure) or free (PWA) |\n| **Distribution** | SAS direct sales, academic licenses | Azure Marketplace, AppSource, public URL |\n| **Target audience** | Scientists, engineers, advanced analysts | Quality practitioners, Green Belts, learners |\n| **Market position** | Premium visual analytics + statistics (SAS product) | Lightweight variation analysis tool |\n| **Analysis model** | Platform-based: Graph Builder, Fit Model, specialized platforms | Four Lenses: 4 coordinated charts with linked filtering |\n| **Navigation** | Launch platforms from menu, each opens in own window | Progressive stratification drill-down |\n| **Parent company** | SAS Institute | Independent |\n\n---\n\n## Core Capabilities\n\nJMP has the strongest EDA heritage of any traditional statistical package. Its Graph Builder and interactive visualization tools set it apart from Minitab's menu-dialog-output model. The capabilities relevant to VariScout include:\n\n### Graph Builder\n\nJMP's signature feature. A drag-and-drop chart construction interface where the user drags variables onto X, Y, Group, Wrap, and Overlay drop zones. The chart type adjusts automatically based on variable types (continuous → scatterplot, categorical → bar chart). Multiple variables can be layered to create complex visualizations interactively.\n\nGraph Builder is genuinely exploratory — the analyst experiments with variable combinations and the visualization updates in real time. This is the closest any major statistical tool comes to supporting open-ended visual investigation. However, it's chart-centric (building one chart at a time), not investigation-centric (guiding through a multi-chart workflow).\n\n### Fit Model Platform\n\nJMP's general modeling environment. The analyst specifies response variables, model effects (main effects, interactions, nested terms), and the platform fits the model and produces diagnostics. Interaction terms must be explicitly added — JMP doesn't automatically scan for interactions, but the Effect Summary table ranks terms by significance.\n\n### Prediction Profiler\n\nAn interactive visualization of a fitted model's factor effects. Each factor gets a slider; moving the slider shows the predicted response change. The Profiler is powerful for understanding factor effects once a model is fitted, but it requires model specification first — the analyst must already know which factors to include.\n\nThe Interaction Profiler extension shows two-factor interaction surfaces. Again, the model must be fitted first, and the interactions must be included in the model specification.\n\n### Scatterplot Matrix and Correlation\n\nPairwise scatterplots and correlation coefficients across multiple variables. Useful for identifying relationships but separate from the modeling workflow — the analyst must navigate to a different platform to act on the patterns observed.\n\n### Column Contributions\n\nIn fitted models, JMP's Effect Summary panel shows variable importance ranked by LogWorth (-log10 of p-value) or sum of squares contribution. This is conceptually similar to VariScout's eta-squared ranking but lives inside the modeling platform rather than being integrated into the navigation workflow.\n\n### Distribution Platform\n\nHistograms, quantile plots, and goodness-of-fit tests. Each variable gets its own panel. Capability indices (Cpk, Ppk) are available through the Process Capability platform, which is separate from the Distribution platform.\n\n### Control Chart Builder\n\nInteractive control chart construction with drag-and-drop. Supports I-MR, Xbar-R, P, NP, C, U. The builder allows phased control limits. Unlike Minitab's menu-dialog approach, JMP's control chart builder is interactive — the analyst can exclude points and update limits in real time.\n\n---\n\n## Analysis and Investigation Workflow\n\nJMP's workflow is **platform-centric**:\n\n1. The analyst opens a platform (Graph Builder, Fit Model, Distribution, etc.)\n2. They drag variables and configure the analysis interactively\n3. They read the output within the platform window\n4. They open another platform for a different perspective\n5. Each platform operates independently (no linked filtering between platforms)\n\nJMP's approach is more interactive than Minitab's menu-dialog model but still analysis-type-centric rather than investigation-centric. The analyst decides which platform to open and which variables to examine. There is no workflow that guides the analyst from \"I see variation\" to \"here's what's causing it\" through connected interactions.\n\nFor variation investigation, a JMP user would:\n\n1. Open Graph Builder to explore distributions and relationships visually\n2. Open Fit Model to fit an ANOVA or regression and examine the Effect Summary\n3. Read the Effect Summary to identify important factors and interactions\n4. Open the Prediction Profiler to understand factor effects interactively\n5. Open the Control Chart Builder for the relevant measurement\n6. Open Process Capability for Cpk assessment\n\nEach step requires opening a new platform. The platforms don't share filter state — filtering in Graph Builder doesn't update the Fit Model output. The analyst must mentally track which findings connect across platforms.\n\n---\n\n## How JMP Addresses Our 6 Tensions\n\n| Tension | JMP's Approach | Assessment |\n| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |\n| **Hierarchy Assumption** | Fit Model supports interaction terms. The Interaction Profiler visualizes two-factor interactions. But interaction terms must be explicitly added to the model — JMP doesn't automatically detect or highlight them during exploration. | Partially addressed through modeling, not through exploration workflow. |\n| **Discoverability** | Graph Builder makes visual exploration highly accessible. The drag-and-drop interface invites experimentation. But moving from Graph Builder to statistical modeling requires a platform switch — the exploratory and confirmatory workflows are disconnected. | Partially addressed for visual patterns; not addressed for statistical investigation workflow. |\n| **Factor Ordering** | Effect Summary in Fit Model ranks terms by significance (LogWorth). Graph Builder surfaces visual patterns that the analyst interprets to prioritize factors. But neither provides navigation guidance — the ranking is information, not an actionable \"drill here next\" prompt. | Information available in modeling platform; not integrated into visual exploration. |\n| **When to Stop** | No stopping guidance. Model fit statistics (R-squared, lack of fit) indicate model adequacy but don't translate to investigation completeness. | Not addressed. |\n| **Mobile Screen Budget** | Not applicable. JMP is desktop software with no mobile interface. JMP Live (web publishing) is view-only. | Not applicable. |\n| **Path Dependency** | No drill-down path exists, so no path dependency. Platforms are independent windows. The analyst's investigation sequence is entirely self-directed. | Avoided by not having a drill-down model. |\n\n---\n\n## Feature Comparison\n\n| Capability | JMP | VariScout |\n| ------------------------------- | ------------------------------------------------ | ------------------------------------------ |\n| Interactive chart building | Graph Builder (drag-and-drop) | Pre-configured Four Lenses |\n| Control charts | Control Chart Builder (interactive) | I-Chart with linked filtering |\n| Capability analysis | Process Capability platform | Integrated capability lens |\n| Boxplot | Graph Builder element | Integrated with drill-down filtering |\n| Pareto chart | Quality and Process > Pareto | Integrated with drill-down filtering |\n| ANOVA / factor ranking | Fit Model with Effect Summary | One-way with eta-squared visual ranking |\n| Interaction detection | Fit Model (explicit interaction terms) | Planned: interaction heatmap |\n| Regression | Fit Model, Fit Y by X | Simple and multiple regression |\n| Gage R&R | MSA platform (Variability / Attribute charts) | Not available |\n| Prediction Profiler | Yes (interactive model profiling) | Not available (different approach) |\n| DOE | Full suite (custom design, definitive screening) | Not available (different problem domain) |\n| Linked filtering across charts | No (each platform is independent) | Yes (core differentiator) |\n| Progressive drill-down | No | Yes (core differentiator) |\n| Variation contribution tracking | Effect Summary (LogWorth, SS%) | Cumulative eta-squared in variation funnel |\n| Browser-based | No (JMP Live is view-only publishing) | Yes (PWA, offline-first) |\n| Price for classroom use | Academic licensing (discounted) | Free (PWA) |\n\n---\n\n## Strategic Implications for VariScout\n\n### Where We Differentiate\n\n- **Investigation workflow**: JMP provides excellent tools for building individual analyses. VariScout provides an investigation workflow where one finding leads to the next through connected interactions. The analyst doesn't need to decide which platform to open next — the drill-down guides the investigation.\n- **No model required**: JMP's strongest features (Prediction Profiler, Effect Summary) require fitting a model first. VariScout's progressive stratification works directly on the data without requiring the analyst to specify model terms.\n- **Price and deployment**: JMP starts at $1,785/year for desktop software. VariScout's PWA is free for training; the Azure app starts at €99/month for teams.\n- **Learning curve**: JMP's power comes with complexity. Graph Builder is intuitive, but moving to Fit Model and interpreting diagnostics requires statistical training. VariScout targets analysts who need answers without formal statistics education.\n\n### What We Can Learn\n\n- **Graph Builder interaction model**: The drag-and-drop exploration approach is effective for open-ended analysis. VariScout's factor suggestion pattern draws on similar exploratory philosophy, using statistical ranking rather than drag-and-drop.\n- **Effect Summary ranking**: JMP's LogWorth ranking in fitted models is a proven way to communicate factor importance. VariScout's eta-squared ranking in the boxplot serves the same purpose with less statistical overhead.\n- **Interactive profiling**: The Prediction Profiler's \"slide and see\" interaction for understanding factor effects is a strong UX pattern. If VariScout adds interactive \"what-if\" exploration, this is the benchmark.\n\n### What to Avoid Adopting\n\n- **Platform fragmentation**: JMP's multi-window, multi-platform architecture means the analyst manages investigation state mentally. VariScout's single-view, linked-filtering approach is a deliberate simplification.\n- **Model-first analysis**: Requiring model specification before exploration inverts the EDA workflow. VariScout should keep the principle that exploration comes before modeling.\n- **Feature depth over workflow clarity**: JMP's depth serves advanced users well but creates barriers for the Green Belt audience. VariScout should prioritize workflow clarity over analytical depth.", + "src/content/docs/01-vision/evaluations/competitive/jmp-benchmark.md", + "a76436a4ce8293d3", + { "html": 13203, "metadata": 13204 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"jmp-competitive-benchmark\">JMP Competitive Benchmark\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#jmp-competitive-benchmark\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “JMP Competitive Benchmark”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Based on public documentation, published feature sets, and market positioning knowledge. Unlike the \u003Ca href=\"edascout-benchmark.md\">EDAScout Benchmark\u003C/a>, this assessment does not include direct codebase analysis.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"product-profile\">Product Profile\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#product-profile\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Profile”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>JMP\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Platform\u003C/strong>\u003C/td>\u003Ctd>Desktop application (macOS, Windows)\u003C/td>\u003Ctd>Browser-based (PWA, Azure, Excel Add-in)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pricing\u003C/strong>\u003C/td>\u003Ctd>$1,785+/year (Pro: $14,900+/year)\u003C/td>\u003Ctd>From €99/month (Azure) or free (PWA)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Distribution\u003C/strong>\u003C/td>\u003Ctd>SAS direct sales, academic licenses\u003C/td>\u003Ctd>Azure Marketplace, AppSource, public URL\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Target audience\u003C/strong>\u003C/td>\u003Ctd>Scientists, engineers, advanced analysts\u003C/td>\u003Ctd>Quality practitioners, Green Belts, learners\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Market position\u003C/strong>\u003C/td>\u003Ctd>Premium visual analytics + statistics (SAS product)\u003C/td>\u003Ctd>Lightweight variation analysis tool\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Analysis model\u003C/strong>\u003C/td>\u003Ctd>Platform-based: Graph Builder, Fit Model, specialized platforms\u003C/td>\u003Ctd>Four Lenses: 4 coordinated charts with linked filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Navigation\u003C/strong>\u003C/td>\u003Ctd>Launch platforms from menu, each opens in own window\u003C/td>\u003Ctd>Progressive stratification drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Parent company\u003C/strong>\u003C/td>\u003Ctd>SAS Institute\u003C/td>\u003Ctd>Independent\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-capabilities\">Core Capabilities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-capabilities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Capabilities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>JMP has the strongest EDA heritage of any traditional statistical package. Its Graph Builder and interactive visualization tools set it apart from Minitab’s menu-dialog-output model. The capabilities relevant to VariScout include:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"graph-builder\">Graph Builder\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#graph-builder\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Graph Builder”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>JMP’s signature feature. A drag-and-drop chart construction interface where the user drags variables onto X, Y, Group, Wrap, and Overlay drop zones. The chart type adjusts automatically based on variable types (continuous → scatterplot, categorical → bar chart). Multiple variables can be layered to create complex visualizations interactively.\u003C/p>\n\u003Cp>Graph Builder is genuinely exploratory — the analyst experiments with variable combinations and the visualization updates in real time. This is the closest any major statistical tool comes to supporting open-ended visual investigation. However, it’s chart-centric (building one chart at a time), not investigation-centric (guiding through a multi-chart workflow).\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"fit-model-platform\">Fit Model Platform\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#fit-model-platform\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Fit Model Platform”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>JMP’s general modeling environment. The analyst specifies response variables, model effects (main effects, interactions, nested terms), and the platform fits the model and produces diagnostics. Interaction terms must be explicitly added — JMP doesn’t automatically scan for interactions, but the Effect Summary table ranks terms by significance.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"prediction-profiler\">Prediction Profiler\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#prediction-profiler\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Prediction Profiler”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>An interactive visualization of a fitted model’s factor effects. Each factor gets a slider; moving the slider shows the predicted response change. The Profiler is powerful for understanding factor effects once a model is fitted, but it requires model specification first — the analyst must already know which factors to include.\u003C/p>\n\u003Cp>The Interaction Profiler extension shows two-factor interaction surfaces. Again, the model must be fitted first, and the interactions must be included in the model specification.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"scatterplot-matrix-and-correlation\">Scatterplot Matrix and Correlation\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#scatterplot-matrix-and-correlation\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Scatterplot Matrix and Correlation”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Pairwise scatterplots and correlation coefficients across multiple variables. Useful for identifying relationships but separate from the modeling workflow — the analyst must navigate to a different platform to act on the patterns observed.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"column-contributions\">Column Contributions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#column-contributions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Column Contributions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>In fitted models, JMP’s Effect Summary panel shows variable importance ranked by LogWorth (-log10 of p-value) or sum of squares contribution. This is conceptually similar to VariScout’s eta-squared ranking but lives inside the modeling platform rather than being integrated into the navigation workflow.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"distribution-platform\">Distribution Platform\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#distribution-platform\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Distribution Platform”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Histograms, quantile plots, and goodness-of-fit tests. Each variable gets its own panel. Capability indices (Cpk, Ppk) are available through the Process Capability platform, which is separate from the Distribution platform.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"control-chart-builder\">Control Chart Builder\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#control-chart-builder\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Control Chart Builder”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Interactive control chart construction with drag-and-drop. Supports I-MR, Xbar-R, P, NP, C, U. The builder allows phased control limits. Unlike Minitab’s menu-dialog approach, JMP’s control chart builder is interactive — the analyst can exclude points and update limits in real time.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysis-and-investigation-workflow\">Analysis and Investigation Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-and-investigation-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis and Investigation Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>JMP’s workflow is \u003Cstrong>platform-centric\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>The analyst opens a platform (Graph Builder, Fit Model, Distribution, etc.)\u003C/li>\n\u003Cli>They drag variables and configure the analysis interactively\u003C/li>\n\u003Cli>They read the output within the platform window\u003C/li>\n\u003Cli>They open another platform for a different perspective\u003C/li>\n\u003Cli>Each platform operates independently (no linked filtering between platforms)\u003C/li>\n\u003C/ol>\n\u003Cp>JMP’s approach is more interactive than Minitab’s menu-dialog model but still analysis-type-centric rather than investigation-centric. The analyst decides which platform to open and which variables to examine. There is no workflow that guides the analyst from “I see variation” to “here’s what’s causing it” through connected interactions.\u003C/p>\n\u003Cp>For variation investigation, a JMP user would:\u003C/p>\n\u003Col>\n\u003Cli>Open Graph Builder to explore distributions and relationships visually\u003C/li>\n\u003Cli>Open Fit Model to fit an ANOVA or regression and examine the Effect Summary\u003C/li>\n\u003Cli>Read the Effect Summary to identify important factors and interactions\u003C/li>\n\u003Cli>Open the Prediction Profiler to understand factor effects interactively\u003C/li>\n\u003Cli>Open the Control Chart Builder for the relevant measurement\u003C/li>\n\u003Cli>Open Process Capability for Cpk assessment\u003C/li>\n\u003C/ol>\n\u003Cp>Each step requires opening a new platform. The platforms don’t share filter state — filtering in Graph Builder doesn’t update the Fit Model output. The analyst must mentally track which findings connect across platforms.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-jmp-addresses-our-6-tensions\">How JMP Addresses Our 6 Tensions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-jmp-addresses-our-6-tensions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How JMP Addresses Our 6 Tensions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tension\u003C/th>\u003Cth>JMP’s Approach\u003C/th>\u003Cth>Assessment\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Hierarchy Assumption\u003C/strong>\u003C/td>\u003Ctd>Fit Model supports interaction terms. The Interaction Profiler visualizes two-factor interactions. But interaction terms must be explicitly added to the model — JMP doesn’t automatically detect or highlight them during exploration.\u003C/td>\u003Ctd>Partially addressed through modeling, not through exploration workflow.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Discoverability\u003C/strong>\u003C/td>\u003Ctd>Graph Builder makes visual exploration highly accessible. The drag-and-drop interface invites experimentation. But moving from Graph Builder to statistical modeling requires a platform switch — the exploratory and confirmatory workflows are disconnected.\u003C/td>\u003Ctd>Partially addressed for visual patterns; not addressed for statistical investigation workflow.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Factor Ordering\u003C/strong>\u003C/td>\u003Ctd>Effect Summary in Fit Model ranks terms by significance (LogWorth). Graph Builder surfaces visual patterns that the analyst interprets to prioritize factors. But neither provides navigation guidance — the ranking is information, not an actionable “drill here next” prompt.\u003C/td>\u003Ctd>Information available in modeling platform; not integrated into visual exploration.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>When to Stop\u003C/strong>\u003C/td>\u003Ctd>No stopping guidance. Model fit statistics (R-squared, lack of fit) indicate model adequacy but don’t translate to investigation completeness.\u003C/td>\u003Ctd>Not addressed.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mobile Screen Budget\u003C/strong>\u003C/td>\u003Ctd>Not applicable. JMP is desktop software with no mobile interface. JMP Live (web publishing) is view-only.\u003C/td>\u003Ctd>Not applicable.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Path Dependency\u003C/strong>\u003C/td>\u003Ctd>No drill-down path exists, so no path dependency. Platforms are independent windows. The analyst’s investigation sequence is entirely self-directed.\u003C/td>\u003Ctd>Avoided by not having a drill-down model.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-comparison\">Feature Comparison\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>JMP\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Interactive chart building\u003C/td>\u003Ctd>Graph Builder (drag-and-drop)\u003C/td>\u003Ctd>Pre-configured Four Lenses\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Control charts\u003C/td>\u003Ctd>Control Chart Builder (interactive)\u003C/td>\u003Ctd>I-Chart with linked filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability analysis\u003C/td>\u003Ctd>Process Capability platform\u003C/td>\u003Ctd>Integrated capability lens\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Graph Builder element\u003C/td>\u003Ctd>Integrated with drill-down filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto chart\u003C/td>\u003Ctd>Quality and Process > Pareto\u003C/td>\u003Ctd>Integrated with drill-down filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ANOVA / factor ranking\u003C/td>\u003Ctd>Fit Model with Effect Summary\u003C/td>\u003Ctd>One-way with eta-squared visual ranking\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Interaction detection\u003C/td>\u003Ctd>Fit Model (explicit interaction terms)\u003C/td>\u003Ctd>Planned: interaction heatmap\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regression\u003C/td>\u003Ctd>Fit Model, Fit Y by X\u003C/td>\u003Ctd>Simple and multiple regression\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Gage R&R\u003C/td>\u003Ctd>MSA platform (Variability / Attribute charts)\u003C/td>\u003Ctd>Not available\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Prediction Profiler\u003C/td>\u003Ctd>Yes (interactive model profiling)\u003C/td>\u003Ctd>Not available (different approach)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>DOE\u003C/td>\u003Ctd>Full suite (custom design, definitive screening)\u003C/td>\u003Ctd>Not available (different problem domain)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Linked filtering across charts\u003C/td>\u003Ctd>No (each platform is independent)\u003C/td>\u003Ctd>Yes (core differentiator)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Progressive drill-down\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Yes (core differentiator)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Variation contribution tracking\u003C/td>\u003Ctd>Effect Summary (LogWorth, SS%)\u003C/td>\u003Ctd>Cumulative eta-squared in variation funnel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Browser-based\u003C/td>\u003Ctd>No (JMP Live is view-only publishing)\u003C/td>\u003Ctd>Yes (PWA, offline-first)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Price for classroom use\u003C/td>\u003Ctd>Academic licensing (discounted)\u003C/td>\u003Ctd>Free (PWA)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-implications-for-variscout\">Strategic Implications for VariScout\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-implications-for-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Implications for VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"where-we-differentiate\">Where We Differentiate\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#where-we-differentiate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Where We Differentiate”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Investigation workflow\u003C/strong>: JMP provides excellent tools for building individual analyses. VariScout provides an investigation workflow where one finding leads to the next through connected interactions. The analyst doesn’t need to decide which platform to open next — the drill-down guides the investigation.\u003C/li>\n\u003Cli>\u003Cstrong>No model required\u003C/strong>: JMP’s strongest features (Prediction Profiler, Effect Summary) require fitting a model first. VariScout’s progressive stratification works directly on the data without requiring the analyst to specify model terms.\u003C/li>\n\u003Cli>\u003Cstrong>Price and deployment\u003C/strong>: JMP starts at $1,785/year for desktop software. VariScout’s PWA is free for training; the Azure app starts at €99/month for teams.\u003C/li>\n\u003Cli>\u003Cstrong>Learning curve\u003C/strong>: JMP’s power comes with complexity. Graph Builder is intuitive, but moving to Fit Model and interpreting diagnostics requires statistical training. VariScout targets analysts who need answers without formal statistics education.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-we-can-learn\">What We Can Learn\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-we-can-learn\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What We Can Learn”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Graph Builder interaction model\u003C/strong>: The drag-and-drop exploration approach is effective for open-ended analysis. VariScout’s factor suggestion pattern draws on similar exploratory philosophy, using statistical ranking rather than drag-and-drop.\u003C/li>\n\u003Cli>\u003Cstrong>Effect Summary ranking\u003C/strong>: JMP’s LogWorth ranking in fitted models is a proven way to communicate factor importance. VariScout’s eta-squared ranking in the boxplot serves the same purpose with less statistical overhead.\u003C/li>\n\u003Cli>\u003Cstrong>Interactive profiling\u003C/strong>: The Prediction Profiler’s “slide and see” interaction for understanding factor effects is a strong UX pattern. If VariScout adds interactive “what-if” exploration, this is the benchmark.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-to-avoid-adopting\">What to Avoid Adopting\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-to-avoid-adopting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What to Avoid Adopting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Platform fragmentation\u003C/strong>: JMP’s multi-window, multi-platform architecture means the analyst manages investigation state mentally. VariScout’s single-view, linked-filtering approach is a deliberate simplification.\u003C/li>\n\u003Cli>\u003Cstrong>Model-first analysis\u003C/strong>: Requiring model specification before exploration inverts the EDA workflow. VariScout should keep the principle that exploration comes before modeling.\u003C/li>\n\u003Cli>\u003Cstrong>Feature depth over workflow clarity\u003C/strong>: JMP’s depth serves advanced users well but creates barriers for the Green Belt audience. VariScout should prioritize workflow clarity over analytical depth.\u003C/li>\n\u003C/ul>", + { + "headings": 13205, + "localImagePaths": 13250, + "remoteImagePaths": 13251, + "frontmatter": 13252, + "imagePaths": 13253 + }, + [ + 13206, 13208, 13209, 13212, 13215, 13218, 13221, 13224, 13227, 13230, 13233, 13236, 13239, + 13240, 13241, 13244, 13247 + ], + { "depth": 30, "slug": 13207, "text": 13195 }, + "jmp-competitive-benchmark", + { "depth": 33, "slug": 13080, "text": 13081 }, + { "depth": 33, "slug": 13210, "text": 13211 }, + "core-capabilities", + "Core Capabilities", + { "depth": 79, "slug": 13213, "text": 13214 }, + "graph-builder", + "Graph Builder", + { "depth": 79, "slug": 13216, "text": 13217 }, + "fit-model-platform", + "Fit Model Platform", + { "depth": 79, "slug": 13219, "text": 13220 }, + "prediction-profiler", + "Prediction Profiler", + { "depth": 79, "slug": 13222, "text": 13223 }, + "scatterplot-matrix-and-correlation", + "Scatterplot Matrix and Correlation", + { "depth": 79, "slug": 13225, "text": 13226 }, + "column-contributions", + "Column Contributions", + { "depth": 79, "slug": 13228, "text": 13229 }, + "distribution-platform", + "Distribution Platform", + { "depth": 79, "slug": 13231, "text": 13232 }, + "control-chart-builder", + "Control Chart Builder", + { "depth": 33, "slug": 13234, "text": 13235 }, + "analysis-and-investigation-workflow", + "Analysis and Investigation Workflow", + { "depth": 33, "slug": 13237, "text": 13238 }, + "how-jmp-addresses-our-6-tensions", + "How JMP Addresses Our 6 Tensions", + { "depth": 33, "slug": 2115, "text": 2116 }, + { "depth": 33, "slug": 13177, "text": 13178 }, + { "depth": 79, "slug": 13242, "text": 13243 }, + "where-we-differentiate", + "Where We Differentiate", + { "depth": 79, "slug": 13245, "text": 13246 }, + "what-we-can-learn", + "What We Can Learn", + { "depth": 79, "slug": 13248, "text": 13249 }, + "what-to-avoid-adopting", + "What to Avoid Adopting", + [], + [], + { "title": 13195 }, + [], + "01-vision/evaluations/competitive/minitab-benchmark", + { + "id": 13254, + "data": 13256, + "body": 13261, + "filePath": 13262, + "digest": 13263, + "rendered": 13264 + }, + { + "title": 13257, + "editUrl": 16, + "head": 13258, + "template": 18, + "sidebar": 13259, + "pagefind": 16, + "draft": 20 + }, + "Minitab Competitive Benchmark", + [], + { "hidden": 20, "attrs": 13260 }, + {}, + "# Minitab Competitive Benchmark\n\n> Based on public documentation, published feature sets, and market positioning knowledge. Unlike the [EDAScout Benchmark](edascout-benchmark.md), this assessment does not include direct codebase analysis.\n\n---\n\n## Product Profile\n\n| Dimension | Minitab | VariScout |\n| ------------------- | ---------------------------------------------------------------- | ------------------------------------------------------- |\n| **Platform** | Desktop application (Windows, macOS) | Browser-based (PWA, Azure, Excel Add-in) |\n| **Pricing** | ~$1,700/year single user, ~$700/year academic | From €99/month (Azure) or free (PWA) |\n| **Distribution** | Direct sales, site licenses, academic programs | Azure Marketplace, AppSource, public URL |\n| **Target audience** | Statisticians, quality engineers, Black Belts | Quality practitioners, Green Belts, learners |\n| **Market position** | Industry standard for statistical analysis (30+ years) | Lightweight variation analysis alternative |\n| **Analysis model** | Menu-driven: select analysis type, configure dialog, view output | Four Lenses: 4 coordinated charts with linked filtering |\n| **Navigation** | 200+ analysis types across deeply nested menus | Progressive stratification drill-down |\n\n---\n\n## Core Capabilities\n\nMinitab's feature set is the result of 30+ years of accumulation. The capabilities relevant to VariScout's analytical space include:\n\n### SPC and Control Charts\n\nMinitab offers a comprehensive suite of control charts: I-MR, Xbar-R, Xbar-S, P, NP, C, U, EWMA, CUSUM, and more. Each chart type is a separate menu selection with a multi-step configuration dialog. Control limits are calculated automatically but customization requires navigating options dialogs. The breadth is unmatched; the interaction cost per chart is high.\n\n### Capability Analysis\n\nFull capability study suite: Cp, Cpk, Pp, Ppk, Cpm, with distribution fitting (normal, Weibull, lognormal, etc.). Process capability sixpack combines multiple views in a single output. The analysis assumes the user has already identified the relevant subgroup and measurement — Minitab doesn't guide the user toward the right measurement to analyze.\n\n### ANOVA and Factor Analysis\n\nGeneral Linear Model, one-way ANOVA, two-way ANOVA, balanced/unbalanced designs, nested designs. Interaction plots are available as post-hoc visualization of fitted models. The user must specify the model terms manually — Minitab does not automatically surface which factors matter or rank them by contribution.\n\n### Regression\n\nSimple, multiple, stepwise, best subsets, binary/ordinal/nominal logistic, Poisson. Comprehensive model diagnostics. Stepwise selection automates variable selection but requires the user to set up the analysis and interpret diagnostic plots.\n\n### DOE (Design of Experiments)\n\nFull factorial, fractional factorial, response surface, mixture, Taguchi. Response Optimizer finds optimal factor settings from designed experiments. This is Minitab's deepest differentiator — a capability set that VariScout does not and will not replicate, as it requires controlled experimental data rather than observational process data.\n\n### Multi-Vari Charts\n\nPurpose-built chart type for visualizing factor interactions. Shows measurement variation across multiple factors simultaneously. Accessed as a separate analysis (Quality Tools > Multi-Vari Chart), not integrated into an investigation workflow.\n\n### Minitab Assistant\n\nGuided analysis selection introduced in recent versions. Uses a decision-tree approach: the user answers questions about their data and objective, and the Assistant recommends the appropriate statistical test. This is hypothesis-driven guidance (confirming a suspected cause) rather than exploration guidance (finding which factor matters). The Assistant directs the user to the right menu item; it doesn't guide them through an iterative investigation.\n\n---\n\n## Analysis and Investigation Workflow\n\nMinitab's workflow is fundamentally **menu-dialog-output**:\n\n1. The analyst has a hypothesis or question (\"Is Machine C different from Machine A?\")\n2. They navigate to the correct menu (Stat > ANOVA > One-Way)\n3. They configure the dialog (select response column, factor column, options)\n4. They read the output (session window text + graphs)\n5. They decide what to do next based on their own statistical knowledge\n\nEach analysis is a discrete, self-contained step. There is no linked filtering between outputs — running a one-way ANOVA on Machine does not automatically update the capability analysis or control chart. The analyst must manually re-run each analysis with new subsets. There is no concept of a \"drill-down path\" where one finding leads to the next through connected interactions.\n\nThe Session Window accumulates text output chronologically. Finding results from earlier analyses requires scrolling. There is no navigation structure that connects related analyses into an investigation narrative.\n\nFor variation investigation specifically, a Minitab user would:\n\n1. Run descriptive statistics to get an overview\n2. Run one-way ANOVA for each factor separately\n3. Examine eta-squared or SS values to rank factor importance (manually)\n4. Create subsets and re-run analyses for factor combinations (manually)\n5. Build a multi-vari chart to visualize interactions (separate analysis)\n6. Run capability analysis on the relevant subgroup (separate analysis)\n\nThis requires 6+ separate analysis steps, each initiated from menus. VariScout's progressive stratification accomplishes the same investigation through clicking boxplot bars, with all four charts updating simultaneously.\n\n---\n\n## How Minitab Addresses Our 6 Tensions\n\n| Tension | Minitab's Approach | Assessment |\n| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |\n| **Hierarchy Assumption** | Multi-vari charts can visualize interactions, but they're a separate analysis that the user must know to run. Interaction terms must be specified manually in GLM. | Not addressed in the workflow; available as a separate tool for experts. |\n| **Discoverability** | All 200+ analyses are listed in menus. The Assistant helps navigate. But the volume of options is itself a discoverability problem — finding the right analysis in nested menus is a known training challenge. | Partially addressed through Assistant; worsened by menu depth. |\n| **Factor Ordering** | ANOVA output includes SS and p-values that implicitly rank factors by contribution. But the ranking is in a text table, not a visual navigation element. The analyst must read the table and manually decide what to investigate next. | Information available but not actionable — no integration with navigation. |\n| **When to Stop** | No stopping guidance. The analyst decides based on statistical significance thresholds and domain knowledge. Minitab reports results; it doesn't suggest when the investigation is complete. | Not addressed. |\n| **Mobile Screen Budget** | Not applicable. Minitab is desktop software designed for large screens. No mobile or responsive interface. | Not applicable. |\n| **Path Dependency** | Each analysis is independent. There is no drill-down path, so there is no path dependency. But this independence means the analyst must manually manage the investigation sequence, which is the problem path dependency addresses. | Avoided by not having a drill-down model, at the cost of manual investigation management. |\n\n---\n\n## Feature Comparison\n\n| Capability | Minitab | VariScout |\n| ------------------------------------ | ------------------------------------------- | ---------------------------------------- |\n| Control charts (I-MR) | Yes, plus 20+ chart types | Yes (I-Chart) |\n| Capability analysis (Cp/Cpk) | Full suite with distribution fitting | Normal-based with spec limit input |\n| Boxplot | Yes, as standalone analysis | Yes, integrated with filtering |\n| Pareto chart | Yes, as standalone analysis | Yes, integrated with filtering |\n| ANOVA | GLM, one-way, multi-way, nested | One-way with eta-squared ranking |\n| Regression | Full suite (simple through logistic) | Simple and multiple regression |\n| Gage R&R | Full MSA suite (crossed, nested, expanded) | Not available |\n| DOE | Full factorial, response surface, mixture | Not available (different problem domain) |\n| Linked filtering across charts | No | Yes (core differentiator) |\n| Progressive drill-down | No | Yes (core differentiator) |\n| Variation contribution (eta-squared) | Available in ANOVA output (as SS%) | Visual, interactive, cumulative tracking |\n| Multi-measure performance analysis | No unified view | Performance Mode (Azure) |\n| Offline/browser-based | No (desktop installation required) | Yes (PWA, offline-first) |\n| Learning curve | Steep (training courses typically 3–5 days) | Minimal (guided by design) |\n| Price for classroom use | $700/year academic per seat | Free (PWA) |\n\n---\n\n## Strategic Implications for VariScout\n\n### Where We Differentiate\n\n- **Exploration UX**: VariScout's linked filtering and progressive stratification provide a fundamentally different investigation experience. Minitab requires the analyst to manage the investigation manually through sequential menu selections.\n- **Price and deployment**: Free browser-based tool vs. $1,700/year desktop software. For training contexts, this is the primary decision factor.\n- **Learning curve**: Minitab's depth creates a steep learning curve. Quality programs spend 3–5 days teaching the software. VariScout's design goal is zero software training.\n- **Methodology integration**: VariScout embeds the investigation methodology (progressive stratification) into the interaction design. Minitab provides tools; the analyst supplies the methodology.\n\n### What We Can Learn\n\n- **Multi-vari chart concept**: Minitab's multi-vari chart is a well-understood visualization for factor interactions. The interaction heatmap pattern draws on similar concepts but integrates them into the drill-down workflow.\n- **Capability sixpack layout**: Combining multiple capability views in a single output is effective for comprehensive assessment. VariScout's Four Lenses approach extends this concept.\n- **Assistant decision trees**: The idea of guided analysis selection has value, though VariScout's version (factor suggestion) operates within an EDA workflow rather than as a test-selection wizard.\n\n### What to Avoid Adopting\n\n- **Menu-driven architecture**: Minitab's menu depth is a known usability problem. VariScout should never evolve toward a menu-heavy interface.\n- **Disconnected analyses**: Each Minitab analysis being independent is the opposite of VariScout's linked-filtering model. Adding features that break the connection between charts would undermine the core differentiator.\n- **Feature accumulation**: Minitab's 200+ analysis types serve different audiences. VariScout should remain focused on the variation investigation workflow rather than becoming a general-purpose statistical package.", + "src/content/docs/01-vision/evaluations/competitive/minitab-benchmark.md", + "eb5174c147e6ae73", + { "html": 13265, "metadata": 13266 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"minitab-competitive-benchmark\">Minitab Competitive Benchmark\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#minitab-competitive-benchmark\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Minitab Competitive Benchmark”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Based on public documentation, published feature sets, and market positioning knowledge. Unlike the \u003Ca href=\"edascout-benchmark.md\">EDAScout Benchmark\u003C/a>, this assessment does not include direct codebase analysis.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"product-profile\">Product Profile\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#product-profile\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Profile”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>Minitab\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Platform\u003C/strong>\u003C/td>\u003Ctd>Desktop application (Windows, macOS)\u003C/td>\u003Ctd>Browser-based (PWA, Azure, Excel Add-in)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pricing\u003C/strong>\u003C/td>\u003Ctd>~$1,700/year single user, ~$700/year academic\u003C/td>\u003Ctd>From €99/month (Azure) or free (PWA)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Distribution\u003C/strong>\u003C/td>\u003Ctd>Direct sales, site licenses, academic programs\u003C/td>\u003Ctd>Azure Marketplace, AppSource, public URL\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Target audience\u003C/strong>\u003C/td>\u003Ctd>Statisticians, quality engineers, Black Belts\u003C/td>\u003Ctd>Quality practitioners, Green Belts, learners\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Market position\u003C/strong>\u003C/td>\u003Ctd>Industry standard for statistical analysis (30+ years)\u003C/td>\u003Ctd>Lightweight variation analysis alternative\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Analysis model\u003C/strong>\u003C/td>\u003Ctd>Menu-driven: select analysis type, configure dialog, view output\u003C/td>\u003Ctd>Four Lenses: 4 coordinated charts with linked filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Navigation\u003C/strong>\u003C/td>\u003Ctd>200+ analysis types across deeply nested menus\u003C/td>\u003Ctd>Progressive stratification drill-down\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-capabilities\">Core Capabilities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-capabilities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Capabilities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Minitab’s feature set is the result of 30+ years of accumulation. The capabilities relevant to VariScout’s analytical space include:\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"spc-and-control-charts\">SPC and Control Charts\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#spc-and-control-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SPC and Control Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Minitab offers a comprehensive suite of control charts: I-MR, Xbar-R, Xbar-S, P, NP, C, U, EWMA, CUSUM, and more. Each chart type is a separate menu selection with a multi-step configuration dialog. Control limits are calculated automatically but customization requires navigating options dialogs. The breadth is unmatched; the interaction cost per chart is high.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"capability-analysis\">Capability Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#capability-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Capability Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Full capability study suite: Cp, Cpk, Pp, Ppk, Cpm, with distribution fitting (normal, Weibull, lognormal, etc.). Process capability sixpack combines multiple views in a single output. The analysis assumes the user has already identified the relevant subgroup and measurement — Minitab doesn’t guide the user toward the right measurement to analyze.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"anova-and-factor-analysis\">ANOVA and Factor Analysis\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#anova-and-factor-analysis\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “ANOVA and Factor Analysis”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>General Linear Model, one-way ANOVA, two-way ANOVA, balanced/unbalanced designs, nested designs. Interaction plots are available as post-hoc visualization of fitted models. The user must specify the model terms manually — Minitab does not automatically surface which factors matter or rank them by contribution.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"regression\">Regression\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#regression\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Regression”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Simple, multiple, stepwise, best subsets, binary/ordinal/nominal logistic, Poisson. Comprehensive model diagnostics. Stepwise selection automates variable selection but requires the user to set up the analysis and interpret diagnostic plots.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"doe-design-of-experiments\">DOE (Design of Experiments)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#doe-design-of-experiments\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “DOE (Design of Experiments)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Full factorial, fractional factorial, response surface, mixture, Taguchi. Response Optimizer finds optimal factor settings from designed experiments. This is Minitab’s deepest differentiator — a capability set that VariScout does not and will not replicate, as it requires controlled experimental data rather than observational process data.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"multi-vari-charts\">Multi-Vari Charts\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#multi-vari-charts\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Multi-Vari Charts”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Purpose-built chart type for visualizing factor interactions. Shows measurement variation across multiple factors simultaneously. Accessed as a separate analysis (Quality Tools > Multi-Vari Chart), not integrated into an investigation workflow.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"minitab-assistant\">Minitab Assistant\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#minitab-assistant\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Minitab Assistant”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Guided analysis selection introduced in recent versions. Uses a decision-tree approach: the user answers questions about their data and objective, and the Assistant recommends the appropriate statistical test. This is hypothesis-driven guidance (confirming a suspected cause) rather than exploration guidance (finding which factor matters). The Assistant directs the user to the right menu item; it doesn’t guide them through an iterative investigation.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysis-and-investigation-workflow\">Analysis and Investigation Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-and-investigation-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis and Investigation Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Minitab’s workflow is fundamentally \u003Cstrong>menu-dialog-output\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>The analyst has a hypothesis or question (“Is Machine C different from Machine A?”)\u003C/li>\n\u003Cli>They navigate to the correct menu (Stat > ANOVA > One-Way)\u003C/li>\n\u003Cli>They configure the dialog (select response column, factor column, options)\u003C/li>\n\u003Cli>They read the output (session window text + graphs)\u003C/li>\n\u003Cli>They decide what to do next based on their own statistical knowledge\u003C/li>\n\u003C/ol>\n\u003Cp>Each analysis is a discrete, self-contained step. There is no linked filtering between outputs — running a one-way ANOVA on Machine does not automatically update the capability analysis or control chart. The analyst must manually re-run each analysis with new subsets. There is no concept of a “drill-down path” where one finding leads to the next through connected interactions.\u003C/p>\n\u003Cp>The Session Window accumulates text output chronologically. Finding results from earlier analyses requires scrolling. There is no navigation structure that connects related analyses into an investigation narrative.\u003C/p>\n\u003Cp>For variation investigation specifically, a Minitab user would:\u003C/p>\n\u003Col>\n\u003Cli>Run descriptive statistics to get an overview\u003C/li>\n\u003Cli>Run one-way ANOVA for each factor separately\u003C/li>\n\u003Cli>Examine eta-squared or SS values to rank factor importance (manually)\u003C/li>\n\u003Cli>Create subsets and re-run analyses for factor combinations (manually)\u003C/li>\n\u003Cli>Build a multi-vari chart to visualize interactions (separate analysis)\u003C/li>\n\u003Cli>Run capability analysis on the relevant subgroup (separate analysis)\u003C/li>\n\u003C/ol>\n\u003Cp>This requires 6+ separate analysis steps, each initiated from menus. VariScout’s progressive stratification accomplishes the same investigation through clicking boxplot bars, with all four charts updating simultaneously.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-minitab-addresses-our-6-tensions\">How Minitab Addresses Our 6 Tensions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-minitab-addresses-our-6-tensions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How Minitab Addresses Our 6 Tensions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tension\u003C/th>\u003Cth>Minitab’s Approach\u003C/th>\u003Cth>Assessment\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Hierarchy Assumption\u003C/strong>\u003C/td>\u003Ctd>Multi-vari charts can visualize interactions, but they’re a separate analysis that the user must know to run. Interaction terms must be specified manually in GLM.\u003C/td>\u003Ctd>Not addressed in the workflow; available as a separate tool for experts.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Discoverability\u003C/strong>\u003C/td>\u003Ctd>All 200+ analyses are listed in menus. The Assistant helps navigate. But the volume of options is itself a discoverability problem — finding the right analysis in nested menus is a known training challenge.\u003C/td>\u003Ctd>Partially addressed through Assistant; worsened by menu depth.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Factor Ordering\u003C/strong>\u003C/td>\u003Ctd>ANOVA output includes SS and p-values that implicitly rank factors by contribution. But the ranking is in a text table, not a visual navigation element. The analyst must read the table and manually decide what to investigate next.\u003C/td>\u003Ctd>Information available but not actionable — no integration with navigation.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>When to Stop\u003C/strong>\u003C/td>\u003Ctd>No stopping guidance. The analyst decides based on statistical significance thresholds and domain knowledge. Minitab reports results; it doesn’t suggest when the investigation is complete.\u003C/td>\u003Ctd>Not addressed.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mobile Screen Budget\u003C/strong>\u003C/td>\u003Ctd>Not applicable. Minitab is desktop software designed for large screens. No mobile or responsive interface.\u003C/td>\u003Ctd>Not applicable.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Path Dependency\u003C/strong>\u003C/td>\u003Ctd>Each analysis is independent. There is no drill-down path, so there is no path dependency. But this independence means the analyst must manually manage the investigation sequence, which is the problem path dependency addresses.\u003C/td>\u003Ctd>Avoided by not having a drill-down model, at the cost of manual investigation management.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-comparison\">Feature Comparison\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>Minitab\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Control charts (I-MR)\u003C/td>\u003Ctd>Yes, plus 20+ chart types\u003C/td>\u003Ctd>Yes (I-Chart)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability analysis (Cp/Cpk)\u003C/td>\u003Ctd>Full suite with distribution fitting\u003C/td>\u003Ctd>Normal-based with spec limit input\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Yes, as standalone analysis\u003C/td>\u003Ctd>Yes, integrated with filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto chart\u003C/td>\u003Ctd>Yes, as standalone analysis\u003C/td>\u003Ctd>Yes, integrated with filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ANOVA\u003C/td>\u003Ctd>GLM, one-way, multi-way, nested\u003C/td>\u003Ctd>One-way with eta-squared ranking\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regression\u003C/td>\u003Ctd>Full suite (simple through logistic)\u003C/td>\u003Ctd>Simple and multiple regression\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Gage R&R\u003C/td>\u003Ctd>Full MSA suite (crossed, nested, expanded)\u003C/td>\u003Ctd>Not available\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>DOE\u003C/td>\u003Ctd>Full factorial, response surface, mixture\u003C/td>\u003Ctd>Not available (different problem domain)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Linked filtering across charts\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Yes (core differentiator)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Progressive drill-down\u003C/td>\u003Ctd>No\u003C/td>\u003Ctd>Yes (core differentiator)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Variation contribution (eta-squared)\u003C/td>\u003Ctd>Available in ANOVA output (as SS%)\u003C/td>\u003Ctd>Visual, interactive, cumulative tracking\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Multi-measure performance analysis\u003C/td>\u003Ctd>No unified view\u003C/td>\u003Ctd>Performance Mode (Azure)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Offline/browser-based\u003C/td>\u003Ctd>No (desktop installation required)\u003C/td>\u003Ctd>Yes (PWA, offline-first)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Learning curve\u003C/td>\u003Ctd>Steep (training courses typically 3–5 days)\u003C/td>\u003Ctd>Minimal (guided by design)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Price for classroom use\u003C/td>\u003Ctd>$700/year academic per seat\u003C/td>\u003Ctd>Free (PWA)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-implications-for-variscout\">Strategic Implications for VariScout\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-implications-for-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Implications for VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"where-we-differentiate\">Where We Differentiate\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#where-we-differentiate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Where We Differentiate”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Exploration UX\u003C/strong>: VariScout’s linked filtering and progressive stratification provide a fundamentally different investigation experience. Minitab requires the analyst to manage the investigation manually through sequential menu selections.\u003C/li>\n\u003Cli>\u003Cstrong>Price and deployment\u003C/strong>: Free browser-based tool vs. $1,700/year desktop software. For training contexts, this is the primary decision factor.\u003C/li>\n\u003Cli>\u003Cstrong>Learning curve\u003C/strong>: Minitab’s depth creates a steep learning curve. Quality programs spend 3–5 days teaching the software. VariScout’s design goal is zero software training.\u003C/li>\n\u003Cli>\u003Cstrong>Methodology integration\u003C/strong>: VariScout embeds the investigation methodology (progressive stratification) into the interaction design. Minitab provides tools; the analyst supplies the methodology.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-we-can-learn\">What We Can Learn\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-we-can-learn\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What We Can Learn”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Multi-vari chart concept\u003C/strong>: Minitab’s multi-vari chart is a well-understood visualization for factor interactions. The interaction heatmap pattern draws on similar concepts but integrates them into the drill-down workflow.\u003C/li>\n\u003Cli>\u003Cstrong>Capability sixpack layout\u003C/strong>: Combining multiple capability views in a single output is effective for comprehensive assessment. VariScout’s Four Lenses approach extends this concept.\u003C/li>\n\u003Cli>\u003Cstrong>Assistant decision trees\u003C/strong>: The idea of guided analysis selection has value, though VariScout’s version (factor suggestion) operates within an EDA workflow rather than as a test-selection wizard.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-to-avoid-adopting\">What to Avoid Adopting\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-to-avoid-adopting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What to Avoid Adopting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Menu-driven architecture\u003C/strong>: Minitab’s menu depth is a known usability problem. VariScout should never evolve toward a menu-heavy interface.\u003C/li>\n\u003Cli>\u003Cstrong>Disconnected analyses\u003C/strong>: Each Minitab analysis being independent is the opposite of VariScout’s linked-filtering model. Adding features that break the connection between charts would undermine the core differentiator.\u003C/li>\n\u003Cli>\u003Cstrong>Feature accumulation\u003C/strong>: Minitab’s 200+ analysis types serve different audiences. VariScout should remain focused on the variation investigation workflow rather than becoming a general-purpose statistical package.\u003C/li>\n\u003C/ul>", + { + "headings": 13267, + "localImagePaths": 13300, + "remoteImagePaths": 13301, + "frontmatter": 13302, + "imagePaths": 13303 + }, + [ + 13268, 13270, 13271, 13272, 13275, 13276, 13279, 13282, 13285, 13288, 13291, 13292, 13295, + 13296, 13297, 13298, 13299 + ], + { "depth": 30, "slug": 13269, "text": 13257 }, + "minitab-competitive-benchmark", + { "depth": 33, "slug": 13080, "text": 13081 }, + { "depth": 33, "slug": 13210, "text": 13211 }, + { "depth": 79, "slug": 13273, "text": 13274 }, + "spc-and-control-charts", + "SPC and Control Charts", + { "depth": 79, "slug": 983, "text": 984 }, + { "depth": 79, "slug": 13277, "text": 13278 }, + "anova-and-factor-analysis", + "ANOVA and Factor Analysis", + { "depth": 79, "slug": 13280, "text": 13281 }, + "regression", + "Regression", + { "depth": 79, "slug": 13283, "text": 13284 }, + "doe-design-of-experiments", + "DOE (Design of Experiments)", + { "depth": 79, "slug": 13286, "text": 13287 }, + "multi-vari-charts", + "Multi-Vari Charts", + { "depth": 79, "slug": 13289, "text": 13290 }, + "minitab-assistant", + "Minitab Assistant", + { "depth": 33, "slug": 13234, "text": 13235 }, + { "depth": 33, "slug": 13293, "text": 13294 }, + "how-minitab-addresses-our-6-tensions", + "How Minitab Addresses Our 6 Tensions", + { "depth": 33, "slug": 2115, "text": 2116 }, + { "depth": 33, "slug": 13177, "text": 13178 }, + { "depth": 79, "slug": 13242, "text": 13243 }, + { "depth": 79, "slug": 13245, "text": 13246 }, + { "depth": 79, "slug": 13248, "text": 13249 }, + [], + [], + { "title": 13257 }, + [], + "01-vision/evaluations/competitive/minor-competitors", + { + "id": 13304, + "data": 13306, + "body": 13311, + "filePath": 13312, + "digest": 13313, + "rendered": 13314 + }, + { + "title": 13307, + "editUrl": 16, + "head": 13308, + "template": 18, + "sidebar": 13309, + "pagefind": 16, + "draft": 20 + }, + "Minor Competitor Profiles", + [], + { "hidden": 20, "attrs": 13310 }, + {}, + "# Minor Competitor Profiles\n\n> Based on public documentation and published feature sets. These competitors appear in only 1–2 pattern evaluations and do not warrant full benchmark documents.\n\nFor full benchmarks of major competitors, see:\n\n- [Minitab Benchmark](minitab-benchmark.md) (6 pattern mentions)\n- [JMP Benchmark](jmp-benchmark.md) (6 pattern mentions)\n- [Tableau Benchmark](tableau-benchmark.md) (6 pattern mentions)\n- [Power BI Benchmark](powerbi-benchmark.md) (5 pattern mentions)\n- [EDAScout Benchmark](edascout-benchmark.md) (7 pattern mentions, codebase-analyzed)\n\n---\n\n## SigmaXL\n\n| Dimension | SigmaXL |\n| ------------------- | --------------------------------------------- |\n| **Platform** | Excel add-in (Windows, macOS via Parallels) |\n| **Pricing** | $299/year (single user) |\n| **Distribution** | Direct download |\n| **Target audience** | Lean Six Sigma practitioners using Excel |\n| **Market position** | Budget alternative to Minitab for Excel users |\n\n### Relevant Capabilities\n\nSigmaXL operates entirely within Excel, adding statistical analysis capabilities through a ribbon menu. The relevant features for VariScout's pattern evaluations:\n\n- **Multiple regression with stepwise selection**: Automated variable selection using forward, backward, or stepwise algorithms. The analyst selects response and candidate predictor columns; SigmaXL identifies the statistically significant subset. This requires understanding of regression assumptions and model diagnostics — it is a statistical tool for trained analysts, not a guided exploration feature.\n- **Control charts**: Standard SPC chart types (I-MR, Xbar-R, P, C) rendered within Excel worksheets. Charts are static — they don't update when slicers change, and there is no linked filtering.\n- **Capability analysis**: Cp, Cpk, Pp, Ppk with basic distribution fitting. Output is an Excel-formatted report.\n- **ANOVA**: One-way and multi-way ANOVA with post-hoc tests. Output includes SS, MS, F, and p-values in tabular form.\n\n### Pattern Relevance\n\nSigmaXL appears in the [Auto-Combination Finder](../patterns/auto-combination-finder.md) evaluation only. Its stepwise regression provides automated factor selection but requires the analyst to configure the analysis, interpret model diagnostics, and make decisions about variable inclusion/exclusion. The approach is expert-driven model building, not automated investigation.\n\n### Strategic Assessment\n\nSigmaXL competes in the \"statistical analysis within Excel\" space. VariScout's Excel Add-in operates in the same environment but with a fundamentally different approach — VariScout provides visual, interactive SPC analysis while SigmaXL provides traditional statistical output in worksheet format. The overlap is minimal because the workflows are different: SigmaXL serves analysts who want Minitab-style statistics at a lower price; VariScout serves practitioners who want investigation-guided analysis without statistical expertise.\n\n---\n\n## Looker\n\n| Dimension | Looker |\n| ------------------- | ---------------------------------------------------------- |\n| **Platform** | Cloud-based (Google Cloud) |\n| **Pricing** | Custom enterprise pricing |\n| **Distribution** | Google Cloud Marketplace, direct sales |\n| **Target audience** | Data teams, enterprise analytics |\n| **Market position** | Google's enterprise BI platform (embedded analytics focus) |\n\n### Relevant Capabilities\n\nLooker is Google's BI platform, focused on embedded analytics and governed data access through its LookML modeling language. The relevant feature for VariScout's pattern evaluations:\n\n- **Filter bar pattern**: Looker dashboards use a filter bar at the top of the page with dropdowns for each filterable dimension. Filters are defined in LookML (the modeling language) and exposed to dashboard consumers. The interaction model is consistent with Tableau and Power BI — the analyst selects filter values from controls, and visuals update accordingly.\n- **Cross-filtering**: Clicking a data element in one tile can filter other tiles on the dashboard. Similar in behavior to Tableau and Power BI cross-filtering.\n- **Embedded analytics**: Looker's primary differentiator is embeddability — Looker dashboards are designed to be embedded in other applications. This is not relevant to VariScout's analysis workflow.\n\n### Pattern Relevance\n\nLooker appears in the [Sidebar Filter Panel](../patterns/sidebar-filter-panel.md) evaluation only. Its filter bar is the same paradigm as Tableau's sidebar filters and Power BI's slicers — always-visible filter controls that the analyst configures. The LookML-driven approach means filters are defined by data engineers rather than end users, which adds a governance layer but doesn't change the fundamental interaction pattern.\n\n### Strategic Assessment\n\nLooker competes in the enterprise BI space alongside Tableau and Power BI. For VariScout's competitive positioning, Looker represents a third data point confirming that the sidebar filter paradigm is the BI industry standard. VariScout's chart-integrated filtering is a deliberate departure from this standard, differentiated by being investigation-driven rather than configuration-driven. Looker has no SPC capabilities, no statistical analysis beyond basic aggregations, and no quality-specific workflow — the competitive overlap is limited to the general concept of filtered data visualization.", + "src/content/docs/01-vision/evaluations/competitive/minor-competitors.md", + "7ec6aa4033dba1cc", + { "html": 13315, "metadata": 13316 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"minor-competitor-profiles\">Minor Competitor Profiles\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#minor-competitor-profiles\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Minor Competitor Profiles”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Based on public documentation and published feature sets. These competitors appear in only 1–2 pattern evaluations and do not warrant full benchmark documents.\u003C/p>\n\u003C/blockquote>\n\u003Cp>For full benchmarks of major competitors, see:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"minitab-benchmark.md\">Minitab Benchmark\u003C/a> (6 pattern mentions)\u003C/li>\n\u003Cli>\u003Ca href=\"jmp-benchmark.md\">JMP Benchmark\u003C/a> (6 pattern mentions)\u003C/li>\n\u003Cli>\u003Ca href=\"tableau-benchmark.md\">Tableau Benchmark\u003C/a> (6 pattern mentions)\u003C/li>\n\u003Cli>\u003Ca href=\"powerbi-benchmark.md\">Power BI Benchmark\u003C/a> (5 pattern mentions)\u003C/li>\n\u003Cli>\u003Ca href=\"edascout-benchmark.md\">EDAScout Benchmark\u003C/a> (7 pattern mentions, codebase-analyzed)\u003C/li>\n\u003C/ul>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"sigmaxl\">SigmaXL\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#sigmaxl\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “SigmaXL”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>SigmaXL\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Platform\u003C/strong>\u003C/td>\u003Ctd>Excel add-in (Windows, macOS via Parallels)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pricing\u003C/strong>\u003C/td>\u003Ctd>$299/year (single user)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Distribution\u003C/strong>\u003C/td>\u003Ctd>Direct download\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Target audience\u003C/strong>\u003C/td>\u003Ctd>Lean Six Sigma practitioners using Excel\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Market position\u003C/strong>\u003C/td>\u003Ctd>Budget alternative to Minitab for Excel users\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"relevant-capabilities\">Relevant Capabilities\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#relevant-capabilities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Relevant Capabilities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>SigmaXL operates entirely within Excel, adding statistical analysis capabilities through a ribbon menu. The relevant features for VariScout’s pattern evaluations:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Multiple regression with stepwise selection\u003C/strong>: Automated variable selection using forward, backward, or stepwise algorithms. The analyst selects response and candidate predictor columns; SigmaXL identifies the statistically significant subset. This requires understanding of regression assumptions and model diagnostics — it is a statistical tool for trained analysts, not a guided exploration feature.\u003C/li>\n\u003Cli>\u003Cstrong>Control charts\u003C/strong>: Standard SPC chart types (I-MR, Xbar-R, P, C) rendered within Excel worksheets. Charts are static — they don’t update when slicers change, and there is no linked filtering.\u003C/li>\n\u003Cli>\u003Cstrong>Capability analysis\u003C/strong>: Cp, Cpk, Pp, Ppk with basic distribution fitting. Output is an Excel-formatted report.\u003C/li>\n\u003Cli>\u003Cstrong>ANOVA\u003C/strong>: One-way and multi-way ANOVA with post-hoc tests. Output includes SS, MS, F, and p-values in tabular form.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pattern-relevance\">Pattern Relevance\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pattern-relevance\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pattern Relevance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>SigmaXL appears in the \u003Ca href=\"../patterns/auto-combination-finder.md\">Auto-Combination Finder\u003C/a> evaluation only. Its stepwise regression provides automated factor selection but requires the analyst to configure the analysis, interpret model diagnostics, and make decisions about variable inclusion/exclusion. The approach is expert-driven model building, not automated investigation.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"strategic-assessment\">Strategic Assessment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-assessment\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Assessment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>SigmaXL competes in the “statistical analysis within Excel” space. VariScout’s Excel Add-in operates in the same environment but with a fundamentally different approach — VariScout provides visual, interactive SPC analysis while SigmaXL provides traditional statistical output in worksheet format. The overlap is minimal because the workflows are different: SigmaXL serves analysts who want Minitab-style statistics at a lower price; VariScout serves practitioners who want investigation-guided analysis without statistical expertise.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"looker\">Looker\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#looker\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Looker”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>Looker\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Platform\u003C/strong>\u003C/td>\u003Ctd>Cloud-based (Google Cloud)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pricing\u003C/strong>\u003C/td>\u003Ctd>Custom enterprise pricing\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Distribution\u003C/strong>\u003C/td>\u003Ctd>Google Cloud Marketplace, direct sales\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Target audience\u003C/strong>\u003C/td>\u003Ctd>Data teams, enterprise analytics\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Market position\u003C/strong>\u003C/td>\u003Ctd>Google’s enterprise BI platform (embedded analytics focus)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"relevant-capabilities-1\">Relevant Capabilities\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#relevant-capabilities-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Relevant Capabilities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Looker is Google’s BI platform, focused on embedded analytics and governed data access through its LookML modeling language. The relevant feature for VariScout’s pattern evaluations:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Filter bar pattern\u003C/strong>: Looker dashboards use a filter bar at the top of the page with dropdowns for each filterable dimension. Filters are defined in LookML (the modeling language) and exposed to dashboard consumers. The interaction model is consistent with Tableau and Power BI — the analyst selects filter values from controls, and visuals update accordingly.\u003C/li>\n\u003Cli>\u003Cstrong>Cross-filtering\u003C/strong>: Clicking a data element in one tile can filter other tiles on the dashboard. Similar in behavior to Tableau and Power BI cross-filtering.\u003C/li>\n\u003Cli>\u003Cstrong>Embedded analytics\u003C/strong>: Looker’s primary differentiator is embeddability — Looker dashboards are designed to be embedded in other applications. This is not relevant to VariScout’s analysis workflow.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"pattern-relevance-1\">Pattern Relevance\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#pattern-relevance-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Pattern Relevance”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Looker appears in the \u003Ca href=\"../patterns/sidebar-filter-panel.md\">Sidebar Filter Panel\u003C/a> evaluation only. Its filter bar is the same paradigm as Tableau’s sidebar filters and Power BI’s slicers — always-visible filter controls that the analyst configures. The LookML-driven approach means filters are defined by data engineers rather than end users, which adds a governance layer but doesn’t change the fundamental interaction pattern.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"strategic-assessment-1\">Strategic Assessment\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-assessment-1\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Assessment”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Looker competes in the enterprise BI space alongside Tableau and Power BI. For VariScout’s competitive positioning, Looker represents a third data point confirming that the sidebar filter paradigm is the BI industry standard. VariScout’s chart-integrated filtering is a deliberate departure from this standard, differentiated by being investigation-driven rather than configuration-driven. Looker has no SPC capabilities, no statistical analysis beyond basic aggregations, and no quality-specific workflow — the competitive overlap is limited to the general concept of filtered data visualization.\u003C/p>", + { + "headings": 13317, + "localImagePaths": 13341, + "remoteImagePaths": 13342, + "frontmatter": 13343, + "imagePaths": 13344 + }, + [13318, 13320, 13323, 13326, 13329, 13332, 13335, 13337, 13339], + { "depth": 30, "slug": 13319, "text": 13307 }, + "minor-competitor-profiles", + { "depth": 33, "slug": 13321, "text": 13322 }, + "sigmaxl", + "SigmaXL", + { "depth": 79, "slug": 13324, "text": 13325 }, + "relevant-capabilities", + "Relevant Capabilities", + { "depth": 79, "slug": 13327, "text": 13328 }, + "pattern-relevance", + "Pattern Relevance", + { "depth": 79, "slug": 13330, "text": 13331 }, + "strategic-assessment", + "Strategic Assessment", + { "depth": 33, "slug": 13333, "text": 13334 }, + "looker", + "Looker", + { "depth": 79, "slug": 13336, "text": 13325 }, + "relevant-capabilities-1", + { "depth": 79, "slug": 13338, "text": 13328 }, + "pattern-relevance-1", + { "depth": 79, "slug": 13340, "text": 13331 }, + "strategic-assessment-1", + [], + [], + { "title": 13307 }, + [], + "01-vision/evaluations/competitive/powerbi-benchmark", + { + "id": 13345, + "data": 13347, + "body": 13352, + "filePath": 13353, + "digest": 13354, + "rendered": 13355 + }, + { + "title": 13348, + "editUrl": 16, + "head": 13349, + "template": 18, + "sidebar": 13350, + "pagefind": 16, + "draft": 20 + }, + "Power BI Competitive Benchmark", + [], + { "hidden": 20, "attrs": 13351 }, + {}, + "# Power BI Competitive Benchmark\n\n> Based on public documentation, published feature sets, and market positioning knowledge. Unlike the [EDAScout Benchmark](edascout-benchmark.md), this assessment does not include direct codebase analysis.\n\n---\n\n## Product Profile\n\n| Dimension | Power BI | VariScout |\n| ------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------- |\n| **Platform** | Desktop (authoring) + Service (cloud) + Mobile | Browser-based (PWA, Azure, Excel Add-in) |\n| **Pricing** | $10/user/month (Pro), $20/user/month (Premium per user), Free (Desktop) | From €99/month (Azure) or free (PWA) |\n| **Distribution** | Microsoft 365 ecosystem, Azure integration | Azure Marketplace, AppSource, public URL |\n| **Target audience** | Business analysts, report builders, enterprise IT | Quality practitioners, Green Belts, learners |\n| **Market position** | Microsoft's enterprise BI platform | Specialized variation analysis tool |\n| **Analysis model** | Report-centric: build visuals, assemble pages, publish reports | Four Lenses: 4 coordinated charts with linked filtering |\n| **Navigation** | Slicers, cross-filtering between visuals | Progressive stratification drill-down |\n| **Parent company** | Microsoft | Independent |\n\n---\n\n## Core Capabilities\n\nPower BI is Microsoft's BI platform, deeply integrated into the Microsoft 365 and Azure ecosystems. Its relevance to VariScout is as the enterprise BI tool that quality teams most commonly have access to, and as the platform whose slicer paradigm parallels Tableau's sidebar filters.\n\n### Slicers\n\nPower BI's primary filtering mechanism. Slicers are visual controls placed on report pages — dropdown lists, checkboxes, date ranges, numeric ranges, and relative date slicers. Sync slicers propagate filter state across multiple pages. The interaction model is identical in concept to Tableau's sidebar filters: the analyst configures the view by selecting values in slicer controls.\n\nSlicers can be configured as single-select or multi-select, and can be set to apply across all visuals or specific visuals. The slicer pane (responsive slicer) collapses into a panel that expands on click, addressing some of the screen real estate concern on smaller displays.\n\n### Cross-Filtering\n\nClicking a data point in one visual filters all other visuals on the page (configurable as cross-filter or cross-highlight). This is the same concept as Tableau's cross-filtering. The analyst sees how one selection affects other dimensions. However, cross-filtering is a dashboard interaction feature, not an investigation methodology — it shows correlated changes but doesn't quantify variation contribution.\n\n### Small Multiples\n\nAdded to Power BI in 2021 as a standard visual option. The analyst drags a dimension to the \"Small multiples\" field well, and the selected chart type replicates across dimension values in a grid layout. Grid size adjusts automatically. This implementation is functional but less flexible than Tableau's rows/columns shelf approach — the grid layout options are more constrained.\n\n### DAX Calculations\n\nDAX (Data Analysis Expressions) is Power BI's formula language. It supports aggregation, filtering, time intelligence, and iterative calculations. Statistically, DAX can calculate means, medians, standard deviations, percentiles, and custom aggregations. However, there is no built-in ANOVA, regression, or capability analysis. Implementing Cpk or eta-squared in DAX is technically possible but requires significant expertise and produces fragile, hard-to-maintain measures.\n\n### Custom Visuals (AppSource)\n\nPower BI's marketplace includes third-party custom visuals. Basic control chart visuals exist (from providers like Nova Silva and others), offering I-MR, Xbar-R, and P charts. These are functional but limited — they typically lack Nelson rules, run tests, and linked filtering with other visuals. The quality and maintenance of third-party visuals varies.\n\n### Excel Integration\n\nPower BI integrates deeply with Excel. Data from Excel workbooks can be imported directly. Power BI reports can be embedded in Excel. This creates a potential overlap with VariScout's Excel Add-in — a quality team using Power BI might embed basic control charts in Excel reports without a separate tool. However, the SPC capabilities of Power BI (even with custom visuals) are superficial compared to a dedicated SPC tool.\n\n### AI Features\n\nPower BI includes Q&A (natural language queries), Key Influencers visual (automated factor analysis using ML), and Anomaly Detection. The Key Influencers visual is relevant: it identifies factors that influence a metric, somewhat similar to VariScout's eta-squared ranking. However, it uses ML classification/regression rather than ANOVA, doesn't integrate into an investigation workflow, and presents results as a static report rather than an interactive drill-down path.\n\n---\n\n## Analysis and Investigation Workflow\n\nPower BI's workflow is **build-then-publish**:\n\n1. The analyst (Pro/Premium user) connects to data in Power BI Desktop\n2. They build data models with DAX measures\n3. They create report pages with visuals and slicers\n4. They publish reports to the Power BI Service\n5. Consumers interact through slicers and cross-filtering\n\nFor variation investigation, a Power BI user would:\n\n1. Import measurement data (from Excel, SQL, or other sources)\n2. Build DAX measures for mean, standard deviation, and possibly control limits\n3. Create bar charts or boxplots showing measurements by factor\n4. Add slicers for each factor dimension\n5. Optionally add a custom control chart visual from AppSource\n6. Use slicers and cross-filtering to explore factor effects\n\nThe fundamental limitation: Power BI is a reporting tool, not an analysis tool. The investigation logic must be built by the report author through DAX measures and visual configuration. There is no guided investigation workflow. The consumer of the report applies filters and reads visual changes but has no statistical framework for interpreting what they see.\n\n---\n\n## How Power BI Addresses Our 6 Tensions\n\n| Tension | Power BI's Approach | Assessment |\n| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |\n| **Hierarchy Assumption** | Key Influencers visual performs automated factor analysis, but does not detect interactions between factors. DAX can calculate interaction terms but requires expert authoring. | Partially addressed through Key Influencers (main effects only); interactions not addressed. |\n| **Discoverability** | Slicers make filter options visible. Sync slicers maintain filter state across pages. The responsive slicer pane provides a collapsible filter panel. Similar to Tableau's approach — all options visible but no guidance on which to select. | Addressed for filter discoverability; not addressed for analytical discoverability. |\n| **Factor Ordering** | Key Influencers visual ranks factors by influence (using ML). However, the ranking is in a separate visual, not integrated with the investigation workflow. Standard slicers present all factors equally with no ordering. | Partially addressed through Key Influencers; not integrated into navigation. |\n| **When to Stop** | No stopping guidance. Reports are open-ended. | Not addressed. |\n| **Mobile Screen Budget** | Power BI Mobile app with phone-optimized layouts. Report authors can create phone-specific layouts with rearranged visuals. Slicers adapt to mobile but still consume screen space. | Better addressed than Tableau through phone-specific layouts; slicer space remains a challenge. |\n| **Path Dependency** | No drill-down path. Slicer selections are commutative — order doesn't matter. | Not applicable — no sequential drill-down model. |\n\n---\n\n## Feature Comparison\n\n| Capability | Power BI | VariScout |\n| ---------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------ |\n| Visual analytics (general) | Broad, enterprise-focused | Focused on SPC/quality domain |\n| Control charts (I-MR) | Third-party custom visuals only | Yes (I-Chart, native) |\n| Capability analysis (Cp/Cpk) | Custom DAX only (complex, fragile) | Yes, integrated |\n| Boxplot | Available as chart type | Integrated with drill-down filtering |\n| Pareto chart | Available (sorted bar chart) | Integrated with drill-down filtering |\n| ANOVA | Not available | Yes, with eta-squared ranking |\n| Regression | Trend lines; R/Python scripts for full regression | Simple and multiple regression |\n| Gage R&R | Not available | Not available |\n| Small multiples | Yes (added 2021, grid layout) | Planned feature |\n| Slicers / filter panel | Core paradigm | Rejected pattern (see [evaluation](../patterns/sidebar-filter-panel.md)) |\n| Cross-filtering | Yes (visual-level interaction) | Yes (linked filtering, investigation-driven) |\n| Factor ranking (automated) | Key Influencers visual (ML-based) | Eta-squared ranking (statistical, transparent) |\n| Statistical calculations | Basic aggregations + DAX (expert-authored) | SPC-specific (Cpk, ANOVA, eta-squared) |\n| Nelson rules / run tests | Not available | Yes |\n| Excel integration | Deep (bidirectional) | Excel Add-in (native Office.js) |\n| Natural language queries | Q&A feature | Not applicable |\n| Price for individual analyst | Free (Desktop), $10/month (Pro sharing) | Free (PWA) or from €99/month (Azure) |\n| Microsoft ecosystem | Deep integration (365, Teams, SharePoint) | Azure Marketplace only |\n\n---\n\n## Strategic Implications for VariScout\n\n### Where We Differentiate\n\n- **SPC-native analysis**: Power BI has no native SPC capability. Custom visuals and DAX workarounds cannot replicate proper control chart logic, capability analysis, or ANOVA. VariScout is purpose-built for the statistical analysis that Power BI cannot perform.\n- **Zero-configuration statistics**: Power BI requires a DAX expert to build statistical measures. VariScout calculates Cpk, eta-squared, and ANOVA automatically from the data.\n- **Investigation workflow**: Power BI reports are static configurations that consumers interact with through slicers. VariScout's progressive stratification is an investigation methodology where each interaction drives the next analytical step.\n- **Quality professional focus**: Power BI serves general business analytics. VariScout is designed specifically for quality practitioners — the terminology, workflow, and output match how quality professionals think about variation.\n\n### What We Can Learn\n\n- **Key Influencers visual**: Power BI's automated factor ranking visual demonstrates that even BI tools recognize the need to surface which factors matter. VariScout's eta-squared ranking is a better implementation for quality data (transparent statistics vs. ML black box), but the concept of visual factor ranking is validated by Power BI's inclusion of this feature.\n- **Phone-specific layouts**: Power BI's approach to creating separate mobile layouts for the same report is a practical solution to the mobile screen budget tension. VariScout could adopt a similar approach for the PWA's mobile experience.\n- **Responsive slicer pane**: The collapsible slicer pane demonstrates that even BI tools recognize sidebar filters consume too much screen space. This validates VariScout's rejection of the sidebar pattern.\n\n### What to Avoid Adopting\n\n- **Slicer paradigm**: The same reasoning as for Tableau applies. Slicers are configuration controls, not investigation actions. VariScout's chart-integrated filtering is a deliberate differentiation.\n- **DAX complexity**: Power BI's reliance on DAX for anything beyond basic aggregations creates a barrier for quality professionals. VariScout should never require formula authoring for standard quality analyses.\n- **Microsoft ecosystem lock-in**: While VariScout's Azure app runs in Azure and the Excel Add-in runs in Office, the analytical capability should remain platform-independent. The PWA works anywhere — this flexibility is a differentiator against Power BI's Microsoft-centric deployment.", + "src/content/docs/01-vision/evaluations/competitive/powerbi-benchmark.md", + "e320a8f1f3b78666", + { "html": 13356, "metadata": 13357 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"power-bi-competitive-benchmark\">Power BI Competitive Benchmark\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#power-bi-competitive-benchmark\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Power BI Competitive Benchmark”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Based on public documentation, published feature sets, and market positioning knowledge. Unlike the \u003Ca href=\"edascout-benchmark.md\">EDAScout Benchmark\u003C/a>, this assessment does not include direct codebase analysis.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"product-profile\">Product Profile\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#product-profile\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Profile”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>Power BI\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Platform\u003C/strong>\u003C/td>\u003Ctd>Desktop (authoring) + Service (cloud) + Mobile\u003C/td>\u003Ctd>Browser-based (PWA, Azure, Excel Add-in)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pricing\u003C/strong>\u003C/td>\u003Ctd>$10/user/month (Pro), $20/user/month (Premium per user), Free (Desktop)\u003C/td>\u003Ctd>From €99/month (Azure) or free (PWA)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Distribution\u003C/strong>\u003C/td>\u003Ctd>Microsoft 365 ecosystem, Azure integration\u003C/td>\u003Ctd>Azure Marketplace, AppSource, public URL\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Target audience\u003C/strong>\u003C/td>\u003Ctd>Business analysts, report builders, enterprise IT\u003C/td>\u003Ctd>Quality practitioners, Green Belts, learners\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Market position\u003C/strong>\u003C/td>\u003Ctd>Microsoft’s enterprise BI platform\u003C/td>\u003Ctd>Specialized variation analysis tool\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Analysis model\u003C/strong>\u003C/td>\u003Ctd>Report-centric: build visuals, assemble pages, publish reports\u003C/td>\u003Ctd>Four Lenses: 4 coordinated charts with linked filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Navigation\u003C/strong>\u003C/td>\u003Ctd>Slicers, cross-filtering between visuals\u003C/td>\u003Ctd>Progressive stratification drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Parent company\u003C/strong>\u003C/td>\u003Ctd>Microsoft\u003C/td>\u003Ctd>Independent\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-capabilities\">Core Capabilities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-capabilities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Capabilities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Power BI is Microsoft’s BI platform, deeply integrated into the Microsoft 365 and Azure ecosystems. Its relevance to VariScout is as the enterprise BI tool that quality teams most commonly have access to, and as the platform whose slicer paradigm parallels Tableau’s sidebar filters.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"slicers\">Slicers\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#slicers\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Slicers”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Power BI’s primary filtering mechanism. Slicers are visual controls placed on report pages — dropdown lists, checkboxes, date ranges, numeric ranges, and relative date slicers. Sync slicers propagate filter state across multiple pages. The interaction model is identical in concept to Tableau’s sidebar filters: the analyst configures the view by selecting values in slicer controls.\u003C/p>\n\u003Cp>Slicers can be configured as single-select or multi-select, and can be set to apply across all visuals or specific visuals. The slicer pane (responsive slicer) collapses into a panel that expands on click, addressing some of the screen real estate concern on smaller displays.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"cross-filtering\">Cross-Filtering\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#cross-filtering\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Cross-Filtering”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Clicking a data point in one visual filters all other visuals on the page (configurable as cross-filter or cross-highlight). This is the same concept as Tableau’s cross-filtering. The analyst sees how one selection affects other dimensions. However, cross-filtering is a dashboard interaction feature, not an investigation methodology — it shows correlated changes but doesn’t quantify variation contribution.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"small-multiples\">Small Multiples\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#small-multiples\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Small Multiples”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Added to Power BI in 2021 as a standard visual option. The analyst drags a dimension to the “Small multiples” field well, and the selected chart type replicates across dimension values in a grid layout. Grid size adjusts automatically. This implementation is functional but less flexible than Tableau’s rows/columns shelf approach — the grid layout options are more constrained.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"dax-calculations\">DAX Calculations\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#dax-calculations\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “DAX Calculations”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>DAX (Data Analysis Expressions) is Power BI’s formula language. It supports aggregation, filtering, time intelligence, and iterative calculations. Statistically, DAX can calculate means, medians, standard deviations, percentiles, and custom aggregations. However, there is no built-in ANOVA, regression, or capability analysis. Implementing Cpk or eta-squared in DAX is technically possible but requires significant expertise and produces fragile, hard-to-maintain measures.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"custom-visuals-appsource\">Custom Visuals (AppSource)\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#custom-visuals-appsource\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Custom Visuals (AppSource)”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Power BI’s marketplace includes third-party custom visuals. Basic control chart visuals exist (from providers like Nova Silva and others), offering I-MR, Xbar-R, and P charts. These are functional but limited — they typically lack Nelson rules, run tests, and linked filtering with other visuals. The quality and maintenance of third-party visuals varies.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"excel-integration\">Excel Integration\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#excel-integration\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Excel Integration”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Power BI integrates deeply with Excel. Data from Excel workbooks can be imported directly. Power BI reports can be embedded in Excel. This creates a potential overlap with VariScout’s Excel Add-in — a quality team using Power BI might embed basic control charts in Excel reports without a separate tool. However, the SPC capabilities of Power BI (even with custom visuals) are superficial compared to a dedicated SPC tool.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"ai-features\">AI Features\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#ai-features\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “AI Features”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Power BI includes Q&A (natural language queries), Key Influencers visual (automated factor analysis using ML), and Anomaly Detection. The Key Influencers visual is relevant: it identifies factors that influence a metric, somewhat similar to VariScout’s eta-squared ranking. However, it uses ML classification/regression rather than ANOVA, doesn’t integrate into an investigation workflow, and presents results as a static report rather than an interactive drill-down path.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysis-and-investigation-workflow\">Analysis and Investigation Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-and-investigation-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis and Investigation Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Power BI’s workflow is \u003Cstrong>build-then-publish\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>The analyst (Pro/Premium user) connects to data in Power BI Desktop\u003C/li>\n\u003Cli>They build data models with DAX measures\u003C/li>\n\u003Cli>They create report pages with visuals and slicers\u003C/li>\n\u003Cli>They publish reports to the Power BI Service\u003C/li>\n\u003Cli>Consumers interact through slicers and cross-filtering\u003C/li>\n\u003C/ol>\n\u003Cp>For variation investigation, a Power BI user would:\u003C/p>\n\u003Col>\n\u003Cli>Import measurement data (from Excel, SQL, or other sources)\u003C/li>\n\u003Cli>Build DAX measures for mean, standard deviation, and possibly control limits\u003C/li>\n\u003Cli>Create bar charts or boxplots showing measurements by factor\u003C/li>\n\u003Cli>Add slicers for each factor dimension\u003C/li>\n\u003Cli>Optionally add a custom control chart visual from AppSource\u003C/li>\n\u003Cli>Use slicers and cross-filtering to explore factor effects\u003C/li>\n\u003C/ol>\n\u003Cp>The fundamental limitation: Power BI is a reporting tool, not an analysis tool. The investigation logic must be built by the report author through DAX measures and visual configuration. There is no guided investigation workflow. The consumer of the report applies filters and reads visual changes but has no statistical framework for interpreting what they see.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-power-bi-addresses-our-6-tensions\">How Power BI Addresses Our 6 Tensions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-power-bi-addresses-our-6-tensions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How Power BI Addresses Our 6 Tensions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tension\u003C/th>\u003Cth>Power BI’s Approach\u003C/th>\u003Cth>Assessment\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Hierarchy Assumption\u003C/strong>\u003C/td>\u003Ctd>Key Influencers visual performs automated factor analysis, but does not detect interactions between factors. DAX can calculate interaction terms but requires expert authoring.\u003C/td>\u003Ctd>Partially addressed through Key Influencers (main effects only); interactions not addressed.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Discoverability\u003C/strong>\u003C/td>\u003Ctd>Slicers make filter options visible. Sync slicers maintain filter state across pages. The responsive slicer pane provides a collapsible filter panel. Similar to Tableau’s approach — all options visible but no guidance on which to select.\u003C/td>\u003Ctd>Addressed for filter discoverability; not addressed for analytical discoverability.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Factor Ordering\u003C/strong>\u003C/td>\u003Ctd>Key Influencers visual ranks factors by influence (using ML). However, the ranking is in a separate visual, not integrated with the investigation workflow. Standard slicers present all factors equally with no ordering.\u003C/td>\u003Ctd>Partially addressed through Key Influencers; not integrated into navigation.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>When to Stop\u003C/strong>\u003C/td>\u003Ctd>No stopping guidance. Reports are open-ended.\u003C/td>\u003Ctd>Not addressed.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mobile Screen Budget\u003C/strong>\u003C/td>\u003Ctd>Power BI Mobile app with phone-optimized layouts. Report authors can create phone-specific layouts with rearranged visuals. Slicers adapt to mobile but still consume screen space.\u003C/td>\u003Ctd>Better addressed than Tableau through phone-specific layouts; slicer space remains a challenge.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Path Dependency\u003C/strong>\u003C/td>\u003Ctd>No drill-down path. Slicer selections are commutative — order doesn’t matter.\u003C/td>\u003Ctd>Not applicable — no sequential drill-down model.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-comparison\">Feature Comparison\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>Power BI\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Visual analytics (general)\u003C/td>\u003Ctd>Broad, enterprise-focused\u003C/td>\u003Ctd>Focused on SPC/quality domain\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Control charts (I-MR)\u003C/td>\u003Ctd>Third-party custom visuals only\u003C/td>\u003Ctd>Yes (I-Chart, native)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability analysis (Cp/Cpk)\u003C/td>\u003Ctd>Custom DAX only (complex, fragile)\u003C/td>\u003Ctd>Yes, integrated\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Available as chart type\u003C/td>\u003Ctd>Integrated with drill-down filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto chart\u003C/td>\u003Ctd>Available (sorted bar chart)\u003C/td>\u003Ctd>Integrated with drill-down filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ANOVA\u003C/td>\u003Ctd>Not available\u003C/td>\u003Ctd>Yes, with eta-squared ranking\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regression\u003C/td>\u003Ctd>Trend lines; R/Python scripts for full regression\u003C/td>\u003Ctd>Simple and multiple regression\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Gage R&R\u003C/td>\u003Ctd>Not available\u003C/td>\u003Ctd>Not available\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Small multiples\u003C/td>\u003Ctd>Yes (added 2021, grid layout)\u003C/td>\u003Ctd>Planned feature\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Slicers / filter panel\u003C/td>\u003Ctd>Core paradigm\u003C/td>\u003Ctd>Rejected pattern (see \u003Ca href=\"../patterns/sidebar-filter-panel.md\">evaluation\u003C/a>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cross-filtering\u003C/td>\u003Ctd>Yes (visual-level interaction)\u003C/td>\u003Ctd>Yes (linked filtering, investigation-driven)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Factor ranking (automated)\u003C/td>\u003Ctd>Key Influencers visual (ML-based)\u003C/td>\u003Ctd>Eta-squared ranking (statistical, transparent)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Statistical calculations\u003C/td>\u003Ctd>Basic aggregations + DAX (expert-authored)\u003C/td>\u003Ctd>SPC-specific (Cpk, ANOVA, eta-squared)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Nelson rules / run tests\u003C/td>\u003Ctd>Not available\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Excel integration\u003C/td>\u003Ctd>Deep (bidirectional)\u003C/td>\u003Ctd>Excel Add-in (native Office.js)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Natural language queries\u003C/td>\u003Ctd>Q&A feature\u003C/td>\u003Ctd>Not applicable\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Price for individual analyst\u003C/td>\u003Ctd>Free (Desktop), $10/month (Pro sharing)\u003C/td>\u003Ctd>Free (PWA) or from €99/month (Azure)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Microsoft ecosystem\u003C/td>\u003Ctd>Deep integration (365, Teams, SharePoint)\u003C/td>\u003Ctd>Azure Marketplace only\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-implications-for-variscout\">Strategic Implications for VariScout\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-implications-for-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Implications for VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"where-we-differentiate\">Where We Differentiate\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#where-we-differentiate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Where We Differentiate”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>SPC-native analysis\u003C/strong>: Power BI has no native SPC capability. Custom visuals and DAX workarounds cannot replicate proper control chart logic, capability analysis, or ANOVA. VariScout is purpose-built for the statistical analysis that Power BI cannot perform.\u003C/li>\n\u003Cli>\u003Cstrong>Zero-configuration statistics\u003C/strong>: Power BI requires a DAX expert to build statistical measures. VariScout calculates Cpk, eta-squared, and ANOVA automatically from the data.\u003C/li>\n\u003Cli>\u003Cstrong>Investigation workflow\u003C/strong>: Power BI reports are static configurations that consumers interact with through slicers. VariScout’s progressive stratification is an investigation methodology where each interaction drives the next analytical step.\u003C/li>\n\u003Cli>\u003Cstrong>Quality professional focus\u003C/strong>: Power BI serves general business analytics. VariScout is designed specifically for quality practitioners — the terminology, workflow, and output match how quality professionals think about variation.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-we-can-learn\">What We Can Learn\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-we-can-learn\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What We Can Learn”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Key Influencers visual\u003C/strong>: Power BI’s automated factor ranking visual demonstrates that even BI tools recognize the need to surface which factors matter. VariScout’s eta-squared ranking is a better implementation for quality data (transparent statistics vs. ML black box), but the concept of visual factor ranking is validated by Power BI’s inclusion of this feature.\u003C/li>\n\u003Cli>\u003Cstrong>Phone-specific layouts\u003C/strong>: Power BI’s approach to creating separate mobile layouts for the same report is a practical solution to the mobile screen budget tension. VariScout could adopt a similar approach for the PWA’s mobile experience.\u003C/li>\n\u003Cli>\u003Cstrong>Responsive slicer pane\u003C/strong>: The collapsible slicer pane demonstrates that even BI tools recognize sidebar filters consume too much screen space. This validates VariScout’s rejection of the sidebar pattern.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-to-avoid-adopting\">What to Avoid Adopting\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-to-avoid-adopting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What to Avoid Adopting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Slicer paradigm\u003C/strong>: The same reasoning as for Tableau applies. Slicers are configuration controls, not investigation actions. VariScout’s chart-integrated filtering is a deliberate differentiation.\u003C/li>\n\u003Cli>\u003Cstrong>DAX complexity\u003C/strong>: Power BI’s reliance on DAX for anything beyond basic aggregations creates a barrier for quality professionals. VariScout should never require formula authoring for standard quality analyses.\u003C/li>\n\u003Cli>\u003Cstrong>Microsoft ecosystem lock-in\u003C/strong>: While VariScout’s Azure app runs in Azure and the Excel Add-in runs in Office, the analytical capability should remain platform-independent. The PWA works anywhere — this flexibility is a differentiator against Power BI’s Microsoft-centric deployment.\u003C/li>\n\u003C/ul>", + { + "headings": 13358, + "localImagePaths": 13391, + "remoteImagePaths": 13392, + "frontmatter": 13393, + "imagePaths": 13394 + }, + [ + 13359, 13361, 13362, 13363, 13366, 13369, 13370, 13373, 13376, 13379, 13382, 13383, 13386, + 13387, 13388, 13389, 13390 + ], + { "depth": 30, "slug": 13360, "text": 13348 }, + "power-bi-competitive-benchmark", + { "depth": 33, "slug": 13080, "text": 13081 }, + { "depth": 33, "slug": 13210, "text": 13211 }, + { "depth": 79, "slug": 13364, "text": 13365 }, + "slicers", + "Slicers", + { "depth": 79, "slug": 13367, "text": 13368 }, + "cross-filtering", + "Cross-Filtering", + { "depth": 79, "slug": 12894, "text": 12882 }, + { "depth": 79, "slug": 13371, "text": 13372 }, + "dax-calculations", + "DAX Calculations", + { "depth": 79, "slug": 13374, "text": 13375 }, + "custom-visuals-appsource", + "Custom Visuals (AppSource)", + { "depth": 79, "slug": 13377, "text": 13378 }, + "excel-integration", + "Excel Integration", + { "depth": 79, "slug": 13380, "text": 13381 }, + "ai-features", + "AI Features", + { "depth": 33, "slug": 13234, "text": 13235 }, + { "depth": 33, "slug": 13384, "text": 13385 }, + "how-power-bi-addresses-our-6-tensions", + "How Power BI Addresses Our 6 Tensions", + { "depth": 33, "slug": 2115, "text": 2116 }, + { "depth": 33, "slug": 13177, "text": 13178 }, + { "depth": 79, "slug": 13242, "text": 13243 }, + { "depth": 79, "slug": 13245, "text": 13246 }, + { "depth": 79, "slug": 13248, "text": 13249 }, + [], + [], + { "title": 13348 }, + [], + "01-vision/evaluations/competitive/tableau-benchmark", + { + "id": 13395, + "data": 13397, + "body": 13402, + "filePath": 13403, + "digest": 13404, + "rendered": 13405 + }, + { + "title": 13398, + "editUrl": 16, + "head": 13399, + "template": 18, + "sidebar": 13400, + "pagefind": 16, + "draft": 20 + }, + "Tableau Competitive Benchmark", + [], + { "hidden": 20, "attrs": 13401 }, + {}, + "# Tableau Competitive Benchmark\n\n> Based on public documentation, published feature sets, and market positioning knowledge. Unlike the [EDAScout Benchmark](edascout-benchmark.md), this assessment does not include direct codebase analysis.\n\n---\n\n## Product Profile\n\n| Dimension | Tableau | VariScout |\n| ------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------- |\n| **Platform** | Desktop (authoring) + Server/Cloud (viewing) | Browser-based (PWA, Azure, Excel Add-in) |\n| **Pricing** | $75/user/month (Creator), $42/user/month (Explorer), $15/user/month (Viewer) | From €99/month (Azure) or free (PWA) |\n| **Distribution** | Salesforce direct sales, cloud and on-premise | Azure Marketplace, AppSource, public URL |\n| **Target audience** | Business analysts, data teams, executives | Quality practitioners, Green Belts, learners |\n| **Market position** | Dominant BI and visual analytics platform | Specialized variation analysis tool |\n| **Analysis model** | Dashboard-centric: drag fields onto shelves, build views, assemble dashboards | Four Lenses: 4 coordinated charts with linked filtering |\n| **Navigation** | Sidebar filters, cross-filtering between sheets | Progressive stratification drill-down |\n| **Parent company** | Salesforce | Independent |\n\n---\n\n## Core Capabilities\n\nTableau is the industry-defining visual analytics platform. It excels at making data accessible through interactive visualizations and dashboards. Its relevance to VariScout is primarily as the tool that defines the \"sidebar filter\" paradigm that VariScout explicitly rejects.\n\n### Visual Analytics Engine\n\nTableau's VizQL engine automatically determines appropriate chart types based on the data types placed on rows, columns, and marks shelves. The analyst builds views by dragging fields — similar in spirit to JMP's Graph Builder but optimized for business data rather than statistical analysis. The visual grammar is expressive: small multiples, stacked bars, scatterplots, maps, and treemaps are all achievable through shelf configuration.\n\n### Sidebar Filters\n\nTableau's filter panel is the paradigm for dashboard filtering. Filters appear as sidebar controls — dropdowns, checkboxes, sliders, date ranges — alongside the visualization area. Each filter operates on a dimension or measure. Filters can be configured as single-select, multi-select, or range. Quick filters provide immediate visual feedback as selections change.\n\nCross-filtering between sheets on a dashboard allows clicking a data point in one chart to filter all other charts. This is the closest Tableau comes to VariScout's linked filtering, though the mechanism is fundamentally different: Tableau cross-filtering is a dashboard configuration feature, not an investigation methodology.\n\n### Small Multiples\n\nTableau natively supports small multiples through the rows and columns shelves. Dragging a dimension to the rows shelf creates a grid of charts — one per dimension value. The implementation is flexible: any chart type can be faceted across any dimension. This is one of Tableau's strongest features for comparison-based analysis.\n\n### Calculated Fields and LOD Expressions\n\nTableau's calculated field language supports aggregation, string manipulation, date operations, and table calculations. Level of Detail (LOD) expressions allow calculations at different granularities than the visualization's default. However, statistical calculations beyond basic aggregations (mean, median, count, percentile) require LOD expertise. There is no built-in ANOVA, regression, or capability analysis.\n\n### Dashboard Assembly\n\nTableau's primary output is the dashboard: a canvas combining multiple visualization sheets, filter controls, text, and images. Dashboards are designed for consumption — built by analysts, viewed by stakeholders. The authoring/viewing split maps to the Creator/Explorer/Viewer pricing tiers.\n\n### Tableau Prep\n\nData preparation tool for cleaning, reshaping, and joining data before analysis. Relevant to quality data workflows where raw measurement data needs structuring. This is a separate product from the analytics platform.\n\n---\n\n## Analysis and Investigation Workflow\n\nTableau's workflow is **build-then-view**:\n\n1. The analyst (Creator) connects to data sources\n2. They build individual visualization sheets by dragging fields onto shelves\n3. They assemble sheets into dashboards with filter controls\n4. They publish dashboards for Explorers and Viewers to consume\n5. Consumers interact through the pre-configured filters and cross-filtering\n\nFor variation investigation, a Tableau user would:\n\n1. Build a bar chart showing a measurement across factors (machines, shifts, etc.)\n2. Add reference lines for specification limits (manual configuration)\n3. Create additional sheets for different views of the same data\n4. Assemble a dashboard with filter controls for each factor\n5. Use the dashboard interactively, applying filters to see subsets\n\nThe critical gap: Tableau cannot calculate control limits, capability indices, ANOVA, or any SPC-specific statistics. The analyst must calculate these externally (in Excel or R/Python) and import the results, or use basic aggregations (mean, standard deviation) as approximations. There are no Nelson rules, no Western Electric rules, no statistical process control logic.\n\nThe filter interaction model is fundamentally different from VariScout's progressive stratification. Tableau filters are configuration controls — the analyst checks boxes and selects values. VariScout's drill-down is an investigation action — the analyst clicks where they see variation, and the click carries analytical meaning (filtering by the source of variation).\n\n---\n\n## How Tableau Addresses Our 6 Tensions\n\n| Tension | Tableau's Approach | Assessment |\n| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |\n| **Hierarchy Assumption** | No interaction detection. Calculated fields can approximate interaction effects through LOD expressions, but this requires advanced Tableau expertise and isn't part of any standard workflow. | Not addressed. |\n| **Discoverability** | Sidebar filters make all filter options permanently visible. Cross-filtering between charts provides visual feedback. This is the strongest discoverability model in BI tools — everything is always visible. | Fully addressed for filter discoverability; not addressed for analytical discoverability (which factors matter). |\n| **Factor Ordering** | No concept of factor ranking by contribution. All filters are presented equally. The analyst must bring their own domain knowledge to decide which factors to examine. | Not addressed. |\n| **When to Stop** | No stopping guidance. Dashboards are open-ended exploration tools with no concept of investigation completeness. | Not addressed. |\n| **Mobile Screen Budget** | Tableau Mobile adapts dashboards to smaller screens. Device-specific layouts can be designed. But sidebar filters consume significant screen real estate on mobile, requiring a collapsible filter pane. | Partially addressed through device layouts; filter space remains problematic. |\n| **Path Dependency** | No drill-down path exists. Filters are stateless configurations — applying Machine=A then Shift=Night produces the same result as Shift=Night then Machine=A. | Not applicable — no sequential drill-down model. |\n\n---\n\n## Feature Comparison\n\n| Capability | Tableau | VariScout |\n| ----------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------ |\n| Visual analytics (general) | Industry-leading breadth and polish | Focused on SPC/quality domain |\n| Control charts (I-MR) | Not available natively | Yes (I-Chart) |\n| Capability analysis (Cp/Cpk) | Not available | Yes, integrated |\n| Boxplot | Available as chart type | Integrated with drill-down filtering |\n| Pareto chart | Available (sorted bar chart) | Integrated with drill-down filtering |\n| ANOVA | Not available | Yes, with eta-squared ranking |\n| Regression | Trend line only (no model diagnostics) | Simple and multiple regression |\n| Gage R&R | Not available | Not available |\n| Small multiples | Native (rows/columns shelf) | Planned feature |\n| Sidebar filters | Core paradigm (checkboxes, sliders, dropdowns) | Rejected pattern (see [evaluation](../patterns/sidebar-filter-panel.md)) |\n| Cross-filtering | Yes (dashboard-level action) | Yes (linked filtering, investigation-driven) |\n| Linked filtering across chart types | Dashboard actions (configurable) | Native (core differentiator) |\n| Statistical calculations | Basic aggregations only | SPC-specific (Cpk, ANOVA, eta-squared) |\n| Nelson rules / run tests | Not available | Yes |\n| Dashboard publishing | Yes (Server/Cloud) | Not applicable (analysis tool, not BI) |\n| Browser-based analysis | Viewer/Explorer roles (view and filter only) | Full analysis capability |\n| Price for individual analyst | $75/month (Creator) | Free (PWA) or from €99/month (Azure) |\n\n---\n\n## Strategic Implications for VariScout\n\n### Where We Differentiate\n\n- **Statistical depth**: Tableau has no SPC capabilities. No control charts, no capability analysis, no ANOVA, no process-specific statistics. This is the most fundamental differentiation — VariScout solves a problem Tableau cannot address.\n- **Investigation vs. dashboard**: Tableau builds dashboards for known questions. VariScout guides investigations for unknown causes. The cognitive model is fundamentally different — configuration vs. investigation.\n- **Variation quantification**: Tableau can show data by factor but cannot quantify how much each factor contributes to variation. Eta-squared ranking and cumulative variation tracking are capabilities that BI tools lack entirely.\n- **Methodology embedding**: VariScout's progressive stratification is an investigation methodology built into the interaction design. Tableau provides flexible tools; the methodology is the analyst's responsibility.\n\n### What We Can Learn\n\n- **Cross-filtering polish**: Tableau's cross-filtering between dashboard sheets is smooth and well-understood by users. VariScout's linked filtering should aspire to the same responsiveness and visual feedback quality.\n- **Small multiples implementation**: Tableau's native small multiples through the rows/columns shelf is the benchmark for how this pattern should work. When VariScout implements small multiples, Tableau's interaction model is the reference.\n- **Device-responsive layouts**: Tableau's approach to device-specific dashboard layouts demonstrates how to handle the mobile screen budget for complex analytical interfaces.\n\n### What to Avoid Adopting\n\n- **Sidebar filter paradigm**: This is the central point. Tableau's sidebar filters solve discoverability by making everything visible, but they convert analysis into configuration. VariScout's chart-integrated filtering is a deliberate differentiation from this paradigm. See the [Sidebar Filter Panel evaluation](../patterns/sidebar-filter-panel.md).\n- **Build-then-view separation**: Tableau's Creator/Viewer split is a BI paradigm where analysts build and stakeholders consume. VariScout treats everyone as an investigator — the same person who sees the data also drills into it.\n- **Breadth over depth**: Tableau's strength is generality — it works with any data for any question. VariScout's strength is specificity — it's designed for variation investigation in quality processes. Generalizing toward a BI tool would lose the domain advantage.", + "src/content/docs/01-vision/evaluations/competitive/tableau-benchmark.md", + "4e70a7f4b9e84435", + { "html": 13406, "metadata": 13407 }, + "\u003Cdiv class=\"sl-heading-wrapper level-h1\">\u003Ch1 id=\"tableau-competitive-benchmark\">Tableau Competitive Benchmark\u003C/h1>\u003Ca class=\"sl-anchor-link\" href=\"#tableau-competitive-benchmark\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tableau Competitive Benchmark”\u003C/span>\u003C/a>\u003C/div>\n\u003Cblockquote>\n\u003Cp>Based on public documentation, published feature sets, and market positioning knowledge. Unlike the \u003Ca href=\"edascout-benchmark.md\">EDAScout Benchmark\u003C/a>, this assessment does not include direct codebase analysis.\u003C/p>\n\u003C/blockquote>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"product-profile\">Product Profile\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#product-profile\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Product Profile”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Dimension\u003C/th>\u003Cth>Tableau\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Platform\u003C/strong>\u003C/td>\u003Ctd>Desktop (authoring) + Server/Cloud (viewing)\u003C/td>\u003Ctd>Browser-based (PWA, Azure, Excel Add-in)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Pricing\u003C/strong>\u003C/td>\u003Ctd>$75/user/month (Creator), $42/user/month (Explorer), $15/user/month (Viewer)\u003C/td>\u003Ctd>From €99/month (Azure) or free (PWA)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Distribution\u003C/strong>\u003C/td>\u003Ctd>Salesforce direct sales, cloud and on-premise\u003C/td>\u003Ctd>Azure Marketplace, AppSource, public URL\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Target audience\u003C/strong>\u003C/td>\u003Ctd>Business analysts, data teams, executives\u003C/td>\u003Ctd>Quality practitioners, Green Belts, learners\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Market position\u003C/strong>\u003C/td>\u003Ctd>Dominant BI and visual analytics platform\u003C/td>\u003Ctd>Specialized variation analysis tool\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Analysis model\u003C/strong>\u003C/td>\u003Ctd>Dashboard-centric: drag fields onto shelves, build views, assemble dashboards\u003C/td>\u003Ctd>Four Lenses: 4 coordinated charts with linked filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Navigation\u003C/strong>\u003C/td>\u003Ctd>Sidebar filters, cross-filtering between sheets\u003C/td>\u003Ctd>Progressive stratification drill-down\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Parent company\u003C/strong>\u003C/td>\u003Ctd>Salesforce\u003C/td>\u003Ctd>Independent\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"core-capabilities\">Core Capabilities\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#core-capabilities\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Core Capabilities”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Tableau is the industry-defining visual analytics platform. It excels at making data accessible through interactive visualizations and dashboards. Its relevance to VariScout is primarily as the tool that defines the “sidebar filter” paradigm that VariScout explicitly rejects.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"visual-analytics-engine\">Visual Analytics Engine\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#visual-analytics-engine\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Visual Analytics Engine”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Tableau’s VizQL engine automatically determines appropriate chart types based on the data types placed on rows, columns, and marks shelves. The analyst builds views by dragging fields — similar in spirit to JMP’s Graph Builder but optimized for business data rather than statistical analysis. The visual grammar is expressive: small multiples, stacked bars, scatterplots, maps, and treemaps are all achievable through shelf configuration.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"sidebar-filters\">Sidebar Filters\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#sidebar-filters\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Sidebar Filters”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Tableau’s filter panel is the paradigm for dashboard filtering. Filters appear as sidebar controls — dropdowns, checkboxes, sliders, date ranges — alongside the visualization area. Each filter operates on a dimension or measure. Filters can be configured as single-select, multi-select, or range. Quick filters provide immediate visual feedback as selections change.\u003C/p>\n\u003Cp>Cross-filtering between sheets on a dashboard allows clicking a data point in one chart to filter all other charts. This is the closest Tableau comes to VariScout’s linked filtering, though the mechanism is fundamentally different: Tableau cross-filtering is a dashboard configuration feature, not an investigation methodology.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"small-multiples\">Small Multiples\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#small-multiples\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Small Multiples”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Tableau natively supports small multiples through the rows and columns shelves. Dragging a dimension to the rows shelf creates a grid of charts — one per dimension value. The implementation is flexible: any chart type can be faceted across any dimension. This is one of Tableau’s strongest features for comparison-based analysis.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"calculated-fields-and-lod-expressions\">Calculated Fields and LOD Expressions\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#calculated-fields-and-lod-expressions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Calculated Fields and LOD Expressions”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Tableau’s calculated field language supports aggregation, string manipulation, date operations, and table calculations. Level of Detail (LOD) expressions allow calculations at different granularities than the visualization’s default. However, statistical calculations beyond basic aggregations (mean, median, count, percentile) require LOD expertise. There is no built-in ANOVA, regression, or capability analysis.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"dashboard-assembly\">Dashboard Assembly\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#dashboard-assembly\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Dashboard Assembly”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Tableau’s primary output is the dashboard: a canvas combining multiple visualization sheets, filter controls, text, and images. Dashboards are designed for consumption — built by analysts, viewed by stakeholders. The authoring/viewing split maps to the Creator/Explorer/Viewer pricing tiers.\u003C/p>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"tableau-prep\">Tableau Prep\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#tableau-prep\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Tableau Prep”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Data preparation tool for cleaning, reshaping, and joining data before analysis. Relevant to quality data workflows where raw measurement data needs structuring. This is a separate product from the analytics platform.\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"analysis-and-investigation-workflow\">Analysis and Investigation Workflow\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#analysis-and-investigation-workflow\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Analysis and Investigation Workflow”\u003C/span>\u003C/a>\u003C/div>\n\u003Cp>Tableau’s workflow is \u003Cstrong>build-then-view\u003C/strong>:\u003C/p>\n\u003Col>\n\u003Cli>The analyst (Creator) connects to data sources\u003C/li>\n\u003Cli>They build individual visualization sheets by dragging fields onto shelves\u003C/li>\n\u003Cli>They assemble sheets into dashboards with filter controls\u003C/li>\n\u003Cli>They publish dashboards for Explorers and Viewers to consume\u003C/li>\n\u003Cli>Consumers interact through the pre-configured filters and cross-filtering\u003C/li>\n\u003C/ol>\n\u003Cp>For variation investigation, a Tableau user would:\u003C/p>\n\u003Col>\n\u003Cli>Build a bar chart showing a measurement across factors (machines, shifts, etc.)\u003C/li>\n\u003Cli>Add reference lines for specification limits (manual configuration)\u003C/li>\n\u003Cli>Create additional sheets for different views of the same data\u003C/li>\n\u003Cli>Assemble a dashboard with filter controls for each factor\u003C/li>\n\u003Cli>Use the dashboard interactively, applying filters to see subsets\u003C/li>\n\u003C/ol>\n\u003Cp>The critical gap: Tableau cannot calculate control limits, capability indices, ANOVA, or any SPC-specific statistics. The analyst must calculate these externally (in Excel or R/Python) and import the results, or use basic aggregations (mean, standard deviation) as approximations. There are no Nelson rules, no Western Electric rules, no statistical process control logic.\u003C/p>\n\u003Cp>The filter interaction model is fundamentally different from VariScout’s progressive stratification. Tableau filters are configuration controls — the analyst checks boxes and selects values. VariScout’s drill-down is an investigation action — the analyst clicks where they see variation, and the click carries analytical meaning (filtering by the source of variation).\u003C/p>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"how-tableau-addresses-our-6-tensions\">How Tableau Addresses Our 6 Tensions\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#how-tableau-addresses-our-6-tensions\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “How Tableau Addresses Our 6 Tensions”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tension\u003C/th>\u003Cth>Tableau’s Approach\u003C/th>\u003Cth>Assessment\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cstrong>Hierarchy Assumption\u003C/strong>\u003C/td>\u003Ctd>No interaction detection. Calculated fields can approximate interaction effects through LOD expressions, but this requires advanced Tableau expertise and isn’t part of any standard workflow.\u003C/td>\u003Ctd>Not addressed.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Discoverability\u003C/strong>\u003C/td>\u003Ctd>Sidebar filters make all filter options permanently visible. Cross-filtering between charts provides visual feedback. This is the strongest discoverability model in BI tools — everything is always visible.\u003C/td>\u003Ctd>Fully addressed for filter discoverability; not addressed for analytical discoverability (which factors matter).\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Factor Ordering\u003C/strong>\u003C/td>\u003Ctd>No concept of factor ranking by contribution. All filters are presented equally. The analyst must bring their own domain knowledge to decide which factors to examine.\u003C/td>\u003Ctd>Not addressed.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>When to Stop\u003C/strong>\u003C/td>\u003Ctd>No stopping guidance. Dashboards are open-ended exploration tools with no concept of investigation completeness.\u003C/td>\u003Ctd>Not addressed.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Mobile Screen Budget\u003C/strong>\u003C/td>\u003Ctd>Tableau Mobile adapts dashboards to smaller screens. Device-specific layouts can be designed. But sidebar filters consume significant screen real estate on mobile, requiring a collapsible filter pane.\u003C/td>\u003Ctd>Partially addressed through device layouts; filter space remains problematic.\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>\u003Cstrong>Path Dependency\u003C/strong>\u003C/td>\u003Ctd>No drill-down path exists. Filters are stateless configurations — applying Machine=A then Shift=Night produces the same result as Shift=Night then Machine=A.\u003C/td>\u003Ctd>Not applicable — no sequential drill-down model.\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"feature-comparison\">Feature Comparison\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#feature-comparison\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Feature Comparison”\u003C/span>\u003C/a>\u003C/div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Capability\u003C/th>\u003Cth>Tableau\u003C/th>\u003Cth>VariScout\u003C/th>\u003C/tr>\u003C/thead>\u003Ctbody>\u003Ctr>\u003Ctd>Visual analytics (general)\u003C/td>\u003Ctd>Industry-leading breadth and polish\u003C/td>\u003Ctd>Focused on SPC/quality domain\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Control charts (I-MR)\u003C/td>\u003Ctd>Not available natively\u003C/td>\u003Ctd>Yes (I-Chart)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Capability analysis (Cp/Cpk)\u003C/td>\u003Ctd>Not available\u003C/td>\u003Ctd>Yes, integrated\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Boxplot\u003C/td>\u003Ctd>Available as chart type\u003C/td>\u003Ctd>Integrated with drill-down filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Pareto chart\u003C/td>\u003Ctd>Available (sorted bar chart)\u003C/td>\u003Ctd>Integrated with drill-down filtering\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>ANOVA\u003C/td>\u003Ctd>Not available\u003C/td>\u003Ctd>Yes, with eta-squared ranking\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Regression\u003C/td>\u003Ctd>Trend line only (no model diagnostics)\u003C/td>\u003Ctd>Simple and multiple regression\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Gage R&R\u003C/td>\u003Ctd>Not available\u003C/td>\u003Ctd>Not available\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Small multiples\u003C/td>\u003Ctd>Native (rows/columns shelf)\u003C/td>\u003Ctd>Planned feature\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Sidebar filters\u003C/td>\u003Ctd>Core paradigm (checkboxes, sliders, dropdowns)\u003C/td>\u003Ctd>Rejected pattern (see \u003Ca href=\"../patterns/sidebar-filter-panel.md\">evaluation\u003C/a>)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Cross-filtering\u003C/td>\u003Ctd>Yes (dashboard-level action)\u003C/td>\u003Ctd>Yes (linked filtering, investigation-driven)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Linked filtering across chart types\u003C/td>\u003Ctd>Dashboard actions (configurable)\u003C/td>\u003Ctd>Native (core differentiator)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Statistical calculations\u003C/td>\u003Ctd>Basic aggregations only\u003C/td>\u003Ctd>SPC-specific (Cpk, ANOVA, eta-squared)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Nelson rules / run tests\u003C/td>\u003Ctd>Not available\u003C/td>\u003Ctd>Yes\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Dashboard publishing\u003C/td>\u003Ctd>Yes (Server/Cloud)\u003C/td>\u003Ctd>Not applicable (analysis tool, not BI)\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Browser-based analysis\u003C/td>\u003Ctd>Viewer/Explorer roles (view and filter only)\u003C/td>\u003Ctd>Full analysis capability\u003C/td>\u003C/tr>\u003Ctr>\u003Ctd>Price for individual analyst\u003C/td>\u003Ctd>$75/month (Creator)\u003C/td>\u003Ctd>Free (PWA) or from €99/month (Azure)\u003C/td>\u003C/tr>\u003C/tbody>\u003C/table>\n\u003Chr>\n\u003Cdiv class=\"sl-heading-wrapper level-h2\">\u003Ch2 id=\"strategic-implications-for-variscout\">Strategic Implications for VariScout\u003C/h2>\u003Ca class=\"sl-anchor-link\" href=\"#strategic-implications-for-variscout\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Strategic Implications for VariScout”\u003C/span>\u003C/a>\u003C/div>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"where-we-differentiate\">Where We Differentiate\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#where-we-differentiate\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “Where We Differentiate”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Statistical depth\u003C/strong>: Tableau has no SPC capabilities. No control charts, no capability analysis, no ANOVA, no process-specific statistics. This is the most fundamental differentiation — VariScout solves a problem Tableau cannot address.\u003C/li>\n\u003Cli>\u003Cstrong>Investigation vs. dashboard\u003C/strong>: Tableau builds dashboards for known questions. VariScout guides investigations for unknown causes. The cognitive model is fundamentally different — configuration vs. investigation.\u003C/li>\n\u003Cli>\u003Cstrong>Variation quantification\u003C/strong>: Tableau can show data by factor but cannot quantify how much each factor contributes to variation. Eta-squared ranking and cumulative variation tracking are capabilities that BI tools lack entirely.\u003C/li>\n\u003Cli>\u003Cstrong>Methodology embedding\u003C/strong>: VariScout’s progressive stratification is an investigation methodology built into the interaction design. Tableau provides flexible tools; the methodology is the analyst’s responsibility.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-we-can-learn\">What We Can Learn\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-we-can-learn\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What We Can Learn”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Cross-filtering polish\u003C/strong>: Tableau’s cross-filtering between dashboard sheets is smooth and well-understood by users. VariScout’s linked filtering should aspire to the same responsiveness and visual feedback quality.\u003C/li>\n\u003Cli>\u003Cstrong>Small multiples implementation\u003C/strong>: Tableau’s native small multiples through the rows/columns shelf is the benchmark for how this pattern should work. When VariScout implements small multiples, Tableau’s interaction model is the reference.\u003C/li>\n\u003Cli>\u003Cstrong>Device-responsive layouts\u003C/strong>: Tableau’s approach to device-specific dashboard layouts demonstrates how to handle the mobile screen budget for complex analytical interfaces.\u003C/li>\n\u003C/ul>\n\u003Cdiv class=\"sl-heading-wrapper level-h3\">\u003Ch3 id=\"what-to-avoid-adopting\">What to Avoid Adopting\u003C/h3>\u003Ca class=\"sl-anchor-link\" href=\"#what-to-avoid-adopting\">\u003Cspan aria-hidden=\"true\" class=\"sl-anchor-icon\">\u003Csvg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\">\u003Cpath fill=\"currentcolor\" d=\"m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z\">\u003C/path>\u003C/svg>\u003C/span>\u003Cspan class=\"sr-only\">Section titled “What to Avoid Adopting”\u003C/span>\u003C/a>\u003C/div>\n\u003Cul>\n\u003Cli>\u003Cstrong>Sidebar filter paradigm\u003C/strong>: This is the central point. Tableau’s sidebar filters solve discoverability by making everything visible, but they convert analysis into configuration. VariScout’s chart-integrated filtering is a deliberate differentiation from this paradigm. See the \u003Ca href=\"../patterns/sidebar-filter-panel.md\">Sidebar Filter Panel evaluation\u003C/a>.\u003C/li>\n\u003Cli>\u003Cstrong>Build-then-view separation\u003C/strong>: Tableau’s Creator/Viewer split is a BI paradigm where analysts build and stakeholders consume. VariScout treats everyone as an investigator — the same person who sees the data also drills into it.\u003C/li>\n\u003Cli>\u003Cstrong>Breadth over depth\u003C/strong>: Tableau’s strength is generality — it works with any data for any question. VariScout’s strength is specificity — it’s designed for variation investigation in quality processes. Generalizing toward a BI tool would lose the domain advantage.\u003C/li>\n\u003C/ul>", + { + "headings": 13408, + "localImagePaths": 13438, + "remoteImagePaths": 13439, + "frontmatter": 13440, + "imagePaths": 13441 + }, + [ + 13409, 13411, 13412, 13413, 13416, 13419, 13420, 13423, 13426, 13429, 13430, 13433, 13434, + 13435, 13436, 13437 + ], + { "depth": 30, "slug": 13410, "text": 13398 }, + "tableau-competitive-benchmark", + { "depth": 33, "slug": 13080, "text": 13081 }, + { "depth": 33, "slug": 13210, "text": 13211 }, + { "depth": 79, "slug": 13414, "text": 13415 }, + "visual-analytics-engine", + "Visual Analytics Engine", + { "depth": 79, "slug": 13417, "text": 13418 }, + "sidebar-filters", + "Sidebar Filters", + { "depth": 79, "slug": 12894, "text": 12882 }, + { "depth": 79, "slug": 13421, "text": 13422 }, + "calculated-fields-and-lod-expressions", + "Calculated Fields and LOD Expressions", + { "depth": 79, "slug": 13424, "text": 13425 }, + "dashboard-assembly", + "Dashboard Assembly", + { "depth": 79, "slug": 13427, "text": 13428 }, + "tableau-prep", + "Tableau Prep", + { "depth": 33, "slug": 13234, "text": 13235 }, + { "depth": 33, "slug": 13431, "text": 13432 }, + "how-tableau-addresses-our-6-tensions", + "How Tableau Addresses Our 6 Tensions", + { "depth": 33, "slug": 2115, "text": 2116 }, + { "depth": 33, "slug": 13177, "text": 13178 }, + { "depth": 79, "slug": 13242, "text": 13243 }, + { "depth": 79, "slug": 13245, "text": 13246 }, + { "depth": 79, "slug": 13248, "text": 13249 }, + [], + [], + { "title": 13398 }, + [] +] diff --git a/apps/docs/.astro/settings.json b/apps/docs/.astro/settings.json new file mode 100644 index 000000000..0144f6b2a --- /dev/null +++ b/apps/docs/.astro/settings.json @@ -0,0 +1,5 @@ +{ + "_variables": { + "lastUpdateCheck": 1773761951977 + } +} diff --git a/apps/docs/.astro/types.d.ts b/apps/docs/.astro/types.d.ts new file mode 100644 index 000000000..306a68bfd --- /dev/null +++ b/apps/docs/.astro/types.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/apps/docs/astro.config.mjs b/apps/docs/astro.config.mjs new file mode 100644 index 000000000..846de880e --- /dev/null +++ b/apps/docs/astro.config.mjs @@ -0,0 +1,853 @@ +import { defineConfig } from 'astro/config'; +import starlight from '@astrojs/starlight'; +import rehypeMermaid from 'rehype-mermaid'; + +export default defineConfig({ + integrations: [ + starlight({ + title: 'VariScout Docs', + description: + 'Lightweight, offline-first variation analysis for quality professionals', + defaultLocale: 'en', + social: [ + { + icon: 'github', + label: 'GitHub', + href: 'https://github.com/variscout/variscout-lite', + }, + ], + customCss: ['./src/styles/custom.css'], + sidebar: [ + // ── Domain ── + { + label: 'Domain', + items: [ + { + label: 'Vision', + items: [ + { label: 'Overview', slug: '01-vision' }, + { label: 'Philosophy', slug: '01-vision/philosophy' }, + { + label: 'Product Overview', + slug: '01-vision/product-overview', + }, + { + label: 'Market Analysis', + slug: '01-vision/market-analysis', + }, + { + label: 'Progressive Stratification', + slug: '01-vision/progressive-stratification', + }, + { + label: 'Four Lenses', + items: [ + { label: 'Overview', slug: '01-vision/four-lenses' }, + { label: 'Change', slug: '01-vision/four-lenses/change' }, + { label: 'Flow', slug: '01-vision/four-lenses/flow' }, + { + label: 'Failure', + slug: '01-vision/four-lenses/failure', + }, + { label: 'Value', slug: '01-vision/four-lenses/value' }, + { + label: 'Drill-Down', + slug: '01-vision/four-lenses/drilldown', + }, + ], + }, + { + label: 'Two Voices', + items: [ + { label: 'Overview', slug: '01-vision/two-voices' }, + { + label: 'Control Limits', + slug: '01-vision/two-voices/control-limits', + }, + { + label: 'Spec Limits', + slug: '01-vision/two-voices/spec-limits', + }, + { + label: 'Variation Types', + slug: '01-vision/two-voices/variation-types', + }, + { + label: 'Scenarios', + slug: '01-vision/two-voices/scenarios', + }, + ], + }, + { + label: 'Evaluations', + collapsed: true, + items: [ + { label: 'Overview', slug: '01-vision/evaluations' }, + { + label: 'Investigation Flow Map', + slug: '01-vision/evaluations/investigation-flow-map', + }, + { + label: 'Design Brief', + slug: '01-vision/evaluations/design-brief-guided-investigation', + }, + { + label: 'Mindmap Spec', + slug: '01-vision/evaluations/design-spec-investigation-mindmap', + }, + { + label: 'Competitive', + collapsed: true, + items: [ + { + label: 'Minitab', + slug: '01-vision/evaluations/competitive/minitab-benchmark', + }, + { + label: 'JMP', + slug: '01-vision/evaluations/competitive/jmp-benchmark', + }, + { + label: 'Tableau', + slug: '01-vision/evaluations/competitive/tableau-benchmark', + }, + { + label: 'Power BI', + slug: '01-vision/evaluations/competitive/powerbi-benchmark', + }, + { + label: 'EDAScout', + slug: '01-vision/evaluations/competitive/edascout-benchmark', + }, + { + label: 'Other', + slug: '01-vision/evaluations/competitive/minor-competitors', + }, + ], + }, + { + label: 'Patterns', + collapsed: true, + items: [ + { + label: 'Investigation Mindmap', + slug: '01-vision/evaluations/patterns/investigation-mindmap', + }, + { + label: 'Investigation Narrative', + slug: '01-vision/evaluations/patterns/investigation-narrative', + }, + { + label: 'Factor Suggestion', + slug: '01-vision/evaluations/patterns/factor-suggestion', + }, + { + label: 'Auto Combination', + slug: '01-vision/evaluations/patterns/auto-combination-finder', + }, + { + label: 'Interaction Heatmap', + slug: '01-vision/evaluations/patterns/interaction-heatmap', + }, + { + label: 'Sidebar Filter', + slug: '01-vision/evaluations/patterns/sidebar-filter-panel', + }, + { + label: 'Small Multiples', + slug: '01-vision/evaluations/patterns/small-multiples', + }, + { + label: 'Factor Map', + slug: '01-vision/evaluations/patterns/factor-map', + }, + { + label: 'Parallel Paths', + slug: '01-vision/evaluations/patterns/parallel-path-comparison', + }, + ], + }, + { + label: 'Tensions', + collapsed: true, + items: [ + { + label: 'Discoverability', + slug: '01-vision/evaluations/tensions/discoverability', + }, + { + label: 'Factor Ordering', + slug: '01-vision/evaluations/tensions/factor-ordering', + }, + { + label: 'Hierarchy Assumption', + slug: '01-vision/evaluations/tensions/hierarchy-assumption', + }, + { + label: 'Mobile Screen', + slug: '01-vision/evaluations/tensions/mobile-screen-budget', + }, + { + label: 'Path Dependency', + slug: '01-vision/evaluations/tensions/path-dependency', + }, + { + label: 'When to Stop', + slug: '01-vision/evaluations/tensions/when-to-stop', + }, + ], + }, + ], + }, + ], + }, + { + label: 'Journeys', + items: [ + { + label: 'Personas', + collapsed: true, + items: [ + { + label: 'Green Belt Gary', + slug: '02-journeys/personas/green-belt-gary', + }, + { + label: 'Curious Carlos', + slug: '02-journeys/personas/curious-carlos', + }, + { + label: 'OpEx Olivia', + slug: '02-journeys/personas/opex-olivia', + }, + { + label: 'Student Sara', + slug: '02-journeys/personas/student-sara', + }, + { + label: 'Evaluator Erik', + slug: '02-journeys/personas/evaluator-erik', + }, + { + label: 'Trainer Tina', + slug: '02-journeys/personas/trainer-tina', + }, + ], + }, + { + label: 'UX Research', + slug: '02-journeys/ux-research', + }, + { + label: 'Use Cases', + collapsed: true, + items: [ + { label: 'Overview', slug: '02-journeys/use-cases' }, + { + label: 'Batch Consistency', + slug: '02-journeys/use-cases/batch-consistency', + }, + { + label: 'Bottleneck Analysis', + slug: '02-journeys/use-cases/bottleneck-analysis', + }, + { + label: 'Call Center', + slug: '02-journeys/use-cases/call-center-performance', + }, + { + label: 'Complaint Investigation', + slug: '02-journeys/use-cases/complaint-investigation', + }, + { + label: 'Consultant Delivery', + slug: '02-journeys/use-cases/consultant-delivery', + }, + { + label: 'COPQ Drilldown', + slug: '02-journeys/use-cases/copq-drilldown', + }, + { + label: 'Lead Time', + slug: '02-journeys/use-cases/lead-time-variation', + }, + { + label: 'On-Time Delivery', + slug: '02-journeys/use-cases/on-time-delivery', + }, + { + label: 'Patient Wait Time', + slug: '02-journeys/use-cases/patient-wait-time', + }, + { + label: 'Pharma OOS', + slug: '02-journeys/use-cases/pharma-oos', + }, + { + label: 'Supplier PPAP', + slug: '02-journeys/use-cases/supplier-ppap', + }, + { + label: 'Supplier Performance', + slug: '02-journeys/use-cases/supplier-performance', + }, + { + label: 'University SPC', + slug: '02-journeys/use-cases/university-spc', + }, + ], + }, + { + label: 'User Flows', + collapsed: true, + items: [ + { + label: 'SEO Learner', + slug: '02-journeys/flows/seo-learner', + }, + { + label: 'Social Discovery', + slug: '02-journeys/flows/social-discovery', + }, + { + label: 'Content & YouTube', + slug: '02-journeys/flows/content-youtube', + }, + { + label: 'Enterprise', + slug: '02-journeys/flows/enterprise', + }, + { + label: 'Return Visitor', + slug: '02-journeys/flows/return-visitor', + }, + { + label: 'Azure First Analysis', + slug: '02-journeys/flows/azure-first-analysis', + }, + { + label: 'Azure Daily Use', + slug: '02-journeys/flows/azure-daily-use', + }, + { + label: 'Azure Team Collaboration', + slug: '02-journeys/flows/azure-team-collaboration', + }, + ], + }, + ], + }, + { + label: 'Case Studies', + collapsed: true, + items: [ + { label: 'Overview', slug: '04-cases' }, + { label: 'Bottleneck', slug: '04-cases/bottleneck' }, + { label: 'Hospital Ward', slug: '04-cases/hospital-ward' }, + { label: 'Coffee', slug: '04-cases/coffee' }, + { label: 'Packaging', slug: '04-cases/packaging' }, + { label: 'Avocado', slug: '04-cases/avocado' }, + { + label: 'Machine Utilization', + slug: '04-cases/machine-utilization', + }, + { label: 'Oven Zones', slug: '04-cases/oven-zones' }, + ], + }, + ], + }, + + // ── Features ── + { + label: 'Features', + items: [ + { label: 'Overview', slug: '03-features' }, + { label: 'Specifications', slug: '03-features/specifications' }, + { label: 'User Guide', slug: '03-features/user-guide' }, + { + label: 'Analysis', + items: [ + { label: 'I-Chart', slug: '03-features/analysis/i-chart' }, + { label: 'Boxplot', slug: '03-features/analysis/boxplot' }, + { label: 'Pareto', slug: '03-features/analysis/pareto' }, + { + label: 'Capability', + slug: '03-features/analysis/capability', + }, + { + label: 'Probability Plot', + slug: '03-features/analysis/probability-plot', + }, + { + label: 'Performance Mode', + slug: '03-features/analysis/performance-mode', + }, + { + label: 'Nelson Rules', + slug: '03-features/analysis/nelson-rules', + }, + { + label: 'Staged Analysis', + slug: '03-features/analysis/staged-analysis', + }, + ], + }, + { + label: 'Workflows', + items: [ + { label: 'Overview', slug: '03-features/workflows' }, + { + label: 'Process Maps', + slug: '03-features/workflows/process-maps', + }, + { + label: 'Four Lenses', + slug: '03-features/workflows/four-lenses-workflow', + }, + { + label: 'Drill-Down', + slug: '03-features/workflows/drill-down-workflow', + }, + { + label: 'Performance Mode', + slug: '03-features/workflows/performance-mode-workflow', + }, + { + label: 'Quick Check', + slug: '03-features/workflows/quick-check', + }, + { + label: 'Deep Dive', + slug: '03-features/workflows/deep-dive', + }, + { + label: 'Decision Trees', + slug: '03-features/workflows/decision-trees', + }, + { + label: 'Investigation to Action', + slug: '03-features/workflows/investigation-to-action', + }, + ], + }, + { + label: 'Navigation', + items: [ + { + label: 'Drill-Down', + slug: '03-features/navigation/drill-down', + }, + { + label: 'Linked Filtering', + slug: '03-features/navigation/linked-filtering', + }, + { + label: 'Breadcrumbs', + slug: '03-features/navigation/breadcrumbs', + }, + ], + }, + { + label: 'Data', + items: [ + { + label: 'Data Input', + slug: '03-features/data/data-input', + }, + { + label: 'Validation', + slug: '03-features/data/validation', + }, + { label: 'Storage', slug: '03-features/data/storage' }, + ], + }, + { + label: 'Learning', + items: [ + { + label: 'Glossary Feature', + slug: '03-features/learning/glossary', + }, + { + label: 'Help Tooltips', + slug: '03-features/learning/help-tooltips', + }, + { + label: 'Case-Based Learning', + slug: '03-features/learning/case-based-learning', + }, + ], + }, + ], + }, + + // ── Architecture ── + { + label: 'Architecture', + items: [ + { label: 'Overview', slug: '05-technical' }, + { label: 'Architecture', slug: '05-technical/architecture' }, + { + label: 'Structure', + items: [ + { + label: 'Monorepo', + slug: '05-technical/architecture/monorepo', + }, + { + label: 'Offline-First', + slug: '05-technical/architecture/offline-first', + }, + { + label: 'Shared Packages', + slug: '05-technical/architecture/shared-packages', + }, + { + label: 'Data Flow', + slug: '05-technical/architecture/data-flow', + }, + { + label: 'Component Patterns', + slug: '05-technical/architecture/component-patterns', + }, + ], + }, + { + label: 'Implementation', + items: [ + { + label: 'Deployment', + slug: '05-technical/implementation/deployment', + }, + { + label: 'Testing', + slug: '05-technical/implementation/testing', + }, + { + label: 'Data Input', + slug: '05-technical/implementation/data-input', + }, + { + label: 'System Limits', + slug: '05-technical/implementation/system-limits', + }, + { + label: 'Security Scanning', + slug: '05-technical/implementation/security-scanning', + }, + { + label: 'AI Tooling', + slug: '05-technical/implementation/ruflo', + }, + ], + }, + { + label: 'Integrations', + items: [ + { + label: 'Embed Messaging', + slug: '05-technical/integrations/embed-messaging', + }, + { + label: 'Shared UI', + slug: '05-technical/integrations/shared-ui', + }, + ], + }, + { + label: 'Design System', + items: [ + { label: 'Overview', slug: '06-design-system' }, + { + label: 'Foundations', + collapsed: true, + items: [ + { + label: 'Colors', + slug: '06-design-system/foundations/colors', + }, + { + label: 'Typography', + slug: '06-design-system/foundations/typography', + }, + { + label: 'Spacing', + slug: '06-design-system/foundations/spacing', + }, + { + label: 'Accessibility', + slug: '06-design-system/foundations/accessibility', + }, + ], + }, + { + label: 'Charts', + collapsed: true, + items: [ + { + label: 'Overview', + slug: '06-design-system/charts/overview', + }, + { + label: 'I-Chart', + slug: '06-design-system/charts/ichart', + }, + { + label: 'Boxplot', + slug: '06-design-system/charts/boxplot', + }, + { + label: 'Pareto', + slug: '06-design-system/charts/pareto', + }, + { + label: 'Capability', + slug: '06-design-system/charts/capability', + }, + { + label: 'Probability Plot', + slug: '06-design-system/charts/probability-plot', + }, + { + label: 'Performance Mode', + slug: '06-design-system/charts/performance-mode', + }, + { + label: 'Executive Mode', + slug: '06-design-system/charts/executive-mode', + }, + { + label: 'Colors', + slug: '06-design-system/charts/colors', + }, + { + label: 'Responsive', + slug: '06-design-system/charts/responsive', + }, + { + label: 'Hooks', + slug: '06-design-system/charts/hooks', + }, + { + label: 'Shared Components', + slug: '06-design-system/charts/shared-components', + }, + ], + }, + { + label: 'Components', + collapsed: true, + items: [ + { + label: 'Buttons', + slug: '06-design-system/components/buttons', + }, + { + label: 'Cards', + slug: '06-design-system/components/cards', + }, + { + label: 'Modals', + slug: '06-design-system/components/modals', + }, + { + label: 'Forms', + slug: '06-design-system/components/forms', + }, + { + label: 'Variation Funnel', + slug: '06-design-system/components/variation-funnel', + }, + { + label: 'What-If Simulator', + slug: '06-design-system/components/what-if-simulator', + }, + ], + }, + { + label: 'Patterns', + collapsed: true, + items: [ + { + label: 'Layout', + slug: '06-design-system/patterns/layout', + }, + { + label: 'Feedback', + slug: '06-design-system/patterns/feedback', + }, + { + label: 'Navigation', + slug: '06-design-system/patterns/navigation', + }, + ], + }, + ], + }, + { + label: 'Products', + items: [ + { label: 'Overview', slug: '08-products' }, + { + label: 'Feature Parity', + slug: '08-products/feature-parity', + }, + { + label: 'PWA', + collapsed: true, + items: [ + { label: 'Overview', slug: '08-products/pwa' }, + { label: 'Storage', slug: '08-products/pwa/storage' }, + ], + }, + { + label: 'Azure', + collapsed: true, + items: [ + { label: 'Overview', slug: '08-products/azure' }, + { + label: 'How It Works', + slug: '08-products/azure/how-it-works', + }, + { + label: 'Authentication', + slug: '08-products/azure/authentication', + }, + { + label: 'OneDrive Sync', + slug: '08-products/azure/onedrive-sync', + }, + { + label: 'Marketplace', + slug: '08-products/azure/marketplace', + }, + { + label: 'ARM Template', + slug: '08-products/azure/arm-template', + }, + { + label: 'Pricing Tiers', + slug: '08-products/azure/pricing-tiers', + }, + { + label: 'Submission Checklist', + slug: '08-products/azure/submission-checklist', + }, + ], + }, + { + label: 'Power BI', + collapsed: true, + items: [{ label: 'Overview', slug: '08-products/powerbi' }], + }, + { + label: 'Website', + collapsed: true, + items: [ + { label: 'Overview', slug: '08-products/website' }, + { + label: 'Design Philosophy', + slug: '08-products/website/design-philosophy', + }, + { + label: 'Content Architecture', + slug: '08-products/website/content-architecture', + }, + ], + }, + ], + }, + ], + }, + + // ── Decisions ── + { + label: 'Decisions', + items: [ + { label: 'Overview', slug: '07-decisions' }, + { label: 'ADR-001 Monorepo', slug: '07-decisions/adr-001-monorepo' }, + { + label: 'ADR-002 Visx Charts', + slug: '07-decisions/adr-002-visx-charts', + }, + { + label: 'ADR-003 IndexedDB', + slug: '07-decisions/adr-003-indexeddb', + }, + { + label: 'ADR-004 Offline-First', + slug: '07-decisions/adr-004-offline-first', + }, + { + label: 'ADR-005 Props-Based Charts', + slug: '07-decisions/adr-005-props-based-charts', + }, + { + label: 'ADR-006 Edition System', + slug: '07-decisions/adr-006-edition-system', + }, + { + label: 'ADR-007 Azure Distribution', + slug: '07-decisions/adr-007-azure-marketplace-distribution', + }, + { + label: 'ADR-008 Website Content', + slug: '07-decisions/adr-008-website-content-architecture', + }, + { + label: 'ADR-009 Violin Mode', + slug: '07-decisions/adr-009-boxplot-violin-mode', + }, + { + label: 'ADR-010 Gage R&R', + slug: '07-decisions/adr-010-gagerr-deferral', + }, + { + label: 'ADR-011 AI Tooling', + slug: '07-decisions/adr-011-ai-development-tooling', + }, + { + label: 'ADR-012 PWA Browser', + slug: '07-decisions/adr-012-pwa-browser-only', + }, + { + label: 'ADR-013 Architecture Eval', + slug: '07-decisions/adr-013-architecture-evaluation-ddd-swarms', + }, + { + label: 'Product Audit Feb 2026', + slug: '07-decisions/audit-2026-02-state-of-product', + }, + ], + }, + + // ── External Links ── + { + label: 'Tools', + items: [ + { + label: 'Storybook', + link: 'http://localhost:6006', + attrs: { target: '_blank' }, + }, + ], + }, + ], + }), + ], + vite: { + ssr: { + noExternal: ['zod'], + }, + }, + markdown: { + rehypePlugins: [ + [ + rehypeMermaid, + { + strategy: 'pre-mermaid', + }, + ], + ], + }, +}); diff --git a/apps/docs/package.json b/apps/docs/package.json new file mode 100644 index 000000000..5e6be4fab --- /dev/null +++ b/apps/docs/package.json @@ -0,0 +1,17 @@ +{ + "name": "@variscout/docs", + "type": "module", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview" + }, + "dependencies": { + "@astrojs/starlight": "^0.34.0", + "astro": "^5.10.0", + "rehype-mermaid": "^3.0.0", + "sharp": "^0.33.0" + } +} diff --git a/apps/docs/src/content.config.ts b/apps/docs/src/content.config.ts new file mode 100644 index 000000000..ab4db096f --- /dev/null +++ b/apps/docs/src/content.config.ts @@ -0,0 +1,10 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ + loader: docsLoader(), + schema: docsSchema(), + }), +}; diff --git a/apps/docs/src/content/docs b/apps/docs/src/content/docs new file mode 120000 index 000000000..ac19935a4 --- /dev/null +++ b/apps/docs/src/content/docs @@ -0,0 +1 @@ +../../../../docs \ No newline at end of file diff --git a/apps/docs/src/styles/custom.css b/apps/docs/src/styles/custom.css new file mode 100644 index 000000000..042200942 --- /dev/null +++ b/apps/docs/src/styles/custom.css @@ -0,0 +1,118 @@ +/* VariScout Documentation Custom Styles for Starlight */ + +:root { + --sl-color-accent-low: #1e3a5f; + --sl-color-accent: #3b82f6; + --sl-color-accent-high: #93c5fd; +} + +/* Status colors for documentation */ +.pass { + color: #22c55e; +} + +.fail { + color: #ef4444; +} + +.warning { + color: #f59e0b; +} + +/* Mermaid diagram sizing */ +.mermaid, +pre.mermaid { + text-align: center; +} + +/* Table styling for better readability */ +table:not([class]) { + font-size: 0.85rem; +} + +/* Code block improvements */ +pre > code { + font-size: 0.8rem; +} + +/* Process map component (carried over from MkDocs) */ +.process-map { + display: flex; + align-items: flex-start; + gap: 0; + overflow-x: auto; + padding: 1rem 0 0.5rem; + -webkit-overflow-scrolling: touch; +} + +.process-step { + display: flex; + flex-direction: column; + align-items: center; + flex-shrink: 0; + min-width: 140px; + max-width: 180px; +} + +.process-step__box { + border: 1px solid var(--sl-color-gray-5); + border-left: 4px solid var(--sl-color-gray-4); + border-radius: 6px; + padding: 0.6rem 0.75rem; + background: var(--sl-color-gray-6); + width: 100%; + text-align: center; +} + +.process-step__title { + font-weight: 700; + font-size: 0.8rem; + color: var(--sl-color-white); + line-height: 1.3; +} + +.process-step__detail { + font-size: 0.7rem; + color: var(--sl-color-gray-3); + margin-top: 0.2rem; + line-height: 1.3; +} + +.process-arrow { + display: flex; + align-items: center; + padding: 0 0.15rem; + flex-shrink: 0; + margin-top: 1.2rem; +} + +.process-arrow::after { + content: '\2192'; + color: var(--sl-color-gray-4); + font-size: 1.1rem; + font-weight: 700; +} + +/* Color swatch for design system docs */ +.color-swatch { + display: inline-block; + width: 20px; + height: 20px; + border-radius: 4px; + vertical-align: middle; + margin-right: 8px; + border: 1px solid rgba(128, 128, 128, 0.3); +} + +@media (max-width: 768px) { + .process-step { + min-width: 120px; + max-width: 150px; + } + .process-step__title { + font-size: 0.75rem; + } + .process-step__detail { + font-size: 0.65rem; + } +} diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json new file mode 100644 index 000000000..bcbf8b509 --- /dev/null +++ b/apps/docs/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "astro/tsconfigs/strict" +} diff --git a/docs/01-vision/evaluations/bottleneck-flow-map.md b/docs/01-vision/evaluations/bottleneck-flow-map.md index af3408a66..ece645cb0 100644 --- a/docs/01-vision/evaluations/bottleneck-flow-map.md +++ b/docs/01-vision/evaluations/bottleneck-flow-map.md @@ -1,3 +1,7 @@ +--- +title: 'Investigation Flow Map: Bottleneck Detection' +--- + # Investigation Flow Map: Bottleneck Detection > A step-by-step walkthrough of a complete variation investigation using the Bottleneck dataset, documenting what exists at each step, what guidance the analyst receives, and where gaps remain. Follows the [Pizza Delivery flow map](investigation-flow-map.md) format. diff --git a/docs/01-vision/evaluations/competitive/edascout-benchmark.md b/docs/01-vision/evaluations/competitive/edascout-benchmark.md index 620d54e8d..31f7e4234 100644 --- a/docs/01-vision/evaluations/competitive/edascout-benchmark.md +++ b/docs/01-vision/evaluations/competitive/edascout-benchmark.md @@ -1,3 +1,7 @@ +--- +title: 'EDAScout Competitive Benchmark' +--- + # EDAScout Competitive Benchmark > Competitive intelligence from analysis of EDAScout v4, v6, v7, and v9 codebases. diff --git a/docs/01-vision/evaluations/competitive/jmp-benchmark.md b/docs/01-vision/evaluations/competitive/jmp-benchmark.md index 0f36fbc74..89ab0957a 100644 --- a/docs/01-vision/evaluations/competitive/jmp-benchmark.md +++ b/docs/01-vision/evaluations/competitive/jmp-benchmark.md @@ -1,3 +1,7 @@ +--- +title: 'JMP Competitive Benchmark' +--- + # JMP Competitive Benchmark > Based on public documentation, published feature sets, and market positioning knowledge. Unlike the [EDAScout Benchmark](edascout-benchmark.md), this assessment does not include direct codebase analysis. diff --git a/docs/01-vision/evaluations/competitive/minitab-benchmark.md b/docs/01-vision/evaluations/competitive/minitab-benchmark.md index 043de9f13..493d9da2a 100644 --- a/docs/01-vision/evaluations/competitive/minitab-benchmark.md +++ b/docs/01-vision/evaluations/competitive/minitab-benchmark.md @@ -1,3 +1,7 @@ +--- +title: 'Minitab Competitive Benchmark' +--- + # Minitab Competitive Benchmark > Based on public documentation, published feature sets, and market positioning knowledge. Unlike the [EDAScout Benchmark](edascout-benchmark.md), this assessment does not include direct codebase analysis. diff --git a/docs/01-vision/evaluations/competitive/minor-competitors.md b/docs/01-vision/evaluations/competitive/minor-competitors.md index 0dea3a91e..561a90fee 100644 --- a/docs/01-vision/evaluations/competitive/minor-competitors.md +++ b/docs/01-vision/evaluations/competitive/minor-competitors.md @@ -1,3 +1,7 @@ +--- +title: 'Minor Competitor Profiles' +--- + # Minor Competitor Profiles > Based on public documentation and published feature sets. These competitors appear in only 1–2 pattern evaluations and do not warrant full benchmark documents. diff --git a/docs/01-vision/evaluations/competitive/powerbi-benchmark.md b/docs/01-vision/evaluations/competitive/powerbi-benchmark.md index 1c17d83b6..9fecc6cd2 100644 --- a/docs/01-vision/evaluations/competitive/powerbi-benchmark.md +++ b/docs/01-vision/evaluations/competitive/powerbi-benchmark.md @@ -1,3 +1,7 @@ +--- +title: 'Power BI Competitive Benchmark' +--- + # Power BI Competitive Benchmark > Based on public documentation, published feature sets, and market positioning knowledge. Unlike the [EDAScout Benchmark](edascout-benchmark.md), this assessment does not include direct codebase analysis. diff --git a/docs/01-vision/evaluations/competitive/tableau-benchmark.md b/docs/01-vision/evaluations/competitive/tableau-benchmark.md index 1523d8590..6dbc16504 100644 --- a/docs/01-vision/evaluations/competitive/tableau-benchmark.md +++ b/docs/01-vision/evaluations/competitive/tableau-benchmark.md @@ -1,3 +1,7 @@ +--- +title: 'Tableau Competitive Benchmark' +--- + # Tableau Competitive Benchmark > Based on public documentation, published feature sets, and market positioning knowledge. Unlike the [EDAScout Benchmark](edascout-benchmark.md), this assessment does not include direct codebase analysis. diff --git a/docs/01-vision/evaluations/design-brief-guided-investigation.md b/docs/01-vision/evaluations/design-brief-guided-investigation.md index b07a930c8..056248f97 100644 --- a/docs/01-vision/evaluations/design-brief-guided-investigation.md +++ b/docs/01-vision/evaluations/design-brief-guided-investigation.md @@ -1,3 +1,7 @@ +--- +title: 'Design Brief: Guided Investigation' +--- + # Design Brief: Guided Investigation > **Historical document** — this design brief led to the Investigation Mindmap (Phases A-D). diff --git a/docs/01-vision/evaluations/design-spec-investigation-mindmap.md b/docs/01-vision/evaluations/design-spec-investigation-mindmap.md index c2a157d2e..a286a0218 100644 --- a/docs/01-vision/evaluations/design-spec-investigation-mindmap.md +++ b/docs/01-vision/evaluations/design-spec-investigation-mindmap.md @@ -1,3 +1,7 @@ +--- +title: 'Design Spec: Investigation Mindmap' +--- + # Design Spec: Investigation Mindmap > Authoritative design specification for the Mindmap-first investigation UX. Consolidates four concept documents into a three-layer architecture that replaces the Funnel Panel ecosystem with one spatial view. diff --git a/docs/01-vision/evaluations/hospital-ward-flow-map.md b/docs/01-vision/evaluations/hospital-ward-flow-map.md index 382e2e7df..42a800266 100644 --- a/docs/01-vision/evaluations/hospital-ward-flow-map.md +++ b/docs/01-vision/evaluations/hospital-ward-flow-map.md @@ -1,3 +1,7 @@ +--- +title: 'Investigation Flow Map: Hospital Ward (Aggregation Trap)' +--- + # Investigation Flow Map: Hospital Ward (Aggregation Trap) > A step-by-step walkthrough of a complete variation investigation using the Hospital Ward dataset, documenting what exists at each step, what guidance the analyst receives, and where gaps remain. Follows the [Pizza Delivery flow map](investigation-flow-map.md) format. diff --git a/docs/01-vision/evaluations/index.md b/docs/01-vision/evaluations/index.md index c584d8243..947ed1d70 100644 --- a/docs/01-vision/evaluations/index.md +++ b/docs/01-vision/evaluations/index.md @@ -1,3 +1,7 @@ +--- +title: 'Evaluations: Progressive Stratification Tensions & Patterns' +--- + # Evaluations: Progressive Stratification Tensions & Patterns Product strategy evaluations for the design tensions and alternative patterns identified in [Progressive Stratification](../progressive-stratification.md) Part 2. Each evaluation assesses fit against VariScout's philosophy, personas, and competitive positioning. diff --git a/docs/01-vision/evaluations/investigation-flow-map.md b/docs/01-vision/evaluations/investigation-flow-map.md index 64186397a..98258c1b4 100644 --- a/docs/01-vision/evaluations/investigation-flow-map.md +++ b/docs/01-vision/evaluations/investigation-flow-map.md @@ -1,3 +1,7 @@ +--- +title: 'Investigation Flow Map: Pizza Delivery' +--- + # Investigation Flow Map: Pizza Delivery > **Historical document** — describes the pre-Mindmap investigation flow using FunnelPanel. diff --git a/docs/01-vision/evaluations/mindmap-chrome-evaluation.md b/docs/01-vision/evaluations/mindmap-chrome-evaluation.md index 4ca914422..b441929b5 100644 --- a/docs/01-vision/evaluations/mindmap-chrome-evaluation.md +++ b/docs/01-vision/evaluations/mindmap-chrome-evaluation.md @@ -1,3 +1,7 @@ +--- +title: 'Chrome Evaluation: Mindmap with Bottleneck & Hospital Ward' +--- + # Chrome Evaluation: Mindmap with Bottleneck & Hospital Ward > Automated Playwright evaluation (13 tests, all passing) of the Investigation Mindmap panel with both Bottleneck and Hospital Ward case study datasets. Evaluates how the Mindmap contributes to the investigation workflow, documenting working features, UX gaps, and bugs. Screenshots in `apps/pwa/e2e/screenshots/mindmap-eval/`. E2E spec: `apps/pwa/e2e/mindmap-evaluation.spec.ts`. diff --git a/docs/01-vision/evaluations/patterns/auto-combination-finder.md b/docs/01-vision/evaluations/patterns/auto-combination-finder.md index 1b0d53a35..3a114cce2 100644 --- a/docs/01-vision/evaluations/patterns/auto-combination-finder.md +++ b/docs/01-vision/evaluations/patterns/auto-combination-finder.md @@ -1,3 +1,7 @@ +--- +title: 'Auto-Combination Finder' +--- + # Auto-Combination Finder > Use the regression engine to identify the highest-impact 2--3 filter combination automatically. diff --git a/docs/01-vision/evaluations/patterns/factor-map.md b/docs/01-vision/evaluations/patterns/factor-map.md index 09bea368a..af03b52d3 100644 --- a/docs/01-vision/evaluations/patterns/factor-map.md +++ b/docs/01-vision/evaluations/patterns/factor-map.md @@ -1,3 +1,7 @@ +--- +title: 'Factor Map' +--- + # Factor Map > A network visualization of the factor landscape showing factors as nodes, values as branches, and interactions as connections. diff --git a/docs/01-vision/evaluations/patterns/factor-suggestion.md b/docs/01-vision/evaluations/patterns/factor-suggestion.md index 217381088..9a7bb29a4 100644 --- a/docs/01-vision/evaluations/patterns/factor-suggestion.md +++ b/docs/01-vision/evaluations/patterns/factor-suggestion.md @@ -1,3 +1,7 @@ +--- +title: 'Factor Suggestion' +--- + # Factor Suggestion > After each filter, highlight the next highest-impact factor to reduce analyst guesswork. diff --git a/docs/01-vision/evaluations/patterns/interaction-heatmap.md b/docs/01-vision/evaluations/patterns/interaction-heatmap.md index 5f3e75008..589881a44 100644 --- a/docs/01-vision/evaluations/patterns/interaction-heatmap.md +++ b/docs/01-vision/evaluations/patterns/interaction-heatmap.md @@ -1,3 +1,7 @@ +--- +title: 'Interaction Heatmap' +--- + # Interaction Heatmap > A small matrix visualization showing factor-by-factor interaction strength before drilling. diff --git a/docs/01-vision/evaluations/patterns/investigation-mindmap.md b/docs/01-vision/evaluations/patterns/investigation-mindmap.md index 079842183..b348e96aa 100644 --- a/docs/01-vision/evaluations/patterns/investigation-mindmap.md +++ b/docs/01-vision/evaluations/patterns/investigation-mindmap.md @@ -1,3 +1,7 @@ +--- +title: 'Investigation Mindmap' +--- + # Investigation Mindmap > A two-mode companion visualization — drilldown overview and interaction view — that opens on demand in a separate window or panel, showing the investigation state as an interactive node-link diagram. diff --git a/docs/01-vision/evaluations/patterns/investigation-narrative.md b/docs/01-vision/evaluations/patterns/investigation-narrative.md index 14c898b39..e967ca445 100644 --- a/docs/01-vision/evaluations/patterns/investigation-narrative.md +++ b/docs/01-vision/evaluations/patterns/investigation-narrative.md @@ -1,3 +1,7 @@ +--- +title: 'Investigation Narrative' +--- + # Investigation Narrative > A presentation mode that transforms the investigation path into a visual story for stakeholders — showing what was found, in what order, and why it matters. diff --git a/docs/01-vision/evaluations/patterns/parallel-path-comparison.md b/docs/01-vision/evaluations/patterns/parallel-path-comparison.md index d860a6a57..a31f6f8d5 100644 --- a/docs/01-vision/evaluations/patterns/parallel-path-comparison.md +++ b/docs/01-vision/evaluations/patterns/parallel-path-comparison.md @@ -1,3 +1,7 @@ +--- +title: 'Parallel Path Comparison' +--- + # Parallel Path Comparison > Show alternative drill paths and whether they converge on the same finding. diff --git a/docs/01-vision/evaluations/patterns/sidebar-filter-panel.md b/docs/01-vision/evaluations/patterns/sidebar-filter-panel.md index e173211fa..5f6f75a87 100644 --- a/docs/01-vision/evaluations/patterns/sidebar-filter-panel.md +++ b/docs/01-vision/evaluations/patterns/sidebar-filter-panel.md @@ -1,3 +1,7 @@ +--- +title: 'Sidebar Filter Panel' +--- + # Sidebar Filter Panel > An always-visible panel listing all factors with checkboxes and sliders, Tableau-style. diff --git a/docs/01-vision/evaluations/patterns/small-multiples.md b/docs/01-vision/evaluations/patterns/small-multiples.md index b7182c569..348a354b5 100644 --- a/docs/01-vision/evaluations/patterns/small-multiples.md +++ b/docs/01-vision/evaluations/patterns/small-multiples.md @@ -1,3 +1,7 @@ +--- +title: 'Small Multiples' +--- + # Small Multiples > Show all factor-by-value combinations as a grid of mini-charts. diff --git a/docs/01-vision/evaluations/tensions/discoverability.md b/docs/01-vision/evaluations/tensions/discoverability.md index 451c152bb..9426f7050 100644 --- a/docs/01-vision/evaluations/tensions/discoverability.md +++ b/docs/01-vision/evaluations/tensions/discoverability.md @@ -1,3 +1,7 @@ +--- +title: 'Discoverability' +--- + # Discoverability > The entire progressive stratification system starts with clicking a boxplot bar --- if the analyst doesn't know to click, the most powerful feature is invisible. diff --git a/docs/01-vision/evaluations/tensions/factor-ordering.md b/docs/01-vision/evaluations/tensions/factor-ordering.md index 626163b05..8029b30cb 100644 --- a/docs/01-vision/evaluations/tensions/factor-ordering.md +++ b/docs/01-vision/evaluations/tensions/factor-ordering.md @@ -1,3 +1,7 @@ +--- +title: 'Factor Ordering' +--- + # Factor Ordering > The analyst chooses which factor to drill next --- there's a tension between guided and exploratory interaction. diff --git a/docs/01-vision/evaluations/tensions/hierarchy-assumption.md b/docs/01-vision/evaluations/tensions/hierarchy-assumption.md index e20b395e0..eb269c5fd 100644 --- a/docs/01-vision/evaluations/tensions/hierarchy-assumption.md +++ b/docs/01-vision/evaluations/tensions/hierarchy-assumption.md @@ -1,3 +1,7 @@ +--- +title: 'Hierarchy Assumption' +--- + # Hierarchy Assumption > The sequential one-factor-at-a-time drill-down captures main effects but may miss interaction effects between factors. diff --git a/docs/01-vision/evaluations/tensions/mobile-screen-budget.md b/docs/01-vision/evaluations/tensions/mobile-screen-budget.md index cb09824dc..8d97a13f6 100644 --- a/docs/01-vision/evaluations/tensions/mobile-screen-budget.md +++ b/docs/01-vision/evaluations/tensions/mobile-screen-budget.md @@ -1,3 +1,7 @@ +--- +title: 'Mobile Screen Budget' +--- + # Mobile Screen Budget > Filter chips, the variation bar, and four charts all compete for screen space on mobile. diff --git a/docs/01-vision/evaluations/tensions/path-dependency.md b/docs/01-vision/evaluations/tensions/path-dependency.md index 848277816..fef6e00e7 100644 --- a/docs/01-vision/evaluations/tensions/path-dependency.md +++ b/docs/01-vision/evaluations/tensions/path-dependency.md @@ -1,3 +1,7 @@ +--- +title: 'Path Dependency' +--- + # Path Dependency > The order you drill matters for intermediate contribution percentages, even though final results converge. diff --git a/docs/01-vision/evaluations/tensions/when-to-stop.md b/docs/01-vision/evaluations/tensions/when-to-stop.md index d5578ca18..86bb89409 100644 --- a/docs/01-vision/evaluations/tensions/when-to-stop.md +++ b/docs/01-vision/evaluations/tensions/when-to-stop.md @@ -1,3 +1,7 @@ +--- +title: 'When to Stop' +--- + # When to Stop > Statistical explanation and actionability aren't the same thing --- isolating variation doesn't mean you can fix it. diff --git a/docs/01-vision/four-lenses/change.md b/docs/01-vision/four-lenses/change.md index 52e336567..f802fb35c 100644 --- a/docs/01-vision/four-lenses/change.md +++ b/docs/01-vision/four-lenses/change.md @@ -1,3 +1,7 @@ +--- +title: 'CHANGE Lens: I-Chart' +--- + # CHANGE Lens: I-Chart > The Adaptive Lens — look at the same data through time diff --git a/docs/01-vision/four-lenses/drilldown.md b/docs/01-vision/four-lenses/drilldown.md index b3b2222a7..9857154e6 100644 --- a/docs/01-vision/four-lenses/drilldown.md +++ b/docs/01-vision/four-lenses/drilldown.md @@ -1,3 +1,7 @@ +--- +title: 'Drill-Down: Progressive Variation Analysis' +--- + # Drill-Down: Progressive Variation Analysis The drill-down methodology is the heart of VariScout's approach to finding where variation hides. @@ -61,11 +65,13 @@ Each chip shows contribution % to TOTAL variation (not local η²). ## Cumulative Variation Tracking -!!! methodology "The Power of Filter Chips" +:::note[The Power of Filter Chips] This is the killer insight of the entire methodology. Filter chips aren't just navigation — they show **contribution to TOTAL variation** that tells you exactly how much of your total problem you've isolated. +::: -!!! warning "Important Terminology" +:::caution[Important Terminology] VariScout identifies **factors driving variation**, not "root causes." EDA shows _which_ factors explain variation — the _why_ requires further investigation (5 Whys, experimentation, Gemba walks). This distinction matters: we quantify contribution, not causation. +::: ### The Math Behind Contribution % diff --git a/docs/01-vision/four-lenses/failure.md b/docs/01-vision/four-lenses/failure.md index 145fb268b..96d11f2ee 100644 --- a/docs/01-vision/four-lenses/failure.md +++ b/docs/01-vision/four-lenses/failure.md @@ -1,3 +1,7 @@ +--- +title: 'FAILURE Lens: Pareto' +--- + # FAILURE Lens: Pareto > The Integrity Lens — look at where problems concentrate diff --git a/docs/01-vision/four-lenses/flow.md b/docs/01-vision/four-lenses/flow.md index 26f5e97bb..548613b65 100644 --- a/docs/01-vision/four-lenses/flow.md +++ b/docs/01-vision/four-lenses/flow.md @@ -1,3 +1,7 @@ +--- +title: 'FLOW Lens: Boxplot' +--- + # FLOW Lens: Boxplot > The Structural Lens — look at the same data grouped by factor diff --git a/docs/01-vision/four-lenses/index.md b/docs/01-vision/four-lenses/index.md index ca8534047..7e1fb3a79 100644 --- a/docs/01-vision/four-lenses/index.md +++ b/docs/01-vision/four-lenses/index.md @@ -1,3 +1,7 @@ +--- +title: "Watson's Four Lenses of Process Knowledge" +--- + # Watson's Four Lenses of Process Knowledge > "VariScout doesn't just display charts — it gives you four lenses to see what averages hide." @@ -29,8 +33,9 @@ VariScout's four core charts aren't random statistical outputs. Each chart direc | -------------- | ----------------- | ----------------------------------------------- | | **Regression** | Correlation Check | "Is there even a relationship between X and Y?" | -!!! note +:::note Regression in VariScout serves as a **first step** to visually check if correlation exists between two continuous variables. It answers "is there a relationship?" before investing in deeper predictive modeling. For most variation analysis, the Four Lenses are sufficient. +::: --- diff --git a/docs/01-vision/four-lenses/value.md b/docs/01-vision/four-lenses/value.md index 76eaece26..6df80a796 100644 --- a/docs/01-vision/four-lenses/value.md +++ b/docs/01-vision/four-lenses/value.md @@ -1,3 +1,7 @@ +--- +title: 'VALUE Lens: Capability Histogram' +--- + # VALUE Lens: Capability Histogram > The Alignment Lens — a different type of question diff --git a/docs/01-vision/index.md b/docs/01-vision/index.md index 41a6d6143..6beca9ad6 100644 --- a/docs/01-vision/index.md +++ b/docs/01-vision/index.md @@ -1,3 +1,7 @@ +--- +title: 'Vision & Methodology' +--- + # Vision & Methodology VariScout is built on a philosophy of **EDA for process improvement** — not statistical verification. diff --git a/docs/01-vision/market-analysis.md b/docs/01-vision/market-analysis.md index e8e7033a9..d12b7d909 100644 --- a/docs/01-vision/market-analysis.md +++ b/docs/01-vision/market-analysis.md @@ -1,3 +1,7 @@ +--- +title: 'Market Analysis & TAM Estimate' +--- + # Market Analysis & TAM Estimate _Last updated: February 2026_ @@ -43,8 +47,9 @@ VariScout doesn't compete with the full Minitab suite (DOE, hypothesis testing, | Convert to paid after training | ~10–20% | Most use the free PWA | | **TAM (Layer 2)** | **~€5–15M/year** | Corporate upgrades to Azure App | -!!! note +:::note Most training revenue comes from the **free PWA** driving awareness, not direct sales. The TAM here flows from corporate training departments that upgrade to Azure App for internal use after discovering VariScout through training. +::: ### Layer 3 — Excel-Native Quality Analytics (Tertiary) diff --git a/docs/01-vision/philosophy.md b/docs/01-vision/philosophy.md index c7256f054..c522f26e6 100644 --- a/docs/01-vision/philosophy.md +++ b/docs/01-vision/philosophy.md @@ -1,3 +1,7 @@ +--- +title: 'EDA for Process Improvement' +--- + # EDA for Process Improvement VariScout is **Exploratory Data Analysis (EDA) for process improvement** — not statistical verification. diff --git a/docs/01-vision/product-overview.md b/docs/01-vision/product-overview.md index d0112371b..76d2cd74c 100644 --- a/docs/01-vision/product-overview.md +++ b/docs/01-vision/product-overview.md @@ -1,3 +1,7 @@ +--- +title: 'VariScout: Product Overview' +--- + # VariScout: Product Overview ## Philosophy diff --git a/docs/01-vision/progressive-stratification.md b/docs/01-vision/progressive-stratification.md index f212db7ec..3bcebecf6 100644 --- a/docs/01-vision/progressive-stratification.md +++ b/docs/01-vision/progressive-stratification.md @@ -1,3 +1,7 @@ +--- +title: 'Progressive Stratification' +--- + # Progressive Stratification Why VariScout's filter chip drill-down is the right interaction model for variation analysis --- and where it might not be. diff --git a/docs/01-vision/two-voices/control-limits.md b/docs/01-vision/two-voices/control-limits.md index d83395953..fa208d73a 100644 --- a/docs/01-vision/two-voices/control-limits.md +++ b/docs/01-vision/two-voices/control-limits.md @@ -1,3 +1,7 @@ +--- +title: 'Voice of the Process: Control Limits' +--- + # Voice of the Process: Control Limits --- diff --git a/docs/01-vision/two-voices/index.md b/docs/01-vision/two-voices/index.md index 8662e2165..d4d6642d6 100644 --- a/docs/01-vision/two-voices/index.md +++ b/docs/01-vision/two-voices/index.md @@ -1,3 +1,7 @@ +--- +title: 'Two Voices: Control Limits vs Specification Limits' +--- + # Two Voices: Control Limits vs Specification Limits > A VariScout educational resource based on ITC Quality Control principles diff --git a/docs/01-vision/two-voices/scenarios.md b/docs/01-vision/two-voices/scenarios.md index d9a054806..985433858 100644 --- a/docs/01-vision/two-voices/scenarios.md +++ b/docs/01-vision/two-voices/scenarios.md @@ -1,3 +1,7 @@ +--- +title: "Four Scenarios: When the Voices Align (or Don't)" +--- + # Four Scenarios: When the Voices Align (or Don't) --- @@ -98,8 +102,9 @@ LSL ━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ "Is that point within our control limits? If yes, it's normal variation — don't adjust. If no, find out why." -!!! warning +:::caution **Tampering with a stable process increases variation.** +::: --- diff --git a/docs/01-vision/two-voices/spec-limits.md b/docs/01-vision/two-voices/spec-limits.md index 9eabec1e5..087faca3b 100644 --- a/docs/01-vision/two-voices/spec-limits.md +++ b/docs/01-vision/two-voices/spec-limits.md @@ -1,3 +1,7 @@ +--- +title: 'Voice of the Customer: Specification Limits' +--- + # Voice of the Customer: Specification Limits --- diff --git a/docs/01-vision/two-voices/variation-types.md b/docs/01-vision/two-voices/variation-types.md index f0513ef1e..487931a91 100644 --- a/docs/01-vision/two-voices/variation-types.md +++ b/docs/01-vision/two-voices/variation-types.md @@ -1,3 +1,7 @@ +--- +title: 'Two Types of Variation, Two Types of Action' +--- + # Two Types of Variation, Two Types of Action The I-Chart reveals patterns — but what you DO about them depends on what TYPE of variation you're seeing. @@ -75,8 +79,9 @@ Traditional SPC treats all special causes as "investigate and remove." Direction | **Special cause present** | Points outside limits, patterns | Find and remove the cause (local action) | | **Stable but not capable** | All points within limits, BUT limits outside specs | Reduce common cause variation (system action) | -!!! warning "The Trap" +:::caution[The Trap] When a process is stable but not capable, local actions won't help. "Trying harder" or adjusting individual points just adds variation. The **system itself** must change. +::: --- diff --git a/docs/02-journeys/flows/azure-daily-use.md b/docs/02-journeys/flows/azure-daily-use.md index e7296124b..aede44b02 100644 --- a/docs/02-journeys/flows/azure-daily-use.md +++ b/docs/02-journeys/flows/azure-daily-use.md @@ -1,3 +1,7 @@ +--- +title: 'Flow 7: Azure App — Daily Use' +--- + # Flow 7: Azure App — Daily Use > Green Belt Gary's daily workflow: repeat analysis, Performance Mode, exports diff --git a/docs/02-journeys/flows/azure-first-analysis.md b/docs/02-journeys/flows/azure-first-analysis.md index 2176a9b65..778ef6aab 100644 --- a/docs/02-journeys/flows/azure-first-analysis.md +++ b/docs/02-journeys/flows/azure-first-analysis.md @@ -1,3 +1,7 @@ +--- +title: 'Flow 6: Azure App — First Analysis' +--- + # Flow 6: Azure App — First Analysis > Green Belt Gary runs his first analysis in the Azure App diff --git a/docs/02-journeys/flows/azure-team-collaboration.md b/docs/02-journeys/flows/azure-team-collaboration.md index 3f8cf7c41..0d91074a2 100644 --- a/docs/02-journeys/flows/azure-team-collaboration.md +++ b/docs/02-journeys/flows/azure-team-collaboration.md @@ -1,3 +1,7 @@ +--- +title: 'Flow 8: Azure App — Team Collaboration' +--- + # Flow 8: Azure App — Team Collaboration > OpEx Olivia deploys VariScout for her team and sets up sharing diff --git a/docs/02-journeys/flows/azure-teams-mobile.md b/docs/02-journeys/flows/azure-teams-mobile.md index f5ad437c2..7db1c4562 100644 --- a/docs/02-journeys/flows/azure-teams-mobile.md +++ b/docs/02-journeys/flows/azure-teams-mobile.md @@ -1,3 +1,7 @@ +--- +title: 'Azure Teams Mobile Flow' +--- + # Azure Teams Mobile Flow How quality engineers use VariScout on their phones via the Teams mobile app. diff --git a/docs/02-journeys/flows/content-youtube.md b/docs/02-journeys/flows/content-youtube.md index a7fc620ad..ff7a39fae 100644 --- a/docs/02-journeys/flows/content-youtube.md +++ b/docs/02-journeys/flows/content-youtube.md @@ -1,3 +1,7 @@ +--- +title: 'Flow 3: YouTube/Content → Website → Product' +--- + # Flow 3: YouTube/Content → Website → Product > Curious Carlos discovers VaRiScout through content, builds trust, converts diff --git a/docs/02-journeys/flows/enterprise.md b/docs/02-journeys/flows/enterprise.md index bf334b466..29acb5a9d 100644 --- a/docs/02-journeys/flows/enterprise.md +++ b/docs/02-journeys/flows/enterprise.md @@ -1,3 +1,7 @@ +--- +title: 'Flow 4: Enterprise Evaluator' +--- + # Flow 4: Enterprise Evaluator > OpEx Olivia evaluates VaRiScout for her team via self-serve journey diff --git a/docs/02-journeys/flows/return-visitor.md b/docs/02-journeys/flows/return-visitor.md index 43399fb82..ed975e00d 100644 --- a/docs/02-journeys/flows/return-visitor.md +++ b/docs/02-journeys/flows/return-visitor.md @@ -1,3 +1,7 @@ +--- +title: 'Flow 5: Return Visitor → App' +--- + # Flow 5: Return Visitor → App > Existing user returns to use VaRiScout diff --git a/docs/02-journeys/flows/seo-learner.md b/docs/02-journeys/flows/seo-learner.md index eb05388b5..67a4edcfb 100644 --- a/docs/02-journeys/flows/seo-learner.md +++ b/docs/02-journeys/flows/seo-learner.md @@ -1,3 +1,7 @@ +--- +title: 'Flow 1: SEO Learner → Product' +--- + # Flow 1: SEO Learner → Product > Green Belt Gary searches Google, finds a tool page, discovers VaRiScout diff --git a/docs/02-journeys/flows/social-discovery.md b/docs/02-journeys/flows/social-discovery.md index f04f5de86..adcbbfad3 100644 --- a/docs/02-journeys/flows/social-discovery.md +++ b/docs/02-journeys/flows/social-discovery.md @@ -1,3 +1,7 @@ +--- +title: 'Flow 2: Social Discovery → Case → Product' +--- + # Flow 2: Social Discovery → Case → Product > Curious Carlos sees a LinkedIn post, explores a case study, discovers VaRiScout diff --git a/docs/02-journeys/index.md b/docs/02-journeys/index.md index aa8f1b821..7fc067d26 100644 --- a/docs/02-journeys/index.md +++ b/docs/02-journeys/index.md @@ -1,3 +1,7 @@ +--- +title: 'User Journeys' +--- + # User Journeys How different users find, navigate, and convert on VariScout. diff --git a/docs/02-journeys/personas/curious-carlos.md b/docs/02-journeys/personas/curious-carlos.md index 06c5bc333..409261ff8 100644 --- a/docs/02-journeys/personas/curious-carlos.md +++ b/docs/02-journeys/personas/curious-carlos.md @@ -1,3 +1,7 @@ +--- +title: 'Curious Carlos' +--- + # Curious Carlos | Attribute | Detail | diff --git a/docs/02-journeys/personas/evaluator-erik.md b/docs/02-journeys/personas/evaluator-erik.md index 00e247449..96f2b749c 100644 --- a/docs/02-journeys/personas/evaluator-erik.md +++ b/docs/02-journeys/personas/evaluator-erik.md @@ -1,3 +1,7 @@ +--- +title: 'Evaluator Erik' +--- + # Evaluator Erik | Attribute | Detail | diff --git a/docs/02-journeys/personas/field-fiona.md b/docs/02-journeys/personas/field-fiona.md index c63224f85..71876d08a 100644 --- a/docs/02-journeys/personas/field-fiona.md +++ b/docs/02-journeys/personas/field-fiona.md @@ -1,3 +1,7 @@ +--- +title: 'Field Fiona' +--- + # Field Fiona | Attribute | Detail | diff --git a/docs/02-journeys/personas/green-belt-gary.md b/docs/02-journeys/personas/green-belt-gary.md index 10287cc8a..36858d5f1 100644 --- a/docs/02-journeys/personas/green-belt-gary.md +++ b/docs/02-journeys/personas/green-belt-gary.md @@ -1,3 +1,7 @@ +--- +title: 'Green Belt Gary' +--- + # Green Belt Gary | Attribute | Detail | diff --git a/docs/02-journeys/personas/opex-olivia.md b/docs/02-journeys/personas/opex-olivia.md index c837360a2..00f944fc8 100644 --- a/docs/02-journeys/personas/opex-olivia.md +++ b/docs/02-journeys/personas/opex-olivia.md @@ -1,3 +1,7 @@ +--- +title: 'OpEx Olivia' +--- + # OpEx Olivia | Attribute | Detail | diff --git a/docs/02-journeys/personas/student-sara.md b/docs/02-journeys/personas/student-sara.md index 732785a6d..549e27a7b 100644 --- a/docs/02-journeys/personas/student-sara.md +++ b/docs/02-journeys/personas/student-sara.md @@ -1,3 +1,7 @@ +--- +title: 'Student Sara' +--- + # Student Sara | Attribute | Detail | diff --git a/docs/02-journeys/personas/trainer-tina.md b/docs/02-journeys/personas/trainer-tina.md index 7860b6646..9837726c4 100644 --- a/docs/02-journeys/personas/trainer-tina.md +++ b/docs/02-journeys/personas/trainer-tina.md @@ -1,3 +1,7 @@ +--- +title: 'Trainer Tina' +--- + # Trainer Tina | Attribute | Detail | diff --git a/docs/02-journeys/use-cases/batch-consistency.md b/docs/02-journeys/use-cases/batch-consistency.md index 2b96390f2..ccd487796 100644 --- a/docs/02-journeys/use-cases/batch-consistency.md +++ b/docs/02-journeys/use-cases/batch-consistency.md @@ -1,3 +1,7 @@ +--- +title: 'Batch Process Consistency' +--- + # Batch Process Consistency ## The Problem diff --git a/docs/02-journeys/use-cases/bottleneck-analysis.md b/docs/02-journeys/use-cases/bottleneck-analysis.md index 23157ac39..fe45a411a 100644 --- a/docs/02-journeys/use-cases/bottleneck-analysis.md +++ b/docs/02-journeys/use-cases/bottleneck-analysis.md @@ -1,3 +1,7 @@ +--- +title: 'Assembly Line Bottleneck Analysis' +--- + # Assembly Line Bottleneck Analysis ## The Problem diff --git a/docs/02-journeys/use-cases/call-center-performance.md b/docs/02-journeys/use-cases/call-center-performance.md index 94989c74b..8188c634f 100644 --- a/docs/02-journeys/use-cases/call-center-performance.md +++ b/docs/02-journeys/use-cases/call-center-performance.md @@ -1,3 +1,7 @@ +--- +title: 'Call Center Performance Analysis' +--- + # Call Center Performance Analysis ## The Problem diff --git a/docs/02-journeys/use-cases/complaint-investigation.md b/docs/02-journeys/use-cases/complaint-investigation.md index b34d05d84..e33f8bda8 100644 --- a/docs/02-journeys/use-cases/complaint-investigation.md +++ b/docs/02-journeys/use-cases/complaint-investigation.md @@ -1,3 +1,7 @@ +--- +title: 'Customer Complaint Investigation' +--- + # Customer Complaint Investigation ## The Problem diff --git a/docs/02-journeys/use-cases/consultant-delivery.md b/docs/02-journeys/use-cases/consultant-delivery.md index a82beaa21..61b74e9fc 100644 --- a/docs/02-journeys/use-cases/consultant-delivery.md +++ b/docs/02-journeys/use-cases/consultant-delivery.md @@ -1,3 +1,7 @@ +--- +title: 'LSS Consultant Client Delivery' +--- + # LSS Consultant Client Delivery ## The Problem diff --git a/docs/02-journeys/use-cases/copq-drilldown.md b/docs/02-journeys/use-cases/copq-drilldown.md index 66a91beac..8594e8667 100644 --- a/docs/02-journeys/use-cases/copq-drilldown.md +++ b/docs/02-journeys/use-cases/copq-drilldown.md @@ -1,3 +1,7 @@ +--- +title: 'COPQ Drill-Down' +--- + # COPQ Drill-Down ## The Problem diff --git a/docs/02-journeys/use-cases/index.md b/docs/02-journeys/use-cases/index.md index 74ad52b02..16b9fbee1 100644 --- a/docs/02-journeys/use-cases/index.md +++ b/docs/02-journeys/use-cases/index.md @@ -1,3 +1,7 @@ +--- +title: 'Use Cases' +--- + # Use Cases Strategic use cases grounded in VariScout's actual capabilities. Each describes a specific problem that brings searchers to VariScout, the analysis journey they take, and website content opportunities. diff --git a/docs/02-journeys/use-cases/lead-time-variation.md b/docs/02-journeys/use-cases/lead-time-variation.md index 23740aa27..0cf01f7b1 100644 --- a/docs/02-journeys/use-cases/lead-time-variation.md +++ b/docs/02-journeys/use-cases/lead-time-variation.md @@ -1,3 +1,7 @@ +--- +title: 'Lead Time Variation Analysis' +--- + # Lead Time Variation Analysis ## The Problem diff --git a/docs/02-journeys/use-cases/on-time-delivery.md b/docs/02-journeys/use-cases/on-time-delivery.md index 88751e5a0..2875350cd 100644 --- a/docs/02-journeys/use-cases/on-time-delivery.md +++ b/docs/02-journeys/use-cases/on-time-delivery.md @@ -1,3 +1,7 @@ +--- +title: 'On-Time Delivery Analysis' +--- + # On-Time Delivery Analysis ## The Problem diff --git a/docs/02-journeys/use-cases/patient-wait-time.md b/docs/02-journeys/use-cases/patient-wait-time.md index 650937210..2874866d5 100644 --- a/docs/02-journeys/use-cases/patient-wait-time.md +++ b/docs/02-journeys/use-cases/patient-wait-time.md @@ -1,3 +1,7 @@ +--- +title: 'Patient Wait Time Variation' +--- + # Patient Wait Time Variation ## The Problem diff --git a/docs/02-journeys/use-cases/pharma-oos.md b/docs/02-journeys/use-cases/pharma-oos.md index d27b78983..2e3c9d1e2 100644 --- a/docs/02-journeys/use-cases/pharma-oos.md +++ b/docs/02-journeys/use-cases/pharma-oos.md @@ -1,3 +1,7 @@ +--- +title: 'Pharma OOS Investigation' +--- + # Pharma OOS Investigation ## The Problem diff --git a/docs/02-journeys/use-cases/supplier-performance.md b/docs/02-journeys/use-cases/supplier-performance.md index 10f7ba314..551f22087 100644 --- a/docs/02-journeys/use-cases/supplier-performance.md +++ b/docs/02-journeys/use-cases/supplier-performance.md @@ -1,3 +1,7 @@ +--- +title: 'Supplier Performance Comparison' +--- + # Supplier Performance Comparison ## The Problem diff --git a/docs/02-journeys/use-cases/supplier-ppap.md b/docs/02-journeys/use-cases/supplier-ppap.md index e7e160dc2..5467e56d0 100644 --- a/docs/02-journeys/use-cases/supplier-ppap.md +++ b/docs/02-journeys/use-cases/supplier-ppap.md @@ -1,3 +1,7 @@ +--- +title: 'Supplier PPAP Capability Studies' +--- + # Supplier PPAP Capability Studies ## The Problem diff --git a/docs/02-journeys/use-cases/university-spc.md b/docs/02-journeys/use-cases/university-spc.md index 33dcff919..122675b03 100644 --- a/docs/02-journeys/use-cases/university-spc.md +++ b/docs/02-journeys/use-cases/university-spc.md @@ -1,3 +1,7 @@ +--- +title: 'University SPC Course' +--- + # University SPC Course ## The Problem diff --git a/docs/02-journeys/ux-research.md b/docs/02-journeys/ux-research.md index 50ea48aa3..164cee9b2 100644 --- a/docs/02-journeys/ux-research.md +++ b/docs/02-journeys/ux-research.md @@ -1,3 +1,7 @@ +--- +title: 'UX Research: VariScout Lite' +--- + # UX Research: VariScout Lite ## Design Thinking & JTBD Framework for Quality Professionals in Developing Countries diff --git a/docs/03-features/analysis/boxplot.md b/docs/03-features/analysis/boxplot.md index 63670eb0e..66812b759 100644 --- a/docs/03-features/analysis/boxplot.md +++ b/docs/03-features/analysis/boxplot.md @@ -1,3 +1,9 @@ +--- +title: 'Boxplot' +--- + + + # Boxplot The Boxplot is VariScout's tool for the **FLOW** lens - comparing variation across factors. diff --git a/docs/03-features/analysis/capability.md b/docs/03-features/analysis/capability.md index 8da97f32d..140ce1c98 100644 --- a/docs/03-features/analysis/capability.md +++ b/docs/03-features/analysis/capability.md @@ -1,3 +1,9 @@ +--- +title: 'Capability Analysis' +--- + + + # Capability Analysis Capability Analysis is VariScout's tool for the **VALUE** lens - comparing process output to customer specifications. diff --git a/docs/03-features/analysis/characteristic-types.md b/docs/03-features/analysis/characteristic-types.md index 8e6d4a311..9c09a1b2a 100644 --- a/docs/03-features/analysis/characteristic-types.md +++ b/docs/03-features/analysis/characteristic-types.md @@ -1,3 +1,7 @@ +--- +title: 'Characteristic Type Awareness' +--- + # Characteristic Type Awareness Quality characteristics come in three types. VariScout detects the type from specification limits and uses it to provide direction-aware analysis throughout the tool. diff --git a/docs/03-features/analysis/i-chart.md b/docs/03-features/analysis/i-chart.md index fcd937f0a..d1c6b76c1 100644 --- a/docs/03-features/analysis/i-chart.md +++ b/docs/03-features/analysis/i-chart.md @@ -1,3 +1,9 @@ +--- +title: 'I-Chart (Individuals Chart)' +--- + + + # I-Chart (Individuals Chart) The I-Chart is VariScout's tool for the **CHANGE** lens - analyzing time-based stability. diff --git a/docs/03-features/analysis/nelson-rules.md b/docs/03-features/analysis/nelson-rules.md index 035139094..850dd6db5 100644 --- a/docs/03-features/analysis/nelson-rules.md +++ b/docs/03-features/analysis/nelson-rules.md @@ -1,3 +1,7 @@ +--- +title: 'Nelson Rules' +--- + # Nelson Rules Nelson Rules detect special cause variation patterns in control charts. VariScout implements Nelson Rule 2 to identify sustained process shifts. diff --git a/docs/03-features/analysis/pareto.md b/docs/03-features/analysis/pareto.md index 5bdf380d1..8892cdc0f 100644 --- a/docs/03-features/analysis/pareto.md +++ b/docs/03-features/analysis/pareto.md @@ -1,3 +1,9 @@ +--- +title: 'Pareto Chart' +--- + + + # Pareto Chart The Pareto Chart is VariScout's tool for the **FAILURE** lens - finding where problems concentrate. diff --git a/docs/03-features/analysis/performance-mode.md b/docs/03-features/analysis/performance-mode.md index aff415a95..58089000b 100644 --- a/docs/03-features/analysis/performance-mode.md +++ b/docs/03-features/analysis/performance-mode.md @@ -1,3 +1,7 @@ +--- +title: 'Performance Mode' +--- + # Performance Mode Performance Mode enables multi-channel analysis for comparing multiple measurement points simultaneously. diff --git a/docs/03-features/analysis/probability-plot.md b/docs/03-features/analysis/probability-plot.md index 645d87dfc..781932660 100644 --- a/docs/03-features/analysis/probability-plot.md +++ b/docs/03-features/analysis/probability-plot.md @@ -1,3 +1,7 @@ +--- +title: 'Probability Plot' +--- + # Probability Plot The probability plot assesses whether data follows a normal distribution, which underpins capability analysis and control chart assumptions. diff --git a/docs/03-features/analysis/staged-analysis.md b/docs/03-features/analysis/staged-analysis.md index 6fbdb4a78..ac34aa386 100644 --- a/docs/03-features/analysis/staged-analysis.md +++ b/docs/03-features/analysis/staged-analysis.md @@ -1,5 +1,11 @@ +--- +title: 'Staged Analysis' +--- + # Staged Analysis + + Staged analysis calculates independent control limits for different time periods, revealing improvements that combined analysis would hide. --- diff --git a/docs/03-features/analysis/variation-decomposition.md b/docs/03-features/analysis/variation-decomposition.md index 4236581ea..9f361aeb4 100644 --- a/docs/03-features/analysis/variation-decomposition.md +++ b/docs/03-features/analysis/variation-decomposition.md @@ -1,3 +1,7 @@ +--- +title: 'Variation Decomposition' +--- + # Variation Decomposition Why VariScout uses different metrics for different questions, and how they relate to one-way ANOVA. diff --git a/docs/03-features/data/data-input.md b/docs/03-features/data/data-input.md index af88be02e..7d4bb1f4f 100644 --- a/docs/03-features/data/data-input.md +++ b/docs/03-features/data/data-input.md @@ -1,5 +1,11 @@ +--- +title: 'Data Input' +--- + # Data Input + + How VariScout handles data input — paste (PWA and Azure App) and file upload (Azure App). --- diff --git a/docs/03-features/data/storage.md b/docs/03-features/data/storage.md index a8dc56f8c..7f7a5d523 100644 --- a/docs/03-features/data/storage.md +++ b/docs/03-features/data/storage.md @@ -1,3 +1,7 @@ +--- +title: 'Project Persistence' +--- + # Project Persistence How VariScout saves and restores analyst workflow state. diff --git a/docs/03-features/data/validation.md b/docs/03-features/data/validation.md index 52c70f9f0..3f4b953f2 100644 --- a/docs/03-features/data/validation.md +++ b/docs/03-features/data/validation.md @@ -1,3 +1,7 @@ +--- +title: 'Data Validation' +--- + # Data Validation Quality checks applied to uploaded data. diff --git a/docs/03-features/index.md b/docs/03-features/index.md index eaa3a0783..7054581c4 100644 --- a/docs/03-features/index.md +++ b/docs/03-features/index.md @@ -1,3 +1,7 @@ +--- +title: 'Features' +--- + # Features Centralized feature specifications for VariScout. @@ -36,6 +40,13 @@ The core statistical charts based on Watson's Four Lenses: --- +## Analysis Journey + +| Map | Description | +| ----------------------------------------------------------------------- | ---------------------------------------------------- | +| [Analysis Journey Map](workflows/analysis-journey-map.md) | 4-phase model: Frame → Scout → Investigate → Improve | +| [Investigation Lifecycle Map](workflows/investigation-lifecycle-map.md) | IDEOI state diagram for the Investigate phase | + ## Analyst Workflows How analysts combine VariScout tools to solve real problems. See the [Workflows index](workflows/index.md) for the full guide. diff --git a/docs/03-features/learning/case-based-learning.md b/docs/03-features/learning/case-based-learning.md index 9e68dc523..86bd29f46 100644 --- a/docs/03-features/learning/case-based-learning.md +++ b/docs/03-features/learning/case-based-learning.md @@ -1,3 +1,7 @@ +--- +title: 'Case-Based Learning' +--- + # Case-Based Learning Learning through real-world examples and the 3-act case structure. diff --git a/docs/03-features/learning/glossary.md b/docs/03-features/learning/glossary.md index 077850a8f..4a389f335 100644 --- a/docs/03-features/learning/glossary.md +++ b/docs/03-features/learning/glossary.md @@ -1,3 +1,7 @@ +--- +title: 'Glossary Feature' +--- + # Glossary Feature Contextual term definitions throughout the application. diff --git a/docs/03-features/learning/help-tooltips.md b/docs/03-features/learning/help-tooltips.md index 05c683853..9a88351d7 100644 --- a/docs/03-features/learning/help-tooltips.md +++ b/docs/03-features/learning/help-tooltips.md @@ -1,3 +1,7 @@ +--- +title: 'Help Tooltips' +--- + # Help Tooltips Contextual help throughout the VariScout interface. diff --git a/docs/03-features/navigation/breadcrumbs.md b/docs/03-features/navigation/breadcrumbs.md index b871e499e..3cf6ea145 100644 --- a/docs/03-features/navigation/breadcrumbs.md +++ b/docs/03-features/navigation/breadcrumbs.md @@ -1,3 +1,7 @@ +--- +title: 'Filter Chips Navigation' +--- + # Filter Chips Navigation Filter chips provide an intuitive way to see and manage active filters with their contribution to total variation. diff --git a/docs/03-features/navigation/drill-down.md b/docs/03-features/navigation/drill-down.md index d15888724..bdca9aea3 100644 --- a/docs/03-features/navigation/drill-down.md +++ b/docs/03-features/navigation/drill-down.md @@ -1,3 +1,7 @@ +--- +title: 'Drill-Down Navigation' +--- + # Drill-Down Navigation Drill-down is VariScout's core methodology for isolating variation sources through progressive stratification. diff --git a/docs/03-features/navigation/linked-filtering.md b/docs/03-features/navigation/linked-filtering.md index 3ae6bf465..590b1b496 100644 --- a/docs/03-features/navigation/linked-filtering.md +++ b/docs/03-features/navigation/linked-filtering.md @@ -1,3 +1,7 @@ +--- +title: 'Linked Filtering' +--- + # Linked Filtering Linked filtering connects all charts so clicking one filters all others. diff --git a/docs/03-features/specifications.md b/docs/03-features/specifications.md index e1a070e63..dbc4c665e 100644 --- a/docs/03-features/specifications.md +++ b/docs/03-features/specifications.md @@ -1,3 +1,7 @@ +--- +title: 'VariScout — Product Spec' +--- + # VariScout — Product Spec **Version:** 1.0 diff --git a/docs/03-features/user-guide.md b/docs/03-features/user-guide.md index cdb9c4fcc..377de35a6 100644 --- a/docs/03-features/user-guide.md +++ b/docs/03-features/user-guide.md @@ -1,3 +1,7 @@ +--- +title: 'VariScout Lite: User Guide' +--- + # VariScout Lite: User Guide This guide covers advanced features and workflows in VariScout Lite, focusing on interactive customization and specification management. diff --git a/docs/03-features/workflows/analysis-journey-map.md b/docs/03-features/workflows/analysis-journey-map.md new file mode 100644 index 000000000..809e9d218 --- /dev/null +++ b/docs/03-features/workflows/analysis-journey-map.md @@ -0,0 +1,432 @@ +--- +title: Analysis Journey Map +description: Visual map of the 4-phase analysis journey — Frame, Scout, Investigate, Improve — with CoScout companion and PDCA loop +journey-phase: [all] +--- + +# Analysis Journey Map + +VariScout guides quality analysts through four distinct phases: **Frame**, **Scout**, **Investigate**, and **Improve**. Each phase has a clear purpose, specific data shapes at its boundaries, and defined decision points that move the analyst forward. CoScout, the AI companion, adapts its behaviour at each phase to provide contextually relevant guidance. + +## Journey Overview + +```mermaid +flowchart LR + subgraph CoScout["CoScout AI Companion"] + direction LR + F["FRAME\nDefine the problem space"] + S["SCOUT\nDiscover variation patterns"] + I["INVESTIGATE\nFind root causes"] + IM["IMPROVE\nProject and verify fixes"] + end + + F --> S + S --> I + I --> IM + IM -- "PDCA loop" --> F + S -- "Add Data" --> F + + style F fill:#3b82f6,color:#fff + style S fill:#22c55e,color:#fff + style I fill:#f59e0b,color:#fff + style IM fill:#8b5cf6,color:#fff +``` + +The journey is not strictly linear. Two feedback loops connect the phases: + +- **PDCA loop** -- After verifying an improvement, the analyst re-enters Frame with new data to confirm the gains hold. +- **Add Data loop** -- While scouting, the analyst may realise the dataset is incomplete and return to Frame to add more data or remap columns. + +--- + +## Phase 1: FRAME + +**Purpose:** Define the problem space by loading data, mapping columns, and setting specification limits. + +```mermaid +flowchart TD + U["Upload / Paste data"] --> P["Parse rows"] + P --> CM["Column Mapping\n(measure + factors)"] + CM --> SS["Set Spec Limits\n(USL, LSL, Target)"] + SS --> PD["Describe Process Context"] + PD --> R["Ready for analysis"] + + style U fill:#3b82f6,color:#fff + style R fill:#22c55e,color:#fff +``` + +### Steps + +1. **Upload or paste data** -- CSV, Excel, or clipboard paste. The parser (`parseText` / `parseFile`) detects delimiters and validates structure. +2. **Map columns** -- Assign one measurement column and up to N factor columns. The `ColumnMapping` component provides data-rich cards with type badges and preview values. +3. **Set specification limits** -- Enter USL, LSL, and optional target via `SpecsPopover`. These flow through to capability calculations. +4. **Describe process context** -- Optional but valuable for CoScout. Process name, characteristic type, and any known constraints. + +### Data Shapes at Boundary + +| Entry | Exit | +| ------------------------- | --------------------------------------------- | +| Raw file / clipboard text | `DataRow[]` (parsed, validated) | +| -- | `ValidationResult` (quality checks) | +| -- | `ColumnMapping` (measure + factors assigned) | +| -- | `AnalysisState` (specs, settings, ready flag) | + +### Tier Differences + +| Dimension | PWA (Free) | Azure (Standard / Team) | +| ----------- | ------------ | ------------------------------- | +| Max factors | 3 | 6 | +| Max rows | 50,000 | 100,000 | +| Persistence | Session only | IndexedDB (+ OneDrive for Team) | + +### CoScout in Frame + +CoScout is **not active** during Frame -- there is no analysed data to reason about yet. Once the analyst clicks "Start", data flows into the Scout phase and CoScout activates. + +### Key Code References + +- `useDataIngestion` -- shared file upload and parsing hook +- `useDataState` -- shared DataContext state management +- `ColumnMapping` component -- column assignment UI +- `parser.ts` -- CSV/Excel parsing and validation + +--- + +## Phase 2: SCOUT + +**Purpose:** Discover variation patterns using the Four Lenses -- CHANGE, FLOW, FAILURE, VALUE. + +```mermaid +flowchart TD + IC["I-Chart\n(CHANGE)"] --> BP["Boxplot\n(FLOW)"] + BP --> PA["Pareto\n(FAILURE)"] + PA --> CA["Capability\n(VALUE)"] + + IC -- "Special cause?" --> PIN1["Pin finding"] + BP -- "High eta-squared?" --> DRILL["Drill down"] + PA -- "Vital few?" --> PIN2["Pin finding"] + CA -- "Cpk concern?" --> PIN3["Pin finding"] + + DRILL --> IC + CA -- "Need more data?" --> ADD["Add Data\n(back to Frame)"] + + style IC fill:#3b82f6,color:#fff + style BP fill:#3b82f6,color:#fff + style PA fill:#3b82f6,color:#fff + style CA fill:#3b82f6,color:#fff + style PIN1 fill:#f59e0b,color:#fff + style PIN2 fill:#f59e0b,color:#fff + style PIN3 fill:#f59e0b,color:#fff +``` + +### Steps + +1. **Scan I-Chart for stability** -- Look for points outside control limits, runs, and trends. Red dots signal special causes. +2. **Compare factors in Boxplot** -- Read ANOVA eta-squared to identify which factor explains the most variation. +3. **Rank in Pareto** -- See which categories within a factor contribute most to failures or out-of-spec results. +4. **Check Cpk** -- After filtering, assess whether the isolated subset meets specification requirements. + +At any point, the analyst can **pin a finding** to capture an observation for later investigation. + +### Two Speeds + +| Path | Duration | When to Use | +| --------------- | -------- | ------------------------------------------------------------- | +| **Quick Check** | ~5 min | Daily monitoring, shift handover | +| **Deep Dive** | ~30 min | Customer complaint, root cause project, process qualification | + +See [quick-check.md](quick-check.md) and [deep-dive.md](deep-dive.md) for detailed protocols. + +### Data Shapes + +| Type | Purpose | +| ------------------------------ | ------------------------------------------------------- | +| `StatsResult` | Mean, sigma, Cp, Cpk, median for current filter scope | +| `AnovaResult` | F-statistic, p-value, eta-squared for factor comparison | +| `FilterAction[]` | Ordered drill trail (filter stack) | +| `Finding` (status: `observed`) | Pinned observations from charts | + +### Tier Differences + +| Dimension | PWA (Free) | Azure (Standard / Team) | +| ------------------ | ------------------------------------- | ------------------------- | +| Max drill factors | 3 | 6 | +| Finding statuses | 3 (observed, investigating, analyzed) | 5 (+ improving, resolved) | +| Variation tracking | Cumulative Total SS | Cumulative Total SS | + +### CoScout in Scout + +- **NarrativeBar** suggests patterns detected in the data ("Shift detected after sample 47") +- **ChartInsightChips** appear on individual charts with contextual observations + +### Key Code References + +- `useFilterNavigation` -- filter navigation with multi-select and breadcrumbs +- `useVariationTracking` -- cumulative Total SS scope tracking +- `useChartScale` -- Y-axis scale calculation +- `useBoxplotData`, `useIChartData` -- chart data transforms + +--- + +## Phase 3: INVESTIGATE + +**Purpose:** Move from observations to validated root causes through structured hypothesis testing. + +```mermaid +stateDiagram-v2 + [*] --> Initial: Pin finding + Initial --> Diverging: Generate sub-hypotheses + Diverging --> Validating: Select hypothesis to test + Validating --> Diverging: Needs more hypotheses + Validating --> Converging: Evidence confirms + Converging --> Acting: Root cause identified + Acting --> [*]: Ready for Improve phase + + note right of Diverging + Brainstorm possible causes + (CoScout suggests) + end note + + note right of Validating + Data evidence (ANOVA) + Gemba observation + Expert input + end note +``` + +### IDEOI Phases + +The investigation follows the IDEOI lifecycle within each finding: + +| Phase | Status | Activity | +| -------------- | ------------------- | --------------------------------------------------------------------------------------- | +| **I**nitial | `observed` | Finding pinned from chart, no hypothesis yet | +| **D**iverging | `investigating` | Generate multiple sub-hypotheses, brainstorm causes | +| **V**alidating | `investigating` | Test hypotheses against data (eta-squared thresholds), gemba walks, expert consultation | +| **C**onverging | `analyzed` | Confirm root cause, tag as key-driver or low-impact | +| **A**cting | `improving` (Azure) | Define corrective actions, enter Improve phase | + +### Steps + +1. **Formulate hypotheses** -- Based on Scout observations, propose why the variation exists. CoScout can suggest hypotheses grounded in the data. +2. **Test with data** -- Use ANOVA results and drill-down filtering to validate or reject each hypothesis. Auto-validation uses eta-squared thresholds. +3. **Gemba observation** -- Go to the process and observe. Azure Team plan supports photo evidence (EXIF-stripped). +4. **Expert input** -- Add comments and notes from domain experts to findings. +5. **Converge** -- Select the validated root cause and classify the finding (key-driver vs low-impact). + +### Data Shapes + +| Type | Purpose | +| --------------- | -------------------------------------------------------------------- | +| `Finding` | Core investigation record with status progression | +| `Hypothesis` | Sub-hypothesis linked to a finding, with validation state | +| `FindingStatus` | `observed` / `investigating` / `analyzed` / `improving` / `resolved` | +| `FindingTag` | `key-driver` or `low-impact` classification | + +### Tier Differences + +| Dimension | PWA (Free) | Azure (Standard / Team) | +| --------------------- | ------------------------------------- | ---------------------------- | +| Finding statuses | 3 (observed, investigating, analyzed) | 5 (all statuses) | +| Photo evidence | No | Team plan only | +| Hypothesis management | Full | Full | +| Board view | 3 columns | 5 columns with drag-and-drop | + +### CoScout in Investigate + +- Suggests hypotheses based on data patterns and process context +- Validates hypotheses against statistical evidence +- Links related findings across investigation sessions + +### Key Code References + +- `useFindings` -- finding CRUD, status transitions, hypothesis linking +- `useHypotheses` -- hypothesis CRUD, auto-validation with eta-squared thresholds +- `FindingsLog`, `FindingBoardView` -- UI components for findings management + +--- + +## Phase 4: IMPROVE + +**Purpose:** Project improvements, define corrective actions, verify with staged analysis, and record outcomes. + +```mermaid +flowchart TD + ID["Ideas from investigation"] --> WI["What-If Simulator\n(project Cpk/yield)"] + WI --> ACT["Define Corrective Actions"] + ACT --> IMPL["Implement changes"] + IMPL --> STAGE["Staged Analysis\n(before vs after)"] + STAGE --> CHK{Verification\npassed?} + CHK -- "Yes" --> OUT["Record Outcome\n(report / share)"] + CHK -- "No" --> PDCA["PDCA loop\n(back to Frame)"] + OUT --> CLOSE["Resolve finding"] + + style ID fill:#8b5cf6,color:#fff + style WI fill:#8b5cf6,color:#fff + style OUT fill:#22c55e,color:#fff + style PDCA fill:#3b82f6,color:#fff +``` + +### Steps + +1. **Generate improvement ideas** -- Based on root cause analysis, propose specific changes. Each idea can have a projected impact. +2. **Model with What-If Simulator** -- Use `directAdjustment` to project how changes would affect Cpk and yield. +3. **Define corrective actions** -- Create trackable action items with owners, dates, and status. +4. **Verify with staged analysis** -- Load before-and-after data into staged analysis to confirm the improvement. Compare control limits and Cpk. +5. **Record outcome** -- Document whether the action resolved the variation source. Mark the finding as resolved. + +### Data Shapes + +| Type | Purpose | +| ------------------------------ | ------------------------------------------ | +| `ActionItem` | Corrective action with owner, date, status | +| `FindingOutcome` | Documented result of the improvement | +| `Finding` (status: `resolved`) | Closed investigation | + +### Tier Differences + +| Dimension | PWA (Free) | Azure (Standard / Team) | +| ----------------- | ---------- | ------------------------------------ | +| What-If Simulator | Available | Available | +| Action tracking | Limited | Full (improving + resolved statuses) | +| Staged analysis | Available | Available | +| Outcome recording | No | Team plan | + +### CoScout in Improve + +- Suggests corrective actions based on validated root cause +- Assists with What-If parameter selection +- Summarises before/after comparison + +### Key Code References + +- `WhatIfSimulator` / `WhatIfPageBase` -- simulation UI +- `simulation.ts` -- `directAdjustment` computation +- [staged-analysis.md](../analysis/staged-analysis.md) -- staged comparison methodology + +--- + +## Two Entry Paths into Scout + +Not every analysis starts the same way. VariScout supports two distinct paths into the Scout phase: + +```mermaid +flowchart TD + START["Data loaded\n(Frame complete)"] --> PATH + + PATH --> DISC["Discovery Path"] + PATH --> HYPO["Hypothesis-Driven Path"] + + DISC --> SCAN["Scan all Four Lenses"] + SCAN --> DRILL["Drill into patterns"] + DRILL --> FIND["Pin findings"] + FIND --> INV["Move to Investigate"] + + HYPO --> SUGGEST["CoScout suggests pattern"] + SUGGEST --> CONFIRM["Confirm with chart evidence"] + CONFIRM --> JUMP["Jump directly to Investigate"] + + style DISC fill:#22c55e,color:#fff + style HYPO fill:#f59e0b,color:#fff +``` + +| Path | Starting Point | Duration | Best For | +| --------------------- | ------------------------------------- | --------- | ---------------------------------- | +| **Discovery** | No prior knowledge | 15-30 min | New datasets, exploratory analysis | +| **Hypothesis-driven** | CoScout suggestion or prior knowledge | 5-10 min | Known issues, repeat monitoring | + +--- + +## The Drill-Down Loop + +The drill-down loop is the core interaction pattern within the Scout phase. Each iteration narrows the data scope and increases the percentage of variation explained. + +```mermaid +flowchart TD + ALL["All Data"] --> READ["Read eta-squared\n(ANOVA under Boxplot)"] + READ --> CLICK["Click highest-eta factor"] + CLICK --> FILTER["Filter applied\n(chip shows contribution %)"] + FILTER --> UPDATE["Charts update\nfor filtered subset"] + UPDATE --> CHECK{Enough variation\nisolated?} + CHECK -- "Yes (>50%)" --> PIN["Pin finding"] + CHECK -- "No" --> READ + + style ALL fill:#3b82f6,color:#fff + style PIN fill:#22c55e,color:#fff +``` + +Each filter chip displays the cumulative contribution percentage (Total SS scope), giving the analyst a running measure of how much variation has been explained by the current drill path. See [drill-down-workflow.md](drill-down-workflow.md) for the detailed protocol. + +--- + +## Decision Point Map + +Twelve key decision points shape the analysis journey. Each has a clear question, evidence source, and branching outcome. + +| # | Decision Point | Phase | Evidence | Yes Path | No Path | +| --- | ---------------------------------- | ----------- | -------------------------------------- | -------------------------------- | ------------------------------------ | +| 1 | Stable? | Scout | I-Chart (control limits, Nelson rules) | Proceed to Boxplot | Investigate special causes first | +| 2 | Which factor drives variation? | Scout | Boxplot eta-squared | Drill into highest eta-squared | Check interactions | +| 3 | Enough variation isolated? | Scout | Cumulative Total SS > 50% | Pin finding, move to Investigate | Continue drilling | +| 4 | Capable? | Scout | Cpk vs target (1.33 default) | Process acceptable | Needs improvement | +| 5 | Quick Check or Deep Dive? | Scout | Time available, severity | Quick Check (~5 min) | Deep Dive (~30 min) | +| 6 | Discovery or Hypothesis-driven? | Scout | Prior knowledge, CoScout input | Discovery (scan all lenses) | Hypothesis-driven (confirm and jump) | +| 7 | Key Driver or Low Impact? | Investigate | eta-squared magnitude, Pareto rank | Tag as key-driver | Tag as low-impact | +| 8 | Single or multiple hypotheses? | Investigate | Complexity of problem | Test single hypothesis | Diverge into sub-hypotheses | +| 9 | Data, gemba, or expert validation? | Investigate | Available evidence | Statistical test (ANOVA) | Physical observation or consultation | +| 10 | Converged on root cause? | Investigate | Hypothesis validation status | Enter Improve phase | Generate more hypotheses | +| 11 | What-If projection effective? | Improve | Projected Cpk meets target | Define corrective actions | Revise approach | +| 12 | Verification passed? | Improve | Staged analysis (before vs after) | Resolve finding, close | PDCA loop back to Frame | + +--- + +## All Loops Visualized + +Five feedback loops keep the analysis iterative and self-correcting: + +```mermaid +flowchart TD + FRAME["FRAME"] --> SCOUT["SCOUT"] + SCOUT --> INVESTIGATE["INVESTIGATE"] + INVESTIGATE --> IMPROVE["IMPROVE"] + + %% Drill-down loop (Scout) + SCOUT -- "Drill-down loop\n(filter, read, repeat)" --> SCOUT + + %% Hypothesis validation loop (Investigate) + INVESTIGATE -- "Hypothesis loop\n(diverge, validate, converge)" --> INVESTIGATE + + %% What-If iteration loop (Improve) + IMPROVE -- "What-If loop\n(project, adjust, re-project)" --> IMPROVE + + %% PDCA re-entry loop + IMPROVE -- "PDCA loop\n(verify failed or new cycle)" --> FRAME + + %% Add Data loop + SCOUT -- "Add Data loop\n(incomplete dataset)" --> FRAME + + style FRAME fill:#3b82f6,color:#fff + style SCOUT fill:#22c55e,color:#fff + style INVESTIGATE fill:#f59e0b,color:#fff + style IMPROVE fill:#8b5cf6,color:#fff +``` + +| Loop | Phase | Trigger | Exit Condition | +| --------------------- | ---------------- | -------------------------------------------------- | ------------------------------------------- | +| Drill-down | Scout | eta-squared suggests deeper factor | >50% variation explained or no more factors | +| Hypothesis validation | Investigate | Hypothesis not yet confirmed | Root cause validated with evidence | +| What-If iteration | Improve | Projected Cpk below target | Projection meets target or approach revised | +| PDCA re-entry | Improve to Frame | Staged verification fails or new improvement cycle | Verification passes | +| Add Data | Scout to Frame | Dataset missing factors or insufficient samples | Data reloaded with additional columns/rows | + +--- + +## Related Documentation + +- [Four Lenses Workflow](four-lenses-workflow.md) -- detailed CHANGE / FLOW / FAILURE / VALUE methodology +- [Drill-Down Workflow](drill-down-workflow.md) -- progressive stratification using filter chips +- [Quick Check](quick-check.md) -- 5-minute monitoring protocol +- [Deep Dive](deep-dive.md) -- 30-minute investigation protocol +- [Investigation to Action](investigation-to-action.md) -- findings and What-If workflow +- [Investigation Lifecycle Map](investigation-lifecycle-map.md) -- IDEOI state machine detail +- [Decision Trees](decision-trees.md) -- branching logic for analysis decisions diff --git a/docs/03-features/workflows/decision-trees.md b/docs/03-features/workflows/decision-trees.md index 6ed8752f4..6fad6ce1b 100644 --- a/docs/03-features/workflows/decision-trees.md +++ b/docs/03-features/workflows/decision-trees.md @@ -1,3 +1,7 @@ +--- +title: 'Decision Trees' +--- + # Decision Trees Flowcharts to answer common analyst questions: "Which chart should I use?" and "What do I do next?" diff --git a/docs/03-features/workflows/deep-dive.md b/docs/03-features/workflows/deep-dive.md index 06a0eb6f8..5d52be81d 100644 --- a/docs/03-features/workflows/deep-dive.md +++ b/docs/03-features/workflows/deep-dive.md @@ -1,5 +1,11 @@ +--- +title: 'Deep Dive Workflow' +--- + # Deep Dive Workflow + + A 30-minute systematic investigation pattern for problem-solving. ## Overview diff --git a/docs/03-features/workflows/drill-down-workflow.md b/docs/03-features/workflows/drill-down-workflow.md index b2876bd1d..9aa3f7108 100644 --- a/docs/03-features/workflows/drill-down-workflow.md +++ b/docs/03-features/workflows/drill-down-workflow.md @@ -1,5 +1,11 @@ +--- +title: 'Drill-Down Analysis Workflow' +--- + # Drill-Down Analysis Workflow + + VariScout's signature interaction pattern—progressive stratification using filter chips to isolate variation sources.
@@ -104,8 +110,9 @@ The percentage on each chip shows that factor's **contribution to variation**: - Shows proportion of variance explained - Helps prioritize which factors matter most -!!! info "Cumulative vs Individual" +:::note[Cumulative vs Individual] Each chip shows its individual contribution. The VariationBar and Investigation Mindmap footer show cumulative progress. +::: ## Tracking Your Investigation diff --git a/docs/03-features/workflows/four-lenses-workflow.md b/docs/03-features/workflows/four-lenses-workflow.md index 6dc6eb143..6d27fdbbb 100644 --- a/docs/03-features/workflows/four-lenses-workflow.md +++ b/docs/03-features/workflows/four-lenses-workflow.md @@ -1,5 +1,11 @@ +--- +title: 'Four Lenses Analysis Workflow' +--- + # Four Lenses Analysis Workflow + + The core VariScout methodology: **CHANGE → FLOW → FAILURE → VALUE** ## Overview @@ -66,8 +72,9 @@ flowchart TD - **Stable:** Process variation is common cause only. Proceed to understand what factors explain that variation. - **Unstable:** Special causes present. These must be investigated—they often point directly to assignable causes. -!!! tip "Start Here" +:::tip[Start Here] Always check stability first. Analyzing an unstable process as if it were stable leads to wrong conclusions. +::: ## Lens 2: FLOW (Boxplot) diff --git a/docs/03-features/workflows/index.md b/docs/03-features/workflows/index.md index ed1fa3aba..5ce0d99de 100644 --- a/docs/03-features/workflows/index.md +++ b/docs/03-features/workflows/index.md @@ -1,3 +1,7 @@ +--- +title: 'Analyst Workflows' +--- + # Analyst Workflows How analysts use VariScout to solve real problems. @@ -18,6 +22,18 @@ Workflows describe **what analysts actually DO** inside VariScout—the sequence | Process Investigation | ~15 | ~10 min | Why is quality dropping? | | Predict Improvement | ~12 | ~8 min | Can we fix it? | +## Analysis Journey + +### [Analysis Journey Map](analysis-journey-map.md) + +The unified 4-phase model: **FRAME → SCOUT → INVESTIGATE → IMPROVE** with CoScout companion across all phases and PDCA loop for re-entry. Start here for the big picture. + +### [Investigation Lifecycle Map](investigation-lifecycle-map.md) + +IDEOI state diagram for the Investigate phase — hypothesis diamond, finding status lifecycle, and CoScout behavior at each state. + +--- + ## Core Workflows ### [Four Lenses Analysis](four-lenses-workflow.md) @@ -105,6 +121,8 @@ Systematic investigation for problem-solving: ## Related Documentation -- [Feature Documentation](../index.md) - What each chart does -- [Case Studies](../../04-cases/index.md) - Teaching examples -- [Four Lenses Philosophy](../../01-vision/four-lenses/index.md) - Why this methodology +- [Feature Documentation](../index.md) — What each chart does +- [Case Studies](../../04-cases/index.md) — Teaching examples +- [Four Lenses Philosophy](../../01-vision/four-lenses/index.md) — Why this methodology +- [System Map](../../05-technical/architecture/system-map.md) — Package topology +- [Data Pipeline Map](../../05-technical/architecture/data-pipeline-map.md) — End-to-end data flow diff --git a/docs/03-features/workflows/investigation-lifecycle-map.md b/docs/03-features/workflows/investigation-lifecycle-map.md new file mode 100644 index 000000000..677925330 --- /dev/null +++ b/docs/03-features/workflows/investigation-lifecycle-map.md @@ -0,0 +1,155 @@ +--- +title: Investigation Lifecycle Map +description: State diagrams for IDEOI investigation phases and Finding status lifecycle with transition triggers and CoScout behavior +journey-phase: investigate +--- + +# Investigation Lifecycle Map + +State diagrams for IDEOI investigation phases, Finding status transitions, and hypothesis validation — showing how CoScout adapts its behavior at each stage. + +## Overview + +The IDEOI framework (Initial, Diverging, Evaluating, Organizing, Implementing) maps the investigation lifecycle from first data scan through verified improvement. Each phase changes CoScout's behavior, UI presentation, and suggested questions. + +The framework connects three moving parts: + +1. **IDEOI phases** — the analyst's cognitive stage in the investigation +2. **Finding statuses** — the lifecycle of individual observations +3. **Hypothesis validation** — the evidence-gathering sub-flow within Diverging/Validating + +## IDEOI State Diagram + +```mermaid +stateDiagram-v2 + [*] --> Initial + Initial --> Diverging : First hypothesis created + Diverging --> Validating : Hypothesis selected for testing + Validating --> Diverging : Need more hypotheses + Validating --> Converging : Evidence supports/refutes + Converging --> Diverging : Insufficient evidence, explore more + Converging --> Acting : Root cause confirmed + Acting --> [*] : Outcome recorded + + state Initial { + [*] --> ScanningData + ScanningData --> PinningFindings + PinningFindings --> ScanningData + } + + state Diverging { + [*] --> GeneratingHypotheses + GeneratingHypotheses --> AddingSubHypotheses + } + + state Validating { + [*] --> DataValidation + DataValidation --> GembaValidation + GembaValidation --> ExpertValidation + } + + state Converging { + [*] --> ReviewingEvidence + ReviewingEvidence --> IdentifyingRootCause + } + + state Acting { + [*] --> PlanningActions + PlanningActions --> VerifyingImprovement + } +``` + +## Phase Behavior Table + +Each IDEOI phase triggers distinct CoScout behavior and UI changes. + +| Phase | Trigger In | CoScout Behavior | UI Changes | Suggested Questions | +| -------------- | ---------------------------- | ---------------------------------------- | -------------------------------------- | ----------------------------------------------- | +| **Initial** | Data loaded, scanning charts | Suggests patterns in data | Dashboard with Four Lenses | "What patterns do you see in the I-Chart?" | +| **Diverging** | First finding pinned | Suggests possible hypotheses | Findings panel opens, hypothesis form | "Could [factor] be driving this?" | +| **Validating** | Hypothesis selected | Provides data evidence for/against | Validation checklist, ANOVA highlights | "eta-squared for [factor] is X% — significant?" | +| **Converging** | Evidence collected | Summarizes evidence, suggests root cause | Finding cards show validation status | "Evidence points to [factor] as root cause" | +| **Acting** | Root cause confirmed | Suggests corrective actions | What-If simulator, action items | "What if you reduced [factor] variation by X%?" | + +## Finding Status Lifecycle + +Individual findings move through a status lifecycle that maps onto the broader IDEOI phases. PWA supports the first three statuses; Azure supports all five. + +```mermaid +stateDiagram-v2 + [*] --> observed + observed --> investigating : Start investigating + investigating --> analyzed : Analysis complete + analyzed --> improving : Action planned (Azure only) + improving --> resolved : Verification passed (Azure only) + resolved --> [*] + + observed --> observed : Add comment + investigating --> investigating : Add comment, link hypothesis + analyzed --> analyzed : Classify tag (key-driver / low-impact) + improving --> improving : Update action progress +``` + +## Finding Status Properties + +| Status | Badge Color | Meaning | Available In | +| --------------- | ----------- | ------------------------------------- | ------------ | +| `observed` | Amber | Pattern spotted, not yet investigated | PWA, Azure | +| `investigating` | Blue | Actively drilling into this finding | PWA, Azure | +| `analyzed` | Purple | Analysis completed, classified | PWA, Azure | +| `improving` | Teal | Action planned, in progress | Azure only | +| `resolved` | Green | Verification passed, closed | Azure only | + +## Hypothesis Validation Sub-flow + +Within the Validating phase, each hypothesis goes through an evidence-gathering loop with three validation paths. + +```mermaid +flowchart TD + A[Hypothesis created] --> B{Choose validation path} + B --> C[Data validation] + B --> D[Gemba validation] + B --> E[Expert validation] + C --> F[Check ANOVA eta-squared, filter and compare] + D --> G[Go to the process, observe] + E --> H[Consult domain expert] + F --> I[Record evidence] + G --> I + H --> I + I --> J{Evidence outcome} + J -->|Supports| K[Mark hypothesis supported] + J -->|Refutes| L[Mark hypothesis refuted] + J -->|Inconclusive| M[Gather more evidence] + M --> B + K --> N[Update hypothesis status] + L --> N +``` + +**Auto-validation thresholds** (based on ANOVA eta-squared): + +| eta-squared | Strength | Interpretation | +| ----------- | -------- | --------------------------------------- | +| > 0.14 | Strong | Factor likely driving variation | +| 0.06 - 0.14 | Moderate | Factor contributes, investigate further | +| < 0.06 | Weak | Factor unlikely to be root cause | + +## Hooks and Components + +Each IDEOI concept maps to a specific hook or component in the codebase. + +| Concept | Hook / Component | Package | +| --------------------- | ---------------------------- | ------------------ | +| Finding CRUD | `useFindings` | `@variscout/hooks` | +| Hypothesis CRUD | `useHypotheses` | `@variscout/hooks` | +| IDEOI phase detection | `detectInvestigationPhase()` | `@variscout/core` | +| CoScout phase context | `getCoScoutPhase()` | `@variscout/core` | +| Finding cards | `FindingCard` | `@variscout/ui` | +| Board view | `FindingBoardView` | `@variscout/ui` | +| What-If simulator | `WhatIfSimulator` | `@variscout/ui` | + +## Related Documentation + +- [Investigation to Action Workflow](investigation-to-action.md) — end-to-end analyst workflow from data load to projection +- [Decision Trees](decision-trees.md) — branching logic for analysis decisions +- [Drill-Down Workflow](drill-down-workflow.md) — factor drill-down navigation +- [Four Lenses Workflow](four-lenses-workflow.md) — the four analytical perspectives (Change, Failure, Flow, Value) diff --git a/docs/03-features/workflows/investigation-to-action.md b/docs/03-features/workflows/investigation-to-action.md index c033febf5..0638015dd 100644 --- a/docs/03-features/workflows/investigation-to-action.md +++ b/docs/03-features/workflows/investigation-to-action.md @@ -1,5 +1,11 @@ +--- +title: 'Investigation to Action Workflow' +--- + # Investigation to Action Workflow + + From variation discovery to projected improvement — the analyst workflow.
diff --git a/docs/03-features/workflows/performance-mode-workflow.md b/docs/03-features/workflows/performance-mode-workflow.md index d43c06a3e..4b3043e15 100644 --- a/docs/03-features/workflows/performance-mode-workflow.md +++ b/docs/03-features/workflows/performance-mode-workflow.md @@ -1,3 +1,7 @@ +--- +title: 'Performance Mode Workflow' +--- + # Performance Mode Workflow Multi-channel analysis for production equipment with multiple measurement points. @@ -123,8 +127,9 @@ Single-channel histogram after drilling down: - Default: Cpk (overall assessment) - Switch to Cp: See if centering could help -!!! tip "Interpreting the Difference" +:::tip[Interpreting the Difference] If Cp >> Cpk, the process can meet specs if centered. If Cp ≈ Cpk, the process is centered but variation is the issue. +::: ## Health Classification diff --git a/docs/03-features/workflows/process-maps.md b/docs/03-features/workflows/process-maps.md index 691b09c4d..5b933fcc3 100644 --- a/docs/03-features/workflows/process-maps.md +++ b/docs/03-features/workflows/process-maps.md @@ -1,3 +1,7 @@ +--- +title: 'Visual Process Maps' +--- + # Visual Process Maps Scannable, step-by-step maps showing exactly how many user actions each analysis workflow requires. @@ -34,113 +38,115 @@ The summary strip at the end shows **total actions** and **approximate time**. _"Is my process stable?"_ -=== "PWA" - -
-
-
-
Paste Data
-
Click "Paste from Excel", Ctrl+V
-
-
2 actions
-
-
-
-
-
Analyze
-
Click "Analyze Data"
-
-
1 click
-
-
-
-
-
Map Columns
-
Outcome + factor + "Start"
-
-
3 clicks
-
-
-
-
-
Read I-Chart
-
Red dots = unstable
-
-
0 clicks
-
-
-
-
-
Check Stats
-
Mean, sigma, UCL, LCL
-
-
0 clicks
-
-
-
6 actions
-
~2 min
-
-
- - **Decision:** All blue dots → stable. Any red dots → investigate with [Root Cause Analysis](#flow-2-root-cause-analysis). - -=== "Azure" - -
-
-
-
New Analysis
-
Click in project list
-
-
1 click
-
-
-
-
-
Paste or Upload
-
Ctrl+V or select file
-
-
2 actions
-
-
-
-
-
Analyze
-
Auto-detects columns
-
-
1 click
-
-
-
-
-
Read I-Chart
-
Red dots = unstable
-
-
0 clicks
-
-
-
-
-
Check Stats
-
Mean, sigma, UCL, LCL
-
-
0 clicks
-
-
-
-
-
Save
-
Persists to OneDrive
-
-
1 click
-
-
-
5 actions
-
~2 min
-
-
- - Azure skips column mapping when auto-detection succeeds, saving 1 action. The Save step persists to OneDrive. +### PWA + +
+
+
+
Paste Data
+
Click "Paste from Excel", Ctrl+V
+
+
2 actions
+
+
+
+
+
Analyze
+
Click "Analyze Data"
+
+
1 click
+
+
+
+
+
Map Columns
+
Outcome + factor + "Start"
+
+
3 clicks
+
+
+
+
+
Read I-Chart
+
Red dots = unstable
+
+
0 clicks
+
+
+
+
+
Check Stats
+
Mean, sigma, UCL, LCL
+
+
0 clicks
+
+
+
6 actions
+
~2 min
+
+
+ +**Decision:** All blue dots → stable. Any red dots → investigate with [Root Cause Analysis](#flow-2-root-cause-analysis). + +### PWA + +### Azure + +
+
+
+
New Analysis
+
Click in project list
+
+
1 click
+
+
+
+
+
Paste or Upload
+
Ctrl+V or select file
+
+
2 actions
+
+
+
+
+
Analyze
+
Auto-detects columns
+
+
1 click
+
+
+
+
+
Read I-Chart
+
Red dots = unstable
+
+
0 clicks
+
+
+
+
+
Check Stats
+
Mean, sigma, UCL, LCL
+
+
0 clicks
+
+
+
+
+
Save
+
Persists to OneDrive
+
+
1 click
+
+
+
5 actions
+
~2 min
+
+
+ +Azure skips column mapping when auto-detection succeeds, saving 1 action. The Save step persists to OneDrive. --- @@ -148,129 +154,131 @@ _"Is my process stable?"_ _"What's causing variation?"_ -=== "PWA" - -
-
-
-
Paste Data
-
Click "Paste from Excel", Ctrl+V
-
-
2 actions
-
-
-
-
-
Analyze
-
Click "Analyze Data"
-
-
1 click
-
-
-
-
-
Map Columns
-
Outcome + 2 factors + "Start"
-
-
4 clicks
-
-
-
-
-
Read ANOVA
-
Check eta-squared under Boxplot
-
-
0 clicks
-
-
-
-
-
Filter Top Factor
-
Click highest-eta bar
-
-
1 click
-
-
-
-
-
Read Filtered
-
Variation explained? Cpk improved?
-
-
0 clicks
-
-
-
8 actions
-
~5 min
-
-
- - **Decision:** eta-squared > 50% → primary driver found. Filter isolates the cause. - -=== "Azure" - -
-
-
-
New Analysis
-
Click in project list
-
-
1 click
-
-
-
-
-
Upload File
-
Select CSV from dialog
-
-
2 actions
-
-
-
-
-
Analyze
-
Auto-detects columns
-
-
1 click
-
-
-
-
-
Read ANOVA
-
Check eta-squared under Boxplot
-
-
0 clicks
-
-
-
-
-
Filter Top Factor
-
Click bar or mindmap node
-
-
1 click
-
-
-
-
-
Read Filtered
-
Variation explained? Cpk improved?
-
-
0 clicks
-
-
-
-
-
Save
-
Persists to OneDrive
-
-
1 click
-
-
-
6 actions
-
~5 min
-
-
- - Azure's mindmap provides an alternative drill-down path alongside the Boxplot. +### PWA + +
+
+
+
Paste Data
+
Click "Paste from Excel", Ctrl+V
+
+
2 actions
+
+
+
+
+
Analyze
+
Click "Analyze Data"
+
+
1 click
+
+
+
+
+
Map Columns
+
Outcome + 2 factors + "Start"
+
+
4 clicks
+
+
+
+
+
Read ANOVA
+
Check eta-squared under Boxplot
+
+
0 clicks
+
+
+
+
+
Filter Top Factor
+
Click highest-eta bar
+
+
1 click
+
+
+
+
+
Read Filtered
+
Variation explained? Cpk improved?
+
+
0 clicks
+
+
+
8 actions
+
~5 min
+
+
+ +**Decision:** eta-squared > 50% → primary driver found. Filter isolates the cause. + +### PWA + +### Azure + +
+
+
+
New Analysis
+
Click in project list
+
+
1 click
+
+
+
+
+
Upload File
+
Select CSV from dialog
+
+
2 actions
+
+
+
+
+
Analyze
+
Auto-detects columns
+
+
1 click
+
+
+
+
+
Read ANOVA
+
Check eta-squared under Boxplot
+
+
0 clicks
+
+
+
+
+
Filter Top Factor
+
Click bar or mindmap node
+
+
1 click
+
+
+
+
+
Read Filtered
+
Variation explained? Cpk improved?
+
+
0 clicks
+
+
+
+
+
Save
+
Persists to OneDrive
+
+
1 click
+
+
+
6 actions
+
~5 min
+
+
+ +Azure's mindmap provides an alternative drill-down path alongside the Boxplot. --- @@ -278,145 +286,147 @@ _"What's causing variation?"_ _"Do we meet specs?"_ -=== "PWA" - -
-
-
-
Paste Data
-
Click "Paste from Excel", Ctrl+V
-
-
2 actions
-
-
-
-
-
Analyze
-
Click "Analyze Data"
-
-
1 click
-
-
-
-
-
Map Columns
-
Outcome + factor + "Start"
-
-
3 clicks
-
-
-
-
-
Enter Specs
-
+ Specs, USL, LSL, Apply
-
-
6 actions
-
-
-
-
-
Read Cp/Cpk
-
Capability indices in stats panel
-
-
0 clicks
-
-
-
-
-
View Histogram
-
Click "Histogram" tab
-
-
1 click
-
-
-
-
-
Read Distribution
-
Shape vs spec lines
-
-
0 clicks
-
-
-
13 actions
-
~3 min
-
-
- - **Decision:** Cpk > 1.33 → capable. Cpk < 1.0 → improvement needed. - -=== "Azure" - -
-
-
-
New Analysis
-
Click in project list
-
-
1 click
-
-
-
-
-
Upload File
-
Select CSV from dialog
-
-
2 actions
-
-
-
-
-
Analyze
-
Auto-detects columns
-
-
1 click
-
-
-
-
-
Enter Specs
-
+ Specs, USL, LSL, Apply
-
-
6 actions
-
-
-
-
-
Read Cp/Cpk
-
Capability indices in stats panel
-
-
0 clicks
-
-
-
-
-
View Histogram
-
Click "Histogram" tab
-
-
1 click
-
-
-
-
-
Read Distribution
-
Shape vs spec lines
-
-
0 clicks
-
-
-
-
-
Save
-
Persists to OneDrive
-
-
1 click
-
-
-
12 actions
-
~3 min
-
-
- - Azure saves 1 action via auto-detection, but adds 1 for the Save step. +### PWA + +
+
+
+
Paste Data
+
Click "Paste from Excel", Ctrl+V
+
+
2 actions
+
+
+
+
+
Analyze
+
Click "Analyze Data"
+
+
1 click
+
+
+
+
+
Map Columns
+
Outcome + factor + "Start"
+
+
3 clicks
+
+
+
+
+
Enter Specs
+
+ Specs, USL, LSL, Apply
+
+
6 actions
+
+
+
+
+
Read Cp/Cpk
+
Capability indices in stats panel
+
+
0 clicks
+
+
+
+
+
View Histogram
+
Click "Histogram" tab
+
+
1 click
+
+
+
+
+
Read Distribution
+
Shape vs spec lines
+
+
0 clicks
+
+
+
13 actions
+
~3 min
+
+
+ +**Decision:** Cpk > 1.33 → capable. Cpk < 1.0 → improvement needed. + +### PWA + +### Azure + +
+
+
+
New Analysis
+
Click in project list
+
+
1 click
+
+
+
+
+
Upload File
+
Select CSV from dialog
+
+
2 actions
+
+
+
+
+
Analyze
+
Auto-detects columns
+
+
1 click
+
+
+
+
+
Enter Specs
+
+ Specs, USL, LSL, Apply
+
+
6 actions
+
+
+
+
+
Read Cp/Cpk
+
Capability indices in stats panel
+
+
0 clicks
+
+
+
+
+
View Histogram
+
Click "Histogram" tab
+
+
1 click
+
+
+
+
+
Read Distribution
+
Shape vs spec lines
+
+
0 clicks
+
+
+
+
+
Save
+
Persists to OneDrive
+
+
1 click
+
+
+
12 actions
+
~3 min
+
+
+ +Azure saves 1 action via auto-detection, but adds 1 for the Save step. --- diff --git a/docs/03-features/workflows/quick-check.md b/docs/03-features/workflows/quick-check.md index b482674ec..476df684e 100644 --- a/docs/03-features/workflows/quick-check.md +++ b/docs/03-features/workflows/quick-check.md @@ -1,5 +1,11 @@ +--- +title: 'Quick Check Workflow' +--- + # Quick Check Workflow + + A 5-minute analysis pattern for daily/shift-level monitoring.
@@ -110,8 +116,9 @@ The Quick Check is a rapid assessment pattern for routine monitoring. Use it to | 1.0-1.33 | Warning - monitor closely | | < 1.0 | Alert - investigate now | -!!! tip "Baseline Comparison" +:::tip[Baseline Comparison] Know your typical Cpk. A drop from 1.5 to 1.2 is significant even though 1.2 is "OK." +::: ### Step 3: Boxplot Scan (1 minute) diff --git a/docs/04-cases/avocado/index.md b/docs/04-cases/avocado/index.md index bdfb78663..3e6deae61 100644 --- a/docs/04-cases/avocado/index.md +++ b/docs/04-cases/avocado/index.md @@ -1,3 +1,7 @@ +--- +title: 'Avocado Coating Case' +--- + # Avocado Coating Case **Location:** Post-harvest processing facility diff --git a/docs/04-cases/bottleneck/index.md b/docs/04-cases/bottleneck/index.md index 50a35e7f1..dc05cc8aa 100644 --- a/docs/04-cases/bottleneck/index.md +++ b/docs/04-cases/bottleneck/index.md @@ -1,3 +1,7 @@ +--- +title: 'Bottleneck Case - ESTIEM' +--- + # Bottleneck Case - ESTIEM ## Campaign Position diff --git a/docs/04-cases/coffee/index.md b/docs/04-cases/coffee/index.md index 13092c42c..60ac1a20b 100644 --- a/docs/04-cases/coffee/index.md +++ b/docs/04-cases/coffee/index.md @@ -1,3 +1,7 @@ +--- +title: 'Coffee Washing Station Case' +--- + # Coffee Washing Station Case **Location:** East African coffee washing station diff --git a/docs/04-cases/hospital-ward/index.md b/docs/04-cases/hospital-ward/index.md index 1be79bafd..cf378ef37 100644 --- a/docs/04-cases/hospital-ward/index.md +++ b/docs/04-cases/hospital-ward/index.md @@ -1,3 +1,7 @@ +--- +title: 'Hospital Ward Case - ABB/Practitioner Context' +--- + # Hospital Ward Case - ABB/Practitioner Context ## Campaign Position diff --git a/docs/04-cases/index.md b/docs/04-cases/index.md index f75a83448..1a69d4855 100644 --- a/docs/04-cases/index.md +++ b/docs/04-cases/index.md @@ -1,3 +1,7 @@ +--- +title: 'VaRiScout Lite Case Studies' +--- + # VaRiScout Lite Case Studies ## 12-Week Content Calendar diff --git a/docs/04-cases/machine-utilization/index.md b/docs/04-cases/machine-utilization/index.md index 232201010..832d20f15 100644 --- a/docs/04-cases/machine-utilization/index.md +++ b/docs/04-cases/machine-utilization/index.md @@ -1,3 +1,7 @@ +--- +title: 'Case Study: "Do We Really Need a New Machine?"' +--- + # Case Study: "Do We Really Need a New Machine?" ## Background diff --git a/docs/04-cases/oven-zones/index.md b/docs/04-cases/oven-zones/index.md index a5ac37acd..a86081a94 100644 --- a/docs/04-cases/oven-zones/index.md +++ b/docs/04-cases/oven-zones/index.md @@ -1,3 +1,7 @@ +--- +title: 'Multi-Zone Oven Temperature Control Case Study' +--- + # Multi-Zone Oven Temperature Control Case Study **Difficulty:** Intermediate diff --git a/docs/04-cases/packaging/index.md b/docs/04-cases/packaging/index.md index 7760e67e2..57003e1ea 100644 --- a/docs/04-cases/packaging/index.md +++ b/docs/04-cases/packaging/index.md @@ -1,3 +1,7 @@ +--- +title: 'Packaging Line Case' +--- + # Packaging Line Case **Location:** Food packaging facility, Africa diff --git a/docs/05-technical/architecture.md b/docs/05-technical/architecture.md index 80199a9dc..01c58abeb 100644 --- a/docs/05-technical/architecture.md +++ b/docs/05-technical/architecture.md @@ -1,3 +1,7 @@ +--- +title: 'VariScout: Architecture Overview' +--- + # VariScout: Architecture Overview VariScout Lite is designed as a **browser-first**, **offline-capable** Progressive Web App (PWA) for manufacturing variation analysis. It prioritizes data privacy (no cloud) and works on any device. diff --git a/docs/05-technical/architecture/component-map.md b/docs/05-technical/architecture/component-map.md new file mode 100644 index 000000000..7b8251075 --- /dev/null +++ b/docs/05-technical/architecture/component-map.md @@ -0,0 +1,416 @@ +--- +title: Component Map +description: L3 component views per package — internal modules and their responsibilities +journey-phase: [all] +--- + +# Component Map + + + +L3 component decomposition for each VariScout package. These diagrams are manually maintained Mermaid translations of the canonical architecture model in [`docs/architecture/likec4/`](../../architecture/likec4/). + +## Package Overview + +All packages and their internal module counts at a glance. + +```mermaid +flowchart LR + subgraph core["@variscout/core (9 modules)"] + direction TB + c1["Statistics Engine"] + c2["CSV/Excel Parser"] + c3["Tier System"] + c4["Navigation"] + c5["Types"] + c6["Variation Analysis"] + c7["Glossary"] + c8["Export"] + c9["Utilities"] + end + + subgraph charts["@variscout/charts (14 components)"] + direction TB + ch1["6 Standard Charts"] + ch2["4 Performance Charts"] + ch3["4 Supporting"] + end + + subgraph hooks["@variscout/hooks (13 hooks)"] + direction TB + h1["2 State"] + h2["2 Navigation"] + h3["6 Chart Data"] + h4["1 Export"] + h5["3 Tracking"] + end + + subgraph ui["@variscout/ui (52 components)"] + direction TB + u1["10 Input"] + u2["4 Data Display"] + u3["8 Analysis"] + u4["6 Chart Wrappers"] + u5["4 Navigation"] + u6["8 Findings"] + u7["2 Simulation"] + u8["5 Dashboard"] + u9["3 Utilities"] + end + + subgraph data["@variscout/data (4 datasets)"] + direction TB + d1["coffee"] + d2["journey"] + d3["bottleneck"] + d4["sachets"] + end + + charts --> core + hooks --> core + ui --> core + ui --> hooks + ui --> charts +``` + +--- + +## @variscout/core + +Pure TypeScript — zero React dependencies. The foundation layer that all other packages depend on. + +```mermaid +flowchart TB + subgraph core["@variscout/core"] + stats["Statistics Engine
stats.ts
calculateStats, mean, stddev,
Cp, Cpk, ANOVA, Nelson rules
"] + parser["CSV/Excel Parser
parser.ts
parseCSV, parseExcel,
detectColumns, keyword detection
"] + tier["Tier System
tier.ts
getTier, isPaidTier,
channel limits, plan gating
"] + nav["Navigation
navigation.ts
drill path, filter types,
breadcrumb state
"] + types["Types
types.ts
StatsResult, DataRow,
Finding, AnalysisState
"] + variation["Variation Analysis
variation/
contributions, simulation,
decomposition, Total SS
"] + glossary["Glossary
glossary/
terms, types,
concept definitions
"] + export["Export
export/
CSV export,
chart data formatting
"] + utils["Utilities
utils/
EXIF stripping,
data transforms
"] + end + + stats --> types + parser --> types + variation --> stats + variation --> types + export --> types + glossary --> types + nav --> types + tier --> types +``` + +**Key dependency rule:** `types.ts` is the shared foundation. Statistics and variation analysis are the most complex modules; everything else is relatively independent. + +--- + +## @variscout/charts + +React + Visx chart components. Every chart exports both a responsive wrapper (uses `withParentSize`) and a `*Base` variant for explicit sizing. + +```mermaid +flowchart TB + subgraph standard["Standard Charts"] + ichart["IChart
Individual control chart
UCL/LCL, Nelson violations
"] + boxplot["Boxplot
Category boxplot
violin mode, sorting, annotations
"] + pareto["ParetoChart
Pareto ranking
cumulative line, annotations
"] + capability["CapabilityHistogram
Process capability
normal curve overlay
"] + probability["ProbabilityPlot
Normal probability
distribution assessment
"] + scatter["ScatterPlot
X-Y scatter
trend line
"] + end + + subgraph performance["Performance Charts (multi-measure)"] + perf_ichart["PerformanceIChart
Cpk scatter by channel"] + perf_boxplot["PerformanceBoxplot
Distribution comparison
max 5 channels
"] + perf_pareto["PerformancePareto
Cpk ranking
max 20 channels
"] + perf_capability["PerformanceCapability
Single channel histogram"] + end + + subgraph supporting["Supporting Components"] + stats_table["BoxplotStatsTable
Summary statistics table"] + legend["ChartLegend"] + signature["ChartSignature
Branding for exports"] + sourcebar["ChartSourceBar
Footer branding (free tier)"] + end + + subgraph deps["@variscout/core"] + core_stats["Statistics Engine"] + core_types["Types"] + end + + standard --> core_types + standard --> core_stats + performance --> core_types + performance --> core_stats + supporting --> core_types +``` + +--- + +## @variscout/hooks + +Shared React hooks organized by concern. Depends on `@variscout/core` for types, statistics utilities, and tier logic. + +```mermaid +flowchart TB + subgraph state["State Hooks"] + datastate["useDataState
Shared DataContext
state management
"] + usetier["useTier
License tier state
and limits
"] + end + + subgraph navigation["Navigation Hooks"] + filternav["useFilterNavigation
Multi-select filters
breadcrumbs, drill trail
"] + keyboard["useKeyboardNavigation
Arrow key focus
management
"] + end + + subgraph chartdata["Chart Data Hooks"] + chartscale["useChartScale
Y-axis scale calculation"] + boxplotdata["useBoxplotData
d3 boxplot computation"] + ichartdata["useIChartData
I-Chart data transform"] + margins["useResponsiveChartMargins
Dynamic margins"] + paretodata["useParetoChartData
Pareto data prep"] + dashdata["useDashboardComputedData
Dashboard stats"] + end + + subgraph exporthooks["Export Hooks"] + chartcopy["useChartCopy
Clipboard, PNG, SVG"] + end + + subgraph tracking["Tracking Hooks"] + vartrack["useVariationTracking
Cumulative Total SS
scope tracking
"] + annotation["useAnnotationMode
Chart annotation state"] + violations["useControlViolations
Control chart violation
detection
"] + end + + subgraph deps["@variscout/core"] + core_types["Types"] + core_stats["Statistics Engine"] + core_tier["Tier System"] + end + + state --> core_types + state --> core_tier + navigation --> core_types + chartdata --> core_types + chartdata --> core_stats + tracking --> core_types + tracking --> core_stats +``` + +--- + +## @variscout/ui + +52 shared UI components across 9 categories. Uses the `colorScheme` pattern with `defaultScheme` semantic tokens. Depends on core, hooks, and charts. + +```mermaid +flowchart TB + subgraph input["Input (10)"] + columnmapping["ColumnMapping"] + createfactor["CreateFactorModal"] + measuresel["MeasureColumnSelector"] + chartype["CharacteristicTypeSelector"] + manualentry["ManualEntryBase"] + manualsetup["ManualEntrySetupBase"] + slider["Slider"] + speceditor["SpecEditor"] + specspopover["SpecsPopover"] + pastescreen["PasteScreenBase"] + end + + subgraph datadisplay["Data Display (4)"] + dataquality["DataQualityBanner"] + datatable["DataTableBase"] + perfdetected["PerformanceDetectedModal"] + mobilesheet["MobileCategorySheet"] + end + + subgraph analysis["Analysis (8)"] + anova["AnovaResults"] + statspanel["StatsPanelBase"] + variationbar["VariationBar"] + yaxispopover["YAxisPopover"] + axiseditor["AxisEditor"] + factorsel["FactorSelector"] + investprompt["InvestigationPrompt"] + boxplottoggle["BoxplotDisplayToggle"] + end + + subgraph chartwrappers["Chart Wrappers (6)"] + annotationlayer["ChartAnnotationLayer"] + annotationmenu["AnnotationContextMenu"] + chartcard["ChartCard"] + downloadmenu["ChartDownloadMenu"] + edittitle["EditableChartTitle"] + focusedview["FocusedChartViewBase"] + end + + subgraph navcomps["Navigation (4)"] + breadcrumb["FilterBreadcrumb"] + chipdropdown["FilterChipDropdown"] + contextbar["FilterContextBar"] + selectionpanel["SelectionPanel"] + end + + subgraph findings["Findings (8)"] + findingslog["FindingsLog"] + findingcard["FindingCard"] + findingeditor["FindingEditor"] + findingstatus["FindingStatusBadge"] + findingcomments["FindingComments"] + findingboard["FindingBoardView"] + findingspanel["FindingsPanel"] + findingswindow["FindingsWindow"] + end + + subgraph simulation["Simulation (2)"] + whatif["WhatIfSimulator"] + whatifpage["WhatIfPageBase"] + end + + subgraph dashboard["Dashboard (5)"] + dashgrid["DashboardGrid"] + dashcard["DashboardChartCard"] + focusedcard["FocusedChartCard"] + focusedoverlay["FocusedViewOverlay"] + settingspanel["SettingsPanelBase"] + end + + subgraph utilities["Utilities (3)"] + helptooltip["HelpTooltip"] + upgradeprompt["UpgradePrompt"] + errorboundary["ErrorBoundary"] + end +``` + +### UI dependency flow + +The UI package composes all three lower-level packages: + +```mermaid +flowchart LR + ui["@variscout/ui
(52 components)"] + core["@variscout/core
types, tier"] + hooks["@variscout/hooks
state, navigation, data"] + charts["@variscout/charts
chart components"] + + ui --> core + ui --> hooks + ui --> charts +``` + +--- + +## @variscout/data + +Pre-computed sample datasets. No internal package dependencies — pure TypeScript data files consumed by apps and website. + +```mermaid +flowchart TB + subgraph data["@variscout/data"] + coffee["coffeeSample
Extraction temperature
multi-factor
"] + journey["journeySample
Customer journey
staged analysis
"] + bottleneck["bottleneckSample
Production bottleneck
multi-measure
"] + sachets["sachetsSample
Packaging weight
basic SPC
"] + end + + pwa["apps/pwa"] --> data + azure["apps/azure"] --> data + website["apps/website"] --> data +``` + +--- + +## Cross-Package Component Flow + +How components compose across package boundaries during a typical analysis session: + +```mermaid +flowchart TB + subgraph app["App Layer (pwa / azure)"] + dashboard["Dashboard"] + datacontext["DataContext"] + end + + subgraph ui_layer["@variscout/ui"] + dashgrid["DashboardGrid"] + chartcard["DashboardChartCard"] + statspanel["StatsPanelBase"] + filternav_ui["FilterBreadcrumb"] + findingslog["FindingsLog"] + end + + subgraph hooks_layer["@variscout/hooks"] + datastate["useDataState"] + filternav["useFilterNavigation"] + boxplotdata["useBoxplotData"] + chartscale["useChartScale"] + end + + subgraph charts_layer["@variscout/charts"] + ichart["IChart"] + boxplot["Boxplot"] + pareto["ParetoChart"] + end + + subgraph core_layer["@variscout/core"] + stats["calculateStats"] + parser["parseCSV"] + types["Types"] + end + + dashboard --> dashgrid + dashboard --> chartcard + dashboard --> statspanel + dashboard --> filternav_ui + dashboard --> findingslog + + datacontext --> datastate + filternav_ui --> filternav + + chartcard --> ichart + chartcard --> boxplot + chartcard --> pareto + + boxplotdata --> stats + chartscale --> types + datastate --> parser + datastate --> types + ichart --> types + boxplot --> types + pareto --> types +``` + +--- + +## Source of Truth + +The canonical architecture model is defined in **LikeC4**: + +``` +docs/architecture/likec4/ +├── model.c4 — L1 context + L2 containers + relationships +├── core.c4 — L3 @variscout/core components +├── charts.c4 — L3 @variscout/charts components +├── hooks.c4 — L3 @variscout/hooks components +├── ui.c4 — L3 @variscout/ui components +└── views.c4 — View definitions (L1-L3) +``` + +To render or export: + +- **Interactive browser:** `pnpm docs:c4:serve` +- **Export to Mermaid:** `pnpm docs:c4` + +The Mermaid diagrams in this file are manually maintained translations. When the LikeC4 model changes, update these diagrams to match. + +## See Also + +- [system-map.md](system-map.md) -- L1 Context + L2 Container diagrams +- [shared-packages.md](shared-packages.md) -- Detailed package APIs and export inventories +- [component-patterns.md](component-patterns.md) -- React component conventions and hook patterns +- [data-flow.md](data-flow.md) -- End-to-end data pipeline +- [data-pipeline-map.md](data-pipeline-map.md) -- Step-by-step data transformation pipeline diff --git a/docs/05-technical/architecture/component-patterns.md b/docs/05-technical/architecture/component-patterns.md index af8d6db9d..de9f28820 100644 --- a/docs/05-technical/architecture/component-patterns.md +++ b/docs/05-technical/architecture/component-patterns.md @@ -1,3 +1,7 @@ +--- +title: 'Component Patterns' +--- + # Component Patterns How VariScout's shared hooks work together to enable drill-down, filtering, and analysis. diff --git a/docs/05-technical/architecture/data-flow.md b/docs/05-technical/architecture/data-flow.md index 76610560e..46756f657 100644 --- a/docs/05-technical/architecture/data-flow.md +++ b/docs/05-technical/architecture/data-flow.md @@ -1,3 +1,7 @@ +--- +title: 'Data Flow Architecture' +--- + # Data Flow Architecture How data moves through VariScout from upload to persistence. @@ -307,8 +311,10 @@ flowchart LR ## See Also -- [Component Patterns](component-patterns.md) - Hook integration details -- [Offline-First](offline-first.md) - Persistence strategy -- [Shared Packages](shared-packages.md) - Package responsibilities -- [PWA Storage](../../08-products/pwa/storage.md) - IndexedDB details -- [OneDrive Sync](../../08-products/azure/onedrive-sync.md) - Cloud sync details +- [Data Pipeline Map](data-pipeline-map.md) — End-to-end pipeline with TypeScript interfaces at every boundary +- [System Map](system-map.md) — Package topology and external integrations +- [Component Patterns](component-patterns.md) — Hook integration details +- [Offline-First](offline-first.md) — Persistence strategy +- [Shared Packages](shared-packages.md) — Package responsibilities +- [PWA Storage](../../08-products/pwa/storage.md) — IndexedDB details +- [OneDrive Sync](../../08-products/azure/onedrive-sync.md) — Cloud sync details diff --git a/docs/05-technical/architecture/data-pipeline-map.md b/docs/05-technical/architecture/data-pipeline-map.md new file mode 100644 index 000000000..d7a91beab --- /dev/null +++ b/docs/05-technical/architecture/data-pipeline-map.md @@ -0,0 +1,502 @@ +--- +title: Data Pipeline Map +description: End-to-end data flow from CSV upload through statistics, charts, and AI — with TypeScript interfaces at every boundary +journey-phase: [all] +--- + +# Data Pipeline Map + +End-to-end data flow from CSV upload through statistics, charts, and AI — with TypeScript interfaces at every boundary. Extends [data-flow.md](data-flow.md) with the full pipeline view including AI integration. + +--- + +## 1. Full Pipeline Overview + +```mermaid +flowchart TB + subgraph Input["Data Input"] + CSV[CSV File] --> Parse[parseCSV] + XLS[Excel File] --> ParseXL[parseExcel] + Paste[Paste Data] --> ParseTxt[parseText] + Sample[Sample Dataset] --> Direct[Pre-parsed DataRow array] + end + + subgraph Detection["Column Detection"] + Parse --> DC[detectColumns] + ParseXL --> DC + ParseTxt --> DC + Direct --> DC + DC --> CM[ColumnMapping UI] + end + + subgraph Validation["Validation"] + CM --> VD[validateData] + VD --> DQR[DataQualityReport] + end + + subgraph State["DataContext"] + DQR --> CTX[rawData + specs + filters] + CTX --> FD[filteredData] + end + + subgraph Stats["Statistics Engine"] + FD --> CS[calculateStats] + CS --> SR[StatsResult] + FD --> CA[calculateAnova] + CA --> AR[AnovaResult] + end + + subgraph Charts["Chart Transforms"] + FD --> IC[useIChartData] + IC --> ICP[IChartPoint array] + FD --> BD[useBoxplotData] + BD --> BDD[BoxplotData array] + FD --> PD[useParetoChartData] + PD --> PI[ParetoItem array] + end + + subgraph Presentation["Chart Components"] + ICP --> ICH[I-Chart] + BDD --> BOX[Boxplot] + PI --> PAR[Pareto] + SR --> STP[StatsPanel] + AR --> ANV[AnovaResults] + end + + subgraph Investigation["Findings"] + Presentation --> FND[Finding array] + FND --> Board[FindingBoardView] + end + + subgraph AI["AI Layer (preview)"] + SR --> AIC[buildAIContext] + AR --> AIC + FD --> AIC + FND --> AIC + AIC --> Prompts[3-tier prompt templates] + Prompts --> SVC[AI Service - Azure OpenAI] + SVC --> NB[NarrativeBar] + SVC --> CIC[ChartInsightChips] + SVC --> COS[CoScout - conversational] + end + + subgraph Persistence["Storage"] + CTX --> IDB[(IndexedDB)] + CTX --> OD[("OneDrive (Team plan)")] + end +``` + +--- + +## 2. TypeScript Interfaces at Boundaries + +Each boundary between pipeline stages has a well-defined TypeScript interface. The shapes below are abbreviated from the actual source. + +### Input Boundary + +```typescript +// packages/core/src/types.ts +type DataCellValue = string | number | boolean | null | undefined; + +interface DataRow { + [columnName: string]: DataCellValue; +} +``` + +All parsers (`parseCSV`, `parseText`, `parseExcel`) return `DataRow[]`. + +### Column Detection Boundary + +```typescript +// packages/core/src/parser/types.ts +interface DetectedColumns { + outcome: string | null; + factors: string[]; + timeColumn: string | null; + confidence: 'high' | 'medium' | 'low'; + columnAnalysis: ColumnAnalysis[]; +} +``` + +### Validation Boundary + +```typescript +// packages/core/src/parser/types.ts +interface DataQualityReport { + totalRows: number; + validRows: number; + excludedRows: ExcludedRow[]; + columnIssues: ColumnIssue[]; +} + +interface ExclusionReason { + type: 'missing' | 'non_numeric' | 'empty'; + column: string; + value?: string; +} +``` + +### Stats Boundary + +```typescript +// packages/core/src/types.ts +interface StatsResult { + mean: number; + median: number; + stdDev: number; // Sample std dev (sigma_overall) + sigmaWithin: number; // Within-subgroup std dev (MR-bar / d2) + mrBar: number; // Mean moving range + ucl: number; // Upper Control Limit (mean + 3 * sigmaWithin) + lcl: number; // Lower Control Limit (mean - 3 * sigmaWithin) + cp?: number; // Process Capability (requires USL + LSL) + cpk?: number; // Process Capability accounting for centering + outOfSpecPercentage: number; +} +``` + +### ANOVA Boundary + +```typescript +// packages/core/src/types.ts +interface AnovaResult { + groups: AnovaGroup[]; + ssb: number; // Sum of squares between groups + ssw: number; // Sum of squares within groups + dfBetween: number; // Degrees of freedom (k-1) + dfWithin: number; // Degrees of freedom (N-k) + msb: number; // Mean square between + msw: number; // Mean square within + fStatistic: number; // F = MSB / MSW + pValue: number; + isSignificant: boolean; // p < 0.05 + etaSquared: number; // Effect size (SSB / SST) + insight: string; // Plain-language interpretation +} +``` + +### Filter Boundary + +```typescript +// packages/core/src/navigation.ts +interface FilterAction { + id: string; + type: FilterType; // 'filter' | 'highlight' + source: FilterSource; // Which chart initiated + factor?: string; // Column being filtered + values: (string | number)[]; + rowIndex?: number; // I-Chart row highlight + timestamp: number; +} +``` + +### Finding Boundary + +```typescript +// packages/core/src/findings.ts +type FindingStatus = 'observed' | 'investigating' | 'analyzed'; +type FindingTag = 'key-driver' | 'low-impact'; + +type FindingSource = + | { chart: 'boxplot' | 'pareto'; category: string } + | { chart: 'ichart'; anchorX: number; anchorY: number }; + +interface FindingContext { + activeFilters: Record; + cumulativeScope: number | null; + stats?: { mean: number; median?: number; cpk?: number; samples: number }; +} + +interface Finding { + id: string; + text: string; + createdAt: number; + context: FindingContext; + status: FindingStatus; + tag?: FindingTag; + comments: FindingComment[]; + statusChangedAt: number; + source?: FindingSource; + assignee?: FindingAssignee; +} +``` + +### Persistence Boundary + +```typescript +// packages/hooks/src/types.ts +interface AnalysisState { + version: string; + rawData: DataRow[]; + outcome: string | null; + factors: string[]; + specs: SpecLimits; + measureSpecs?: Record; + filters: Record; + axisSettings: { min?: number; max?: number; scaleMode?: ScaleMode }; + columnAliases?: Record; + valueLabels?: Record>; + displayOptions?: DisplayOptions; + cpkTarget?: number; + stageColumn?: string | null; + stageOrderMode?: StageOrderMode; + isPerformanceMode?: boolean; + measureColumns?: string[]; + selectedMeasure?: string | null; + measureLabel?: string | null; + chartTitles?: Record; + filterStack?: FilterAction[]; + viewState?: ViewState; + findings?: Finding[]; +} +``` + +--- + +## 3. Stats Pipeline Swim Lane + +```mermaid +flowchart LR + subgraph Input["Filtered Data"] + FD["filteredData (DataRow[])"] + SP["specs (SpecLimits)"] + FC["factor (string)"] + end + + subgraph Core["@variscout/core"] + CS["calculateStats(values, specs)"] + CA["calculateAnova(data, factor)"] + end + + subgraph Output["Results"] + SR["StatsResult"] + AR["AnovaResult"] + end + + subgraph Hooks["@variscout/hooks — Chart Transforms"] + ICD["useIChartData()"] + BPD["useBoxplotData()"] + PCD["useParetoChartData()"] + end + + subgraph ChartData["Chart Data Shapes"] + ICP["IChartPoint[]"] + BDD["BoxplotData[]"] + PI["ParetoItem[]"] + end + + FD --> CS + SP --> CS + CS --> SR + + FD --> CA + FC --> CA + CA --> AR + + FD --> ICD + FD --> BPD + FD --> PCD + SR --> ICD + + ICD --> ICP + BPD --> BDD + PCD --> PI +``` + +--- + +## 4. AI Pipeline Swim Lane + +> **Note**: AI features are shipped behind a preview gate. The pipeline components (NarrativeBar, ChartInsightChips, CoScout) are defined in the knowledge layer but not yet wired to live AI services in the main codebase. See the [investigation lifecycle map](../../03-features/workflows/investigation-lifecycle-map.md) for IDEOI phase definitions and CoScout behavior per phase. + +```mermaid +flowchart LR + subgraph Context["Analysis Context"] + SR[StatsResult] + AR[AnovaResult] + FA["FilterAction[]"] + FND["Finding[]"] + Phase["IDEOI Phase"] + end + + subgraph Build["Context Assembly"] + BAC["buildAIContext()"] + end + + subgraph Prompts["Prompt Templates (3-tier)"] + SYS["System prompt (role + rules)"] + DOM["Domain prompt (SPC methodology)"] + CTX["Context prompt (current data state)"] + end + + subgraph Service["AI Service"] + AOAI["Azure OpenAI"] + end + + subgraph Output["AI Output Components"] + NB["NarrativeBar — summary text"] + CIC["ChartInsightChips — per-chart suggestions"] + COS["CoScout — conversational, phase-aware"] + end + + SR --> BAC + AR --> BAC + FA --> BAC + FND --> BAC + Phase --> BAC + + BAC --> SYS + BAC --> DOM + BAC --> CTX + + SYS --> AOAI + DOM --> AOAI + CTX --> AOAI + + AOAI --> NB + AOAI --> CIC + AOAI --> COS +``` + +### IDEOI Phase Mapping + +The AI layer adapts behavior based on the current investigation phase: + +| IDEOI Phase | Trigger | CoScout Behavior | +| ---------------- | -------------------- | ------------------------------------------- | +| **Initial** | Data loaded | Suggests patterns in data | +| **Diverging** | First finding pinned | Suggests possible hypotheses | +| **Evaluating** | Hypothesis linked | Challenges assumptions, suggests validation | +| **Organizing** | Finding analyzed | Summarizes root causes, suggests actions | +| **Implementing** | Actions defined | Tracks progress, projects improvement | + +--- + +## 5. Persistence Pipeline + +```mermaid +flowchart TB + subgraph State["Application State"] + AS["AnalysisState"] + end + + subgraph Local["Local Storage (all platforms)"] + IDB[("IndexedDB")] + end + + subgraph Cloud["Cloud Storage (Team plan only)"] + EA["EasyAuth"] --> TK["Access Token"] + TK --> GRAPH["Graph API"] + GRAPH --> OD[("OneDrive")] + end + + AS -->|"Dexie.js"| IDB + AS -->|"StorageProvider"| EA + IDB <-->|"Bi-directional sync"| OD + + style Cloud fill:#f0f9ff,stroke:#3b82f6 +``` + +`AnalysisState` is the single serializable shape that captures the full state of an analysis session. Key fields for persistence: + +| Field | Purpose | +| ------------------- | -------------------------------------- | +| `rawData` | Original uploaded data rows | +| `specs` | USL, LSL, target specifications | +| `filters` | Active filter selections | +| `filterStack` | Ordered `FilterAction[]` drill trail | +| `findings` | Investigation findings with status | +| `viewState` | Active tab, focused chart, panel state | +| `isPerformanceMode` | Multi-measure mode flag | +| `measureColumns` | Selected measure columns | +| `cpkTarget` | Capability target (default 1.33) | + +--- + +## 6. Filter Recalculation Flow + +A single filter click triggers a cascade of recalculations through the pipeline: + +```mermaid +flowchart TD + A["User clicks Boxplot category"] --> B["useFilterNavigation.addFilter()"] + B --> C["DataContext.dispatch( SET_FILTERS )"] + C --> D["filteredData recomputed"] + D --> E["calculateStats(filteredData)"] + D --> F["calculateAnova(filteredData, nextFactor)"] + E --> G["New StatsResult"] + F --> H["New AnovaResult"] + G --> I["All chart hooks recompute"] + H --> I + I --> J["All chart components re-render"] + J --> K{"AI enabled?"} + K -->|Yes| L["Debounce 500ms"] + L --> M["buildAIContext()"] + M --> N["NarrativeBar updates"] + K -->|No| O["Done"] +``` + +### What gets recomputed + +| Stage | Function / Hook | Output | +| ------------ | ---------------------- | --------------------------------------------- | +| Filter | `useFilterNavigation` | Updated `FilterAction[]` | +| Data | DataContext reducer | `filteredData` (subset of `rawData`) | +| Stats | `calculateStats()` | New `StatsResult` (mean, Cpk, control limits) | +| ANOVA | `calculateAnova()` | New `AnovaResult` (F, p, eta-squared) | +| I-Chart | `useIChartData()` | New `IChartPoint[]` | +| Boxplot | `useBoxplotData()` | New `BoxplotData[]` | +| Pareto | `useParetoChartData()` | New `ParetoItem[]` | +| Variation | `useVariationTracking` | Updated scope fraction and cumulative % | +| AI (preview) | `buildAIContext()` | Refreshed narrative and insights | + +--- + +## 7. Filter Drill-Down Sequence Diagram + +Complete round-trip from user click to updated UI: + +```mermaid +sequenceDiagram + participant User + participant Boxplot + participant useFilterNavigation + participant DataContext + participant Stats as calculateStats + participant ANOVA as calculateAnova + participant Charts as Chart hooks + participant AI as AI layer (debounced) + + User->>Boxplot: Click category bar + Boxplot->>useFilterNavigation: addFilter(factor, value) + useFilterNavigation->>DataContext: dispatch SET_FILTERS + DataContext->>DataContext: Recompute filteredData + + par Statistics + DataContext->>Stats: calculateStats(filteredData, specs) + Stats-->>DataContext: StatsResult + and ANOVA + DataContext->>ANOVA: calculateAnova(filteredData, nextFactor) + ANOVA-->>DataContext: AnovaResult + end + + DataContext-->>Charts: New props (filteredData, stats, anova) + Charts->>Charts: useIChartData + useBoxplotData + useParetoChartData + + Charts-->>Boxplot: Re-render with drill-down data + Note over Boxplot: Next factor level displayed + + opt AI preview enabled + DataContext-->>AI: AIContext (debounced 500ms) + AI-->>User: NarrativeBar update + end +``` + +--- + +## 8. See Also + +- [Data Flow](data-flow.md) -- detailed input/validation stages and platform-specific flows +- [System Map](system-map.md) -- package topology and dependency graph +- [Component Patterns](component-patterns.md) -- hook integration details and DataContext structure +- [Investigation Lifecycle Map](../../03-features/workflows/investigation-lifecycle-map.md) -- IDEOI phases and CoScout behavior +- [Investigation to Action](../../03-features/workflows/investigation-to-action.md) -- findings workflow specification diff --git a/docs/05-technical/architecture/generated/ChartsComponents.mmd b/docs/05-technical/architecture/generated/ChartsComponents.mmd new file mode 100644 index 000000000..1da9a77d0 --- /dev/null +++ b/docs/05-technical/architecture/generated/ChartsComponents.mmd @@ -0,0 +1,31 @@ +--- +title: "charts Components (C4 L3)" +--- +graph TB + subgraph VariscoutCharts["`@variscout/charts`"] + VariscoutCharts.Ichart@{ shape: rectangle, label: "IChart" } + VariscoutCharts.Boxplot@{ shape: rectangle, label: "Boxplot" } + VariscoutCharts.Pareto@{ shape: rectangle, label: "ParetoChart" } + VariscoutCharts.Capability@{ shape: rectangle, label: "CapabilityHistogram" } + VariscoutCharts.Probability@{ shape: rectangle, label: "ProbabilityPlot" } + VariscoutCharts.Scatter@{ shape: rectangle, label: "ScatterPlot" } + VariscoutCharts.PerfIchart@{ shape: rectangle, label: "PerformanceIChart" } + VariscoutCharts.PerfBoxplot@{ shape: rectangle, label: "PerformanceBoxplot" } + VariscoutCharts.PerfPareto@{ shape: rectangle, label: "PerformancePareto" } + VariscoutCharts.PerfCapability@{ shape: rectangle, label: "PerformanceCapability" } + VariscoutCharts.StatsTable@{ shape: rectangle, label: "BoxplotStatsTable" } + VariscoutCharts.Legend@{ shape: rectangle, label: "ChartLegend" } + VariscoutCharts.Signature@{ shape: rectangle, label: "ChartSignature" } + VariscoutCharts.SourceBar@{ shape: rectangle, label: "ChartSourceBar" } + end + VariscoutCore@{ shape: rectangle, label: "@variscout/core" } + VariscoutCharts.Ichart -. "`[...]`" .-> VariscoutCore + VariscoutCharts.Boxplot -. "`uses DataRow`" .-> VariscoutCore + VariscoutCharts.Pareto -. "`uses DataRow`" .-> VariscoutCore + VariscoutCharts.Capability -. "`uses Cp/Cpk`" .-> VariscoutCore + VariscoutCharts.Probability -. "`uses distribution`" .-> VariscoutCore + VariscoutCharts.PerfIchart -. "`uses ChannelResult`" .-> VariscoutCore + VariscoutCharts.PerfBoxplot -. "`uses ChannelResult`" .-> VariscoutCore + VariscoutCharts.PerfPareto -. "`uses ChannelResult`" .-> VariscoutCore + VariscoutCharts.PerfCapability -. "`uses Cp/Cpk`" .-> VariscoutCore + VariscoutCharts.SourceBar -. "`checks isPaidTier`" .-> VariscoutCore diff --git a/docs/05-technical/architecture/generated/Containers.mmd b/docs/05-technical/architecture/generated/Containers.mmd new file mode 100644 index 000000000..e4b9f1aa3 --- /dev/null +++ b/docs/05-technical/architecture/generated/Containers.mmd @@ -0,0 +1,41 @@ +--- +title: "VariScout Container Diagram (C4 L2)" +--- +graph TB + subgraph Variscout["`VariScout`"] + Variscout.Pwa@{ shape: rectangle, label: "apps/pwa" } + Variscout.Website@{ shape: rectangle, label: "apps/website" } + Variscout.Infra@{ shape: rectangle, label: "infra/" } + Variscout.Azure@{ shape: rectangle, label: "apps/azure" } + Variscout.Ui@{ shape: rectangle, label: "@variscout/ui" } + Variscout.Data@{ shape: rectangle, label: "@variscout/data" } + Variscout.Charts@{ shape: rectangle, label: "@variscout/charts" } + Variscout.Hooks@{ shape: rectangle, label: "@variscout/hooks" } + Variscout.Core@{ shape: rectangle, label: "@variscout/core" } + end + Azuread@{ shape: rectangle, label: "Azure AD" } + Onedrive@{ shape: rectangle, label: "Microsoft OneDrive" } + Teams@{ shape: rectangle, label: "Microsoft Teams" } + Aisearch@{ shape: rectangle, label: "Azure AI Search" } + Variscout.Charts -. "`imports types, stats`" .-> Variscout.Core + Variscout.Ui -. "`wraps chart components`" .-> Variscout.Charts + Variscout.Pwa -. "`imports`" .-> Variscout.Charts + Variscout.Azure -. "`imports`" .-> Variscout.Charts + Variscout.Website -. "`embeds demos`" .-> Variscout.Charts + Variscout.Hooks -. "`imports types, utilities, tier`" .-> Variscout.Core + Variscout.Ui -. "`imports types, tier`" .-> Variscout.Core + Variscout.Pwa -. "`imports`" .-> Variscout.Core + Variscout.Azure -. "`imports`" .-> Variscout.Core + Variscout.Ui -. "`composes hooks`" .-> Variscout.Hooks + Variscout.Pwa -. "`imports`" .-> Variscout.Hooks + Variscout.Azure -. "`imports`" .-> Variscout.Hooks + Variscout.Pwa -. "`imports`" .-> Variscout.Ui + Variscout.Azure -. "`imports`" .-> Variscout.Ui + Variscout.Pwa -. "`loads samples`" .-> Variscout.Data + Variscout.Azure -. "`loads samples`" .-> Variscout.Data + Variscout.Website -. "`loads samples`" .-> Variscout.Data + Variscout.Infra -. "`deploys`" .-> Variscout.Azure + Variscout.Azure -. "`EasyAuth authentication`" .-> Azuread + Variscout.Azure -. "`OneDrive sync (Team plan)`" .-> Onedrive + Variscout.Azure -. "`Teams SDK integration`" .-> Teams + Variscout.Azure -. "`AI search queries`" .-> Aisearch diff --git a/docs/05-technical/architecture/generated/CoreComponents.mmd b/docs/05-technical/architecture/generated/CoreComponents.mmd new file mode 100644 index 000000000..733b1dc7e --- /dev/null +++ b/docs/05-technical/architecture/generated/CoreComponents.mmd @@ -0,0 +1,34 @@ +--- +title: "core Components (C4 L3)" +--- +graph TB + VariscoutCharts@{ shape: rectangle, label: "@variscout/charts" } + VariscoutHooks@{ shape: rectangle, label: "@variscout/hooks" } + subgraph VariscoutCore["`@variscout/core`"] + VariscoutCore.Tier@{ shape: rectangle, label: "Tier System" } + VariscoutCore.Parser@{ shape: rectangle, label: "CSV/Excel Parser" } + VariscoutCore.Navigation@{ shape: rectangle, label: "Navigation" } + VariscoutCore.Variation@{ shape: rectangle, label: "Variation Analysis" } + VariscoutCore.Glossary@{ shape: rectangle, label: "Glossary" } + VariscoutCore.Export@{ shape: rectangle, label: "Export" } + VariscoutCore.Stats@{ shape: rectangle, label: "Statistics Engine" } + VariscoutCore.Types@{ shape: rectangle, label: "Types" } + VariscoutCore.Utils@{ shape: rectangle, label: "Utilities" } + end + VariscoutCharts -. "`[...]`" .-> VariscoutCore.Stats + VariscoutCharts -. "`checks isPaidTier`" .-> VariscoutCore.Tier + VariscoutCharts -. "`[...]`" .-> VariscoutCore.Types + VariscoutHooks -. "`[...]`" .-> VariscoutCore.Stats + VariscoutHooks -. "`invokes parseCSV`" .-> VariscoutCore.Parser + VariscoutHooks -. "`uses getTier`" .-> VariscoutCore.Tier + VariscoutHooks -. "`uses filter types`" .-> VariscoutCore.Navigation + VariscoutHooks -. "`[...]`" .-> VariscoutCore.Types + VariscoutHooks -. "`uses contributions`" .-> VariscoutCore.Variation + VariscoutCore.Stats -. "`uses`" .-> VariscoutCore.Types + VariscoutCore.Variation -. "`uses`" .-> VariscoutCore.Stats + VariscoutCore.Parser -. "`uses`" .-> VariscoutCore.Types + VariscoutCore.Tier -. "`uses`" .-> VariscoutCore.Types + VariscoutCore.Navigation -. "`uses`" .-> VariscoutCore.Types + VariscoutCore.Variation -. "`uses`" .-> VariscoutCore.Types + VariscoutCore.Glossary -. "`uses`" .-> VariscoutCore.Types + VariscoutCore.Export -. "`uses`" .-> VariscoutCore.Types diff --git a/docs/05-technical/architecture/generated/DataComponents.mmd b/docs/05-technical/architecture/generated/DataComponents.mmd new file mode 100644 index 000000000..9a53c4d67 --- /dev/null +++ b/docs/05-technical/architecture/generated/DataComponents.mmd @@ -0,0 +1,11 @@ +--- +title: "data Components (C4 L3)" +--- +graph TB + VariscoutPwa@{ shape: rectangle, label: "apps/pwa" } + VariscoutAzure@{ shape: rectangle, label: "apps/azure" } + VariscoutWebsite@{ shape: rectangle, label: "apps/website" } + VariscoutData@{ shape: rectangle, label: "@variscout/data" } + VariscoutPwa -. "`loads samples`" .-> VariscoutData + VariscoutAzure -. "`loads samples`" .-> VariscoutData + VariscoutWebsite -. "`loads samples`" .-> VariscoutData diff --git a/docs/05-technical/architecture/generated/HooksComponents.mmd b/docs/05-technical/architecture/generated/HooksComponents.mmd new file mode 100644 index 000000000..51401ec83 --- /dev/null +++ b/docs/05-technical/architecture/generated/HooksComponents.mmd @@ -0,0 +1,29 @@ +--- +title: "hooks Components (C4 L3)" +--- +graph TB + subgraph VariscoutHooks["`@variscout/hooks`"] + VariscoutHooks.DataState@{ shape: rectangle, label: "useDataState" } + VariscoutHooks.UseTier@{ shape: rectangle, label: "useTier" } + VariscoutHooks.FilterNav@{ shape: rectangle, label: "useFilterNavigation" } + VariscoutHooks.Keyboard@{ shape: rectangle, label: "useKeyboardNavigation" } + VariscoutHooks.ChartScale@{ shape: rectangle, label: "useChartScale" } + VariscoutHooks.BoxplotData@{ shape: rectangle, label: "useBoxplotData" } + VariscoutHooks.IchartData@{ shape: rectangle, label: "useIChartData" } + VariscoutHooks.Margins@{ shape: rectangle, label: "useResponsiveChartMargins" } + VariscoutHooks.ParetoData@{ shape: rectangle, label: "useParetoChartData" } + VariscoutHooks.DashboardData@{ shape: rectangle, label: "useDashboardComputedData" } + VariscoutHooks.ChartCopy@{ shape: rectangle, label: "useChartCopy" } + VariscoutHooks.VariationTracking@{ shape: rectangle, label: "useVariationTracking" } + VariscoutHooks.AnnotationMode@{ shape: rectangle, label: "useAnnotationMode" } + VariscoutHooks.ControlViolations@{ shape: rectangle, label: "useControlViolations" } + end + VariscoutCore@{ shape: rectangle, label: "@variscout/core" } + VariscoutHooks.DataState -. "`[...]`" .-> VariscoutCore + VariscoutHooks.UseTier -. "`uses getTier`" .-> VariscoutCore + VariscoutHooks.FilterNav -. "`uses filter types`" .-> VariscoutCore + VariscoutHooks.ChartScale -. "`uses StatsResult`" .-> VariscoutCore + VariscoutHooks.BoxplotData -. "`computes quartiles`" .-> VariscoutCore + VariscoutHooks.IchartData -. "`computes control limits`" .-> VariscoutCore + VariscoutHooks.VariationTracking -. "`uses contributions`" .-> VariscoutCore + VariscoutHooks.ControlViolations -. "`uses Nelson rules`" .-> VariscoutCore diff --git a/docs/05-technical/architecture/generated/SystemContext.mmd b/docs/05-technical/architecture/generated/SystemContext.mmd new file mode 100644 index 000000000..df6a63418 --- /dev/null +++ b/docs/05-technical/architecture/generated/SystemContext.mmd @@ -0,0 +1,41 @@ +--- +title: "VariScout System Context (C4 L1)" +--- +graph TB + subgraph Variscout["`VariScout`"] + Variscout.Pwa@{ shape: rectangle, label: "apps/pwa" } + Variscout.Website@{ shape: rectangle, label: "apps/website" } + Variscout.Infra@{ shape: rectangle, label: "infra/" } + Variscout.Azure@{ shape: rectangle, label: "apps/azure" } + Variscout.Ui@{ shape: rectangle, label: "@variscout/ui" } + Variscout.Data@{ shape: rectangle, label: "@variscout/data" } + Variscout.Charts@{ shape: rectangle, label: "@variscout/charts" } + Variscout.Hooks@{ shape: rectangle, label: "@variscout/hooks" } + Variscout.Core@{ shape: rectangle, label: "@variscout/core" } + end + Azuread@{ shape: rectangle, label: "Azure AD" } + Onedrive@{ shape: rectangle, label: "Microsoft OneDrive" } + Teams@{ shape: rectangle, label: "Microsoft Teams" } + Aisearch@{ shape: rectangle, label: "Azure AI Search" } + Variscout.Charts -. "`imports types, stats`" .-> Variscout.Core + Variscout.Ui -. "`wraps chart components`" .-> Variscout.Charts + Variscout.Pwa -. "`imports`" .-> Variscout.Charts + Variscout.Azure -. "`imports`" .-> Variscout.Charts + Variscout.Website -. "`embeds demos`" .-> Variscout.Charts + Variscout.Hooks -. "`imports types, utilities, tier`" .-> Variscout.Core + Variscout.Ui -. "`imports types, tier`" .-> Variscout.Core + Variscout.Pwa -. "`imports`" .-> Variscout.Core + Variscout.Azure -. "`imports`" .-> Variscout.Core + Variscout.Ui -. "`composes hooks`" .-> Variscout.Hooks + Variscout.Pwa -. "`imports`" .-> Variscout.Hooks + Variscout.Azure -. "`imports`" .-> Variscout.Hooks + Variscout.Pwa -. "`imports`" .-> Variscout.Ui + Variscout.Azure -. "`imports`" .-> Variscout.Ui + Variscout.Pwa -. "`loads samples`" .-> Variscout.Data + Variscout.Azure -. "`loads samples`" .-> Variscout.Data + Variscout.Website -. "`loads samples`" .-> Variscout.Data + Variscout.Infra -. "`deploys`" .-> Variscout.Azure + Variscout.Azure -. "`EasyAuth authentication`" .-> Azuread + Variscout.Azure -. "`OneDrive sync (Team plan)`" .-> Onedrive + Variscout.Azure -. "`Teams SDK integration`" .-> Teams + Variscout.Azure -. "`AI search queries`" .-> Aisearch diff --git a/docs/05-technical/architecture/generated/UIComponents.mmd b/docs/05-technical/architecture/generated/UIComponents.mmd new file mode 100644 index 000000000..ea82fc7a4 --- /dev/null +++ b/docs/05-technical/architecture/generated/UIComponents.mmd @@ -0,0 +1,56 @@ +--- +title: "ui Components (C4 L3)" +--- +graph TB + subgraph VariscoutUi["`@variscout/ui`"] + VariscoutUi.ColumnMapping@{ shape: rectangle, label: "ColumnMapping" } + VariscoutUi.CreateFactor@{ shape: rectangle, label: "CreateFactorModal" } + VariscoutUi.MeasureSel@{ shape: rectangle, label: "MeasureColumnSelector" } + VariscoutUi.CharType@{ shape: rectangle, label: "CharacteristicTypeSelector" } + VariscoutUi.ManualEntry@{ shape: rectangle, label: "ManualEntryBase" } + VariscoutUi.ManualSetup@{ shape: rectangle, label: "ManualEntrySetupBase" } + VariscoutUi.Slider@{ shape: rectangle, label: "Slider" } + VariscoutUi.SpecEditor@{ shape: rectangle, label: "SpecEditor" } + VariscoutUi.SpecsPopover@{ shape: rectangle, label: "SpecsPopover" } + VariscoutUi.PasteScreen@{ shape: rectangle, label: "PasteScreenBase" } + VariscoutUi.DataQuality@{ shape: rectangle, label: "DataQualityBanner" } + VariscoutUi.DataTable@{ shape: rectangle, label: "DataTableBase" } + VariscoutUi.PerfDetected@{ shape: rectangle, label: "PerformanceDetectedModal" } + VariscoutUi.MobileSheet@{ shape: rectangle, label: "MobileCategorySheet" } + VariscoutUi.Anova@{ shape: rectangle, label: "AnovaResults" } + VariscoutUi.StatsPanel@{ shape: rectangle, label: "StatsPanelBase" } + VariscoutUi.VariationBar@{ shape: rectangle, label: "VariationBar" } + VariscoutUi.YAxisPopover@{ shape: rectangle, label: "YAxisPopover" } + VariscoutUi.AxisEditor@{ shape: rectangle, label: "AxisEditor" } + VariscoutUi.FactorSel@{ shape: rectangle, label: "FactorSelector" } + VariscoutUi.InvestPrompt@{ shape: rectangle, label: "InvestigationPrompt" } + VariscoutUi.BoxplotToggle@{ shape: rectangle, label: "BoxplotDisplayToggle" } + VariscoutUi.AnnotationLayer@{ shape: rectangle, label: "ChartAnnotationLayer" } + VariscoutUi.AnnotationMenu@{ shape: rectangle, label: "AnnotationContextMenu" } + VariscoutUi.ChartCard@{ shape: rectangle, label: "ChartCard" } + VariscoutUi.DownloadMenu@{ shape: rectangle, label: "ChartDownloadMenu" } + VariscoutUi.EditTitle@{ shape: rectangle, label: "EditableChartTitle" } + VariscoutUi.FocusedView@{ shape: rectangle, label: "FocusedChartViewBase" } + VariscoutUi.Breadcrumb@{ shape: rectangle, label: "FilterBreadcrumb" } + VariscoutUi.ChipDropdown@{ shape: rectangle, label: "FilterChipDropdown" } + VariscoutUi.ContextBar@{ shape: rectangle, label: "FilterContextBar" } + VariscoutUi.SelectionPanel@{ shape: rectangle, label: "SelectionPanel" } + VariscoutUi.FindingsLog@{ shape: rectangle, label: "FindingsLog" } + VariscoutUi.FindingCard@{ shape: rectangle, label: "FindingCard" } + VariscoutUi.FindingEditor@{ shape: rectangle, label: "FindingEditor" } + VariscoutUi.FindingStatus@{ shape: rectangle, label: "FindingStatusBadge" } + VariscoutUi.FindingComments@{ shape: rectangle, label: "FindingComments" } + VariscoutUi.FindingBoard@{ shape: rectangle, label: "FindingBoardView" } + VariscoutUi.FindingsPanel@{ shape: rectangle, label: "FindingsPanel" } + VariscoutUi.FindingsWindow@{ shape: rectangle, label: "FindingsWindow" } + VariscoutUi.WhatIf@{ shape: rectangle, label: "WhatIfSimulator" } + VariscoutUi.WhatIfPage@{ shape: rectangle, label: "WhatIfPageBase" } + VariscoutUi.DashGrid@{ shape: rectangle, label: "DashboardGrid" } + VariscoutUi.DashCard@{ shape: rectangle, label: "DashboardChartCard" } + VariscoutUi.FocusedCard@{ shape: rectangle, label: "FocusedChartCard" } + VariscoutUi.FocusedOverlay@{ shape: rectangle, label: "FocusedViewOverlay" } + VariscoutUi.SettingsPanel@{ shape: rectangle, label: "SettingsPanelBase" } + VariscoutUi.HelpTooltip@{ shape: rectangle, label: "HelpTooltip" } + VariscoutUi.UpgradePrompt@{ shape: rectangle, label: "UpgradePrompt" } + VariscoutUi.ErrorBoundary@{ shape: rectangle, label: "ErrorBoundary" } + end diff --git a/docs/05-technical/architecture/generated/index.mmd b/docs/05-technical/architecture/generated/index.mmd new file mode 100644 index 000000000..ad3c70c69 --- /dev/null +++ b/docs/05-technical/architecture/generated/index.mmd @@ -0,0 +1,16 @@ +--- +title: "Landscape view" +--- +graph TB + Analyst@{ shape: rectangle, label: "Quality Analyst" } + Variscout@{ shape: rectangle, label: "VariScout" } + Azuread@{ shape: rectangle, label: "Azure AD" } + Onedrive@{ shape: rectangle, label: "Microsoft OneDrive" } + Teams@{ shape: rectangle, label: "Microsoft Teams" } + Aisearch@{ shape: rectangle, label: "Azure AI Search" } + Variscout -. "`Authenticates via EasyAuth`" .-> Azuread + Variscout -. "`Syncs projects (Team plan)`" .-> Onedrive + Variscout -. "`Embeds as channel tab, captures photos`" .-> Teams + Variscout -. "`Queries for AI-assisted analysis`" .-> Aisearch + Analyst -. "`Uploads data, reviews charts, +investigates variation`" .-> Variscout diff --git a/docs/05-technical/architecture/monorepo.md b/docs/05-technical/architecture/monorepo.md index 5159ce8d0..e201ca8dd 100644 --- a/docs/05-technical/architecture/monorepo.md +++ b/docs/05-technical/architecture/monorepo.md @@ -1,3 +1,7 @@ +--- +title: 'Monorepo Architecture' +--- + # Monorepo Architecture VariScout uses a pnpm workspaces monorepo to share code across multiple applications. diff --git a/docs/05-technical/architecture/offline-first.md b/docs/05-technical/architecture/offline-first.md index 95943ccaa..6fec6ea7b 100644 --- a/docs/05-technical/architecture/offline-first.md +++ b/docs/05-technical/architecture/offline-first.md @@ -1,3 +1,7 @@ +--- +title: 'Offline-First Architecture' +--- + # Offline-First Architecture VariScout is designed to work without internet access after the initial load. diff --git a/docs/05-technical/architecture/shared-packages.md b/docs/05-technical/architecture/shared-packages.md index ff7c6637b..ebf8cec4f 100644 --- a/docs/05-technical/architecture/shared-packages.md +++ b/docs/05-technical/architecture/shared-packages.md @@ -1,3 +1,7 @@ +--- +title: 'Shared Packages' +--- + # Shared Packages The monorepo contains several shared packages that provide common functionality across apps. diff --git a/docs/05-technical/architecture/system-map.md b/docs/05-technical/architecture/system-map.md new file mode 100644 index 000000000..d95c6d1ce --- /dev/null +++ b/docs/05-technical/architecture/system-map.md @@ -0,0 +1,122 @@ +--- +title: System Map +description: Visual architecture overview of VariScout's packages, apps, and external integrations +journey-phase: [all] +--- + +# System Map + +Visual entry point for understanding VariScout's architecture. Start here, then drill into component-level docs linked below. + +## Context Diagram (C4 L1) + +Who uses VariScout and what external systems does it touch? + +```mermaid +C4Context + title VariScout System Context + + Person(analyst, "Quality Analyst", "Analyses process variation using control charts, capability indices, and Pareto rankings") + + System(variscout, "VariScout", "Offline-first variation analysis tool (PWA + Azure App)") + + System_Ext(azuread, "Azure AD", "EasyAuth identity provider") + System_Ext(onedrive, "Microsoft OneDrive", "Cloud file sync via Graph API") + System_Ext(teams, "Microsoft Teams", "Channel tabs, SSO, photo capture") + System_Ext(aisearch, "Azure AI Search", "AI-powered analysis suggestions") + + Rel(analyst, variscout, "Uploads data, reviews charts, investigates variation") + Rel(variscout, azuread, "Authenticates via EasyAuth") + Rel(variscout, onedrive, "Syncs projects (Team plan)") + Rel(variscout, teams, "Embeds as channel tab, captures photos") + Rel(variscout, aisearch, "Queries for AI-assisted analysis") +``` + +## Container Diagram (C4 L2) + +Monorepo packages, apps, and their dependency relationships. + +```mermaid +flowchart TB + subgraph apps["Apps"] + pwa["apps/pwa
React + Vite
FREE demo tool"] + azure["apps/azure
React + Vite
Azure Team App"] + website["apps/website
Astro + React Islands
Marketing site"] + end + + subgraph packages["Packages"] + ui["@variscout/ui
Shared UI components"] + hooks["@variscout/hooks
Shared React hooks"] + charts["@variscout/charts
React + Visx charts"] + core["@variscout/core
Pure logic, stats, parser, tier"] + data["@variscout/data
Sample datasets"] + end + + subgraph infra["Infrastructure"] + arm["infra/mainTemplate.json
ARM template"] + end + + subgraph external["External Systems"] + azuread["Azure AD"] + onedrive["OneDrive"] + teams["Teams"] + aisearch["Azure AI Search"] + end + + %% App dependencies + pwa --> core & charts & hooks & ui & data + azure --> core & charts & hooks & ui & data + website --> charts & data + + %% Package dependencies + ui --> core & hooks & charts + hooks --> core + charts --> core + + %% External integrations (Azure app only) + azure -.-> azuread & onedrive & teams & aisearch + arm -.-> azure +``` + +### Key dependency rules + +- **Apps** import from packages; packages never import from apps. +- **`@variscout/core`** has zero React dependencies (pure TypeScript + d3-array, exceljs, papaparse). +- **`@variscout/data`** has no internal package dependencies. +- **`@variscout/ui`** is the highest-level shared package, composing core, hooks, and charts. + +## Package Responsibilities + +| Package | Role | Key exports | Docs | +| ------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------ | ---------------------------------------------- | +| `@variscout/core` | Statistics engine, CSV/Excel parser, tier system, glossary, types | `calculateStats`, `parseCSV`, `getTier`, `GlossaryTerm` | [shared-packages.md](shared-packages.md) | +| `@variscout/charts` | Visx chart components (I-Chart, Boxplot, Pareto, Performance suite) | `IChart`, `Boxplot`, `ParetoChart`, `PerformanceIChart`, `useChartTheme` | [component-patterns.md](component-patterns.md) | +| `@variscout/data` | Pre-computed sample datasets for demo and testing | `coffeeSample`, `journeySample`, `bottleneckSample` | [shared-packages.md](shared-packages.md) | +| `@variscout/hooks` | Shared React hooks for state, navigation, data transforms | `useDataState`, `useFilterNavigation`, `useChartScale`, `useTier` | [component-patterns.md](component-patterns.md) | +| `@variscout/ui` | Shared UI components with colorScheme theming pattern | `StatsPanelBase`, `FindingsLog`, `DashboardGrid`, `WhatIfSimulator` | [component-patterns.md](component-patterns.md) | + +## App Responsibilities + +| App | Distribution | Technology | Key characteristics | +| -------------- | ----------------- | ----------------------- | ------------------------------------------------------------------ | +| `apps/pwa` | Public URL (free) | React + Vite PWA | Session-only storage, 3 factors max, 50K rows | +| `apps/azure` | Azure Marketplace | React + Vite + EasyAuth | IndexedDB + OneDrive sync, 6 factors, 100K rows, Teams integration | +| `apps/website` | Public URL | Astro + React Islands | Static marketing site with embedded chart demos | + +## Infrastructure + +| Component | Purpose | Docs | +| -------------------------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------- | +| `infra/mainTemplate.json` | ARM template for Azure Marketplace Managed Application deployment | [arm-template.md](../../08-products/azure/arm-template.md) | +| `.github/workflows/deploy-azure-staging.yml` | CI/CD pipeline: build + OIDC deploy to staging | [deployment.md](../implementation/deployment.md) | + +## See Also + +- [component-map.md](component-map.md) -- L3 component views per package (internal modules) +- [data-flow.md](data-flow.md) -- End-to-end data pipeline from ingestion to chart rendering +- [shared-packages.md](shared-packages.md) -- Detailed package APIs and export inventories +- [monorepo.md](monorepo.md) -- Build system, workspace configuration, import rules +- [component-patterns.md](component-patterns.md) -- React component conventions and hook patterns +- [offline-first.md](offline-first.md) -- Storage strategy, sync architecture, conflict resolution +- [data-pipeline-map.md](data-pipeline-map.md) -- Step-by-step data transformation pipeline +- [`docs/architecture/likec4/`](../../architecture/likec4/) -- LikeC4 model: canonical source of truth for C4 architecture topology (L1-L3) diff --git a/docs/05-technical/documentation-methodology.md b/docs/05-technical/documentation-methodology.md new file mode 100644 index 000000000..3c7fd8d67 --- /dev/null +++ b/docs/05-technical/documentation-methodology.md @@ -0,0 +1,418 @@ +--- +title: Documentation Methodology +description: How VariScout's 100+ docs are organized — grounded in Diataxis, C4, Docs-as-Code, and the 4-phase analysis journey +journey-phase: [all] +--- + +# Documentation Methodology + +```mermaid +flowchart TB + subgraph L1["Layer 1 — AI Agent Routing"] + CLAUDE["CLAUDE.md\ntask-to-doc table"] + end + + subgraph L2["Layer 2 — Visual Maps"] + SM["system-map.md"] + JM["analysis-journey-map.md"] + PM["data-pipeline-map.md"] + LM["investigation-lifecycle-map.md"] + end + + subgraph L3["Layer 3 — Workflow Docs"] + FL["Four Lenses"] + DD["Drill-Down"] + QC["Quick Check"] + DV["Deep Dive"] + IA["Investigation to Action"] + end + + subgraph L4["Layer 4 — Feature Docs"] + CH["Charts"] + DA["Data"] + NV["Navigation"] + LN["Learning"] + end + + subgraph L5["Layer 5 — Technical Reference"] + AR["Architecture"] + API["TypeDoc API"] + ADR["ADRs"] + end + + subgraph L6["Layer 6 — Product Specs"] + PWA["PWA"] + AZ["Azure"] + WEB["Website"] + end + + CLAUDE --> L2 + L2 --> L3 + L3 --> L4 + L4 --> L5 + L5 --> L6 + + style L1 fill:#3b82f6,color:#fff + style L2 fill:#22c55e,color:#fff + style L3 fill:#f59e0b,color:#fff + style L4 fill:#8b5cf6,color:#fff +``` + +Six layers, each serving a different reader at a different zoom level. AI agents enter at Layer 1 (CLAUDE.md routing table). Developers enter at Layer 2 (visual maps) or Layer 3 (workflows). Product managers enter at Layer 6 (product specs). + +--- + +## Why Document the Documentation? + +VariScout's documentation serves three audiences simultaneously: + +1. **AI coding agents** — need structured, cross-linked docs to navigate the codebase. CLAUDE.md's task-to-doc table routes agents to the right file in one hop. +2. **Human developers** — need visual maps and architecture docs to understand the system. Mermaid diagrams provide sub-60-second comprehension. +3. **Quality analysts** — need workflow docs that mirror their real analysis journey. The 4-phase model (Frame → Scout → Investigate → Improve) organizes features around how work actually happens. + +With 100+ markdown files across 8 doc sections, a governing methodology prevents drift, duplication, and orphaned docs. + +--- + +## Foundations: Industry Frameworks Applied + +VariScout's docs align naturally with three established frameworks. This wasn't retrofitted — the structure emerged from building docs alongside code. + +### Diataxis + +[Diataxis](https://diataxis.fr/) classifies documentation into four types by purpose. VariScout maps cleanly: + +| Diataxis Type | VariScout Section | Examples | +| ---------------------------------------- | --------------------------------------------------------------- | -------------------------------------------------- | +| **Tutorials** (learning-oriented) | `docs/04-cases/` — case studies with teaching briefs | Coffee extraction, Packaging weight, Hospital Ward | +| **How-to Guides** (task-oriented) | `docs/03-features/workflows/` — step-by-step analysis protocols | Quick Check, Deep Dive, Drill-Down, Four Lenses | +| **Reference** (information-oriented) | `docs/05-technical/`, TypeDoc API docs | Architecture, data-flow, api/core/ | +| **Explanation** (understanding-oriented) | `docs/01-vision/`, `docs/07-decisions/` | Philosophy, Four Lenses theory, ADRs | + +The remaining sections fit naturally: `02-journeys/` (personas informing tutorials), `06-design-system/` (reference), `08-products/` (reference per product). + +### C4 Model + +The [C4 Model](https://c4model.com/) provides four zoom levels for architecture diagrams. VariScout implements three explicitly and one via tooling: + +| C4 Level | VariScout Implementation | File | +| --------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | +| **L1 System Context** | VariScout + Azure AD, OneDrive, Teams, AI Search | [system-map.md](architecture/system-map.md) (Mermaid C4Context) | +| **L2 Container** | 5 packages + 3 apps + infra with dependency arrows | [system-map.md](architecture/system-map.md) (Mermaid flowchart) | +| **L3 Component** | Hook dependencies, chart composition, data transforms | [component-patterns.md](architecture/component-patterns.md), [data-flow.md](architecture/data-flow.md) | +| **L4 Code** | Auto-generated API reference for @variscout/core | [api/core/](api/core/) (TypeDoc) | + +### Docs-as-Code + +[Docs-as-Code](https://www.writethedocs.org/guide/docs-as-code/) principles treat documentation with the same rigor as source code: + +| Principle | VariScout Practice | +| ---------------------- | -------------------------------------------------------------------- | +| Markdown source in Git | All 100+ docs in `docs/` directory, same repo as code | +| Version controlled | Documentation changes in the same PRs as code changes | +| Automated builds | Starlight (`pnpm docs:build`) for static site generation | +| Generated API docs | TypeDoc for `@variscout/core` (`pnpm --filter @variscout/core docs`) | +| Review in PRs | Documentation reviewed alongside code in every PR | +| Linting rules | `.claude/rules/documentation.md` enforces structure | + +--- + +## The Journey Spine + +VariScout's unique contribution to its documentation model: **every doc is organized around a 4-phase analysis journey**. + +```mermaid +flowchart LR + F["FRAME\nDefine problem"] --> S["SCOUT\nDiscover patterns"] + S --> I["INVESTIGATE\nFind root causes"] + I --> IM["IMPROVE\nVerify fixes"] + IM -- "PDCA loop" --> F + + style F fill:#3b82f6,color:#fff + style S fill:#22c55e,color:#fff + style I fill:#f59e0b,color:#fff + style IM fill:#8b5cf6,color:#fff +``` + +Each phase maps to specific UI screens, data shapes, code modules, and CoScout behaviors. The full journey model is documented in [analysis-journey-map.md](../03-features/workflows/analysis-journey-map.md). + +### Journey Phase Tags + +All workflow and feature docs include a `journey-phase:` tag — either in YAML frontmatter or as an HTML comment: + +```markdown + +``` + +Valid phases: `frame`, `scout`, `investigate`, `improve`, `[all]`. + +These tags enable AI agents and developers to discover docs by the phase of analysis they support. Combined with CLAUDE.md's task-to-doc routing table, an AI agent can resolve "how does drill-down work?" → `journey-phase: scout` → `drill-down-workflow.md` in one hop. + +### Decision Point Map + +The journey defines 12 key branching points where the analyst makes a decision. Each has a clear question, evidence source, and branching outcome. See the [Decision Point Map](../03-features/workflows/analysis-journey-map.md#decision-point-map) for the full table. + +These decision points serve double duty: + +- **For analysts**: they guide the investigation workflow +- **For CoScout**: they define where AI suggestions are most valuable + +--- + +## Documentation Layers + +Each layer serves a different reader at a different zoom level: + +| Layer | Content | Primary Reader | Entry Point | +| -------------------------- | ---------------------------------------------------- | ----------------------------- | ---------------------------- | +| **1. AI Agent Routing** | CLAUDE.md task-to-doc table | AI coding agents | Task description → file path | +| **2. Visual Maps** | system-map, journey-map, pipeline-map, lifecycle-map | Developers needing overview | Mermaid diagrams | +| **3. Workflow Docs** | Four Lenses, Drill-Down, Quick Check, Deep Dive | Quality analysts + developers | Step-by-step protocols | +| **4. Feature Docs** | Charts, data input, navigation, learning | Developers building features | Component specs | +| **5. Technical Reference** | Architecture, TypeDoc API, ADRs | Developers + architects | API signatures, decisions | +| **6. Product Specs** | PWA, Azure, Website | Product managers + developers | Platform-specific details | + +A developer investigating a bug starts at Layer 1 (CLAUDE.md routes to the right file). A new team member starts at Layer 2 (visual maps for orientation). A quality analyst learning the tool starts at Layer 3 (workflow docs mirror their real work). + +--- + +## Documentation as CoScout's Foundation + +The documentation methodology directly powers CoScout, the AI companion. Structured docs become structured AI behavior. + +### The Documentation-to-AI Pipeline + +```mermaid +flowchart LR + subgraph Docs["Documentation"] + VIS["docs/01-vision/\nFour Lenses, Two Voices"] + WF["docs/03-features/workflows/\nanalysis-journey-map"] + ARCH["docs/05-technical/architecture/\ndata-pipeline-map"] + CASES["docs/04-cases/\nCase studies"] + end + + subgraph Model["Knowledge Model"] + CON["concepts.ts\n~15 methodology concepts"] + PHASE["Journey Phase Model\nIDEOI phases"] + CTX["AIContext type\nStructured analysis state"] + SAMP["@variscout/data\nTeaching scenarios"] + end + + subgraph CoScout["CoScout Behavior"] + SYS["buildGlossaryPrompt()\nSystem prompt"] + DET["detectInvestigationPhase()\nPhase-adaptive prompts"] + BUILD["buildAIContext()\nContext assembly"] + SQ["suggestedQuestions.ts\nContext-aware prompts"] + end + + VIS --> CON --> SYS + WF --> PHASE --> DET + ARCH --> CTX --> BUILD + CASES --> SAMP --> SQ +``` + +### How Each Layer Feeds CoScout + +| Doc Layer | CoScout Feature | Mechanism | +| --------------------------------------------- | ---------------------- | ----------------------------------------------------------- | +| Vision docs (Four Lenses, Two Voices) | Methodology grounding | `concepts.ts` → `buildGlossaryPrompt()` in system prompt | +| Journey Map (Frame/Scout/Investigate/Improve) | Phase-adaptive prompts | `detectInvestigationPhase()` → `getCoScoutPhase()` | +| Investigation Lifecycle (IDEOI states) | Hypothesis suggestions | `suggestedQuestions.ts` adapts per IDEOI state | +| Data Pipeline Map (TypeScript interfaces) | Context assembly | `buildAIContext()` produces `AIContext` from analysis state | +| Case studies | Teaching examples | Sample datasets inform suggested questions | +| Glossary terms | Terminology alignment | ~41 terms in system prompt via Azure prompt caching | + +### Practical Implications + +When documentation is structured around the journey model, CoScout inherits that structure automatically: + +- Updating `analysis-journey-map.md` should trigger review of `suggestedQuestions.ts` +- New concepts in `docs/01-vision/` should be added to `concepts.ts` +- New workflow docs tagged with `journey-phase:` become candidates for CoScout prompt context +- The documentation IS the spec for CoScout's behavior + +--- + +## Documentation as Navigation and UX Spec + +The journey model serves double duty: it documents the analysis workflow AND specifies the navigation/UX design. + +### Journey Phases = Navigation States + +``` +FRAME → HomeScreen / PasteScreen / ColumnMapping +SCOUT → Dashboard (Four Lenses tabs, filter chips, drill-down) +INVESTIGATE → FindingsPanel + Board view + hypothesis forms +IMPROVE → WhatIfSimulator + ActionItems + StagedAnalysis +``` + +### Tier-Progressive UX + +The same 4-phase journey applies to all tiers, with features progressively unlocked: + +| Journey Phase | PWA (Free) | Azure Standard | Azure Team | +| --------------- | ------------------------------- | ----------------------------------- | ------------------------------------------------ | +| **FRAME** | Paste only, 3 factors, 50K rows | + File upload, 6 factors, 100K rows | + OneDrive sync | +| **SCOUT** | Four Lenses + drill-down | Same + more factors | + NarrativeBar, ChartInsightChips | +| **INVESTIGATE** | 3 statuses, no photos | Same | + 5 statuses, photo evidence, CoScout | +| **IMPROVE** | What-If only | Same | + Action tracking, staged verification, outcomes | + +This table is the master spec for: + +- Which components render at each phase per tier +- Where `UpgradePrompt` appears (at the feature boundary) +- What CoScout can suggest at each phase +- Which navigation paths exist + +### With and Without AI + +**Without AI (PWA / Azure Standard):** + +- The journey is fully manual — the analyst reads charts, makes decisions, pins findings +- Navigation follows the Four Lenses sequence (I-Chart → Boxplot → Pareto → Capability) +- All decision points in the Decision Point Map are human-driven + +**With AI (Azure Team):** + +- CoScout adds a second entry path: hypothesis-driven (AI suggests → confirm → jump to Investigate) +- NarrativeBar provides passive guidance at each phase +- ChartInsightChips highlight actionable patterns on charts + +**With Teams (Azure Team plan):** + +- Channel tabs = shared navigation context (multiple analysts, same journey) +- Photo evidence at Investigate phase (Teams camera API) +- OneDrive sync = persistent journey state across devices + +--- + +## Visual-First Methodology + +Rules codified in [`.claude/rules/documentation.md`](../../.claude/rules/documentation.md): + +| Rule | Purpose | +| -------------------------------- | --------------------------------------------------------------------------------------------- | +| **Mermaid diagram first** | Every architecture/workflow doc opens with a diagram. Readers grasp structure in <60 seconds. | +| **Data boundary interfaces** | Architecture docs show TypeScript interface shapes at module boundaries. | +| **Mermaid for all new diagrams** | GitHub-native rendering, machine-readable by AI agents. | +| **Journey phase tags** | All workflow/feature docs tagged with analysis phase for discovery. | +| **Cross-linking required** | New docs added to parent index, CLAUDE.md table, and related See Also sections. | +| **YAML frontmatter** | Title, description, journey-phase for docs in the journey map. | + +--- + +## Tooling Stack + +| Tool | Purpose | Status | +| ------------------ | ------------------------------------------------------------------------------------------------ | ------ | +| **Markdown + Git** | Source of truth for all documentation | Active | +| **Starlight** | Astro-based doc site (`pnpm docs:build`) — Pagefind search, dark/light toggle, Mermaid rendering | Active | +| **Mermaid** | Diagrams (30+ across docs) — flowchart, sequence, state, C4 | Active | +| **TypeDoc** | API reference for @variscout/core (`pnpm --filter @variscout/core docs`) | Active | +| **CLAUDE.md** | AI agent routing layer (task-to-doc table) | Active | +| **LikeC4** | C4 architecture model (`docs/architecture/likec4/`) — exports to Mermaid via `pnpm docs:c4` | Active | +| **Storybook** | Interactive component catalog (66 components) | Active | + +--- + +## Roadmap + +### Phase B — LikeC4 (Architecture as Code) ✓ + +Split [`docs/architecture/likec4/`](../architecture/likec4/) model files define the full system at C4 L1/L2/L3: + +- Source of truth for architecture topology → exports to Mermaid via `pnpm docs:c4` +- L3 Component views decompose each package into modules +- `pnpm docs:c4:serve` launches interactive browser; see [component-map.md](architecture/component-map.md) + +### Phase C — Storybook (Living Component Docs) ✓ + +Interactive playground for 52 UI + 14 chart components: + +- Theme toggle (dark/light) + chart mode (technical/executive) +- 66 stories across all shared packages +- `pnpm storybook` to launch; see `.storybook/stories/README.md` + +### Phase D — ADR Visualization ✓ + +Mermaid dependency graph in [`docs/07-decisions/index.md`](../../07-decisions/index.md): + +- Shows supersedes/extends relationships between 18 ADRs +- Groups by domain (Architecture, Charts, Storage, Distribution, Features, Teams) +- ADR-018 (Channel @Mention) added to index and dependency map + +--- + +## ADR Dependency Map + +```mermaid +flowchart TB + subgraph Architecture["Architecture"] + ADR001["001\nMonorepo"] + ADR004["004\nOffline-First"] + ADR011["011\nAI Tooling"] + ADR013["013\nDDD/Swarms"] + ADR001 --> ADR013 + end + + subgraph Charts["Charts & UI"] + ADR002["002\nVisx Charts"] + ADR005["005\nProps-Based"] + ADR009["009\nViolin Mode"] + ADR017["017\nFluent 2"] + ADR002 --> ADR005 + ADR005 --> ADR009 + end + + subgraph Storage["Storage"] + ADR003["003\nIndexedDB"] + ADR012["012\nPWA Browser-Only"] + ADR003 --> ADR004 + ADR004 --> ADR012 + end + + subgraph Distribution["Distribution"] + ADR006["006\nEdition System"] + ADR007["007\nAzure Marketplace"] + ADR008["008\nWebsite Architecture"] + ADR006 -.->|superseded| ADR007 + end + + subgraph Features["Features"] + ADR010["010\nGage R&R"] + ADR014["014\nRegression Deferral"] + ADR015["015\nInvestigation Board"] + end + + subgraph Teams["Teams Platform"] + ADR016["016\nTeams Integration"] + ADR018["018\nChannel @Mention"] + ADR007 --> ADR016 + ADR015 --> ADR016 + ADR016 --> ADR018 + ADR015 --> ADR018 + end + + style ADR006 fill:#94a3b8,color:#fff + style ADR010 fill:#94a3b8,color:#fff +``` + +--- + +## Sources and References + +- [Diataxis](https://diataxis.fr/) — A systematic approach to technical documentation authoring +- [C4 Model](https://c4model.com/) — Software architecture diagrams at four zoom levels +- [Docs-as-Code (Write the Docs)](https://www.writethedocs.org/guide/docs-as-code/) — Treat documentation with the same tools as code +- [LikeC4](https://likec4.dev/) — Architecture models as code (npm-native, Mermaid export) +- [Storybook](https://storybook.js.org/docs/writing-docs) — Interactive component documentation + +--- + +## See Also + +- [Analysis Journey Map](../03-features/workflows/analysis-journey-map.md) — the 4-phase journey model +- [System Map](architecture/system-map.md) — C4 L1/L2 architecture diagrams +- [Data Pipeline Map](architecture/data-pipeline-map.md) — end-to-end data flow with TypeScript boundaries +- [Investigation Lifecycle Map](../03-features/workflows/investigation-lifecycle-map.md) — IDEOI state machine +- [Documentation Rules](../../.claude/rules/documentation.md) — enforced rules for doc structure diff --git a/docs/05-technical/implementation/azure-testing-plan.md b/docs/05-technical/implementation/azure-testing-plan.md index a7679ab4b..50dca7148 100644 --- a/docs/05-technical/implementation/azure-testing-plan.md +++ b/docs/05-technical/implementation/azure-testing-plan.md @@ -1,3 +1,7 @@ +--- +title: 'Azure App Testing Plan — rdmaic Organization' +--- + # Azure App Testing Plan — rdmaic Organization Internal testing plan for VariScout Azure App before Azure Marketplace submission. Covers browser-based App Service testing and Microsoft Teams tab integration. diff --git a/docs/05-technical/implementation/data-input.md b/docs/05-technical/implementation/data-input.md index 427040db6..d383e2844 100644 --- a/docs/05-technical/implementation/data-input.md +++ b/docs/05-technical/implementation/data-input.md @@ -1,3 +1,7 @@ +--- +title: 'Data Input System' +--- + # Data Input System Technical documentation for data parsing, validation, and auto-mapping in VariScout Lite. diff --git a/docs/05-technical/implementation/deployment.md b/docs/05-technical/implementation/deployment.md index 42b04f88b..f5d15a1fc 100644 --- a/docs/05-technical/implementation/deployment.md +++ b/docs/05-technical/implementation/deployment.md @@ -1,3 +1,7 @@ +--- +title: 'Deployment Guide' +--- + # Deployment Guide This document covers build commands, deployment workflows, and environment configurations for VariScout applications. diff --git a/docs/05-technical/implementation/glm-roadmap.md b/docs/05-technical/implementation/glm-roadmap.md index 03b3b874f..f445ef2ec 100644 --- a/docs/05-technical/implementation/glm-roadmap.md +++ b/docs/05-technical/implementation/glm-roadmap.md @@ -1,3 +1,7 @@ +--- +title: 'GLM Engine Roadmap' +--- + # GLM Engine Roadmap > **Note:** Regression UI has been deferred per [ADR-014](../../07-decisions/adr-014-regression-deferral.md). Core math files (regression.ts, multiRegression.ts, interaction.ts, modelReduction.ts, matrix.ts) are preserved in the repository but unexported from `@variscout/core`. This roadmap applies to Phase 2 re-enablement. diff --git a/docs/05-technical/implementation/phase2-regression-roadmap.md b/docs/05-technical/implementation/phase2-regression-roadmap.md index 65930ca4c..2277e306d 100644 --- a/docs/05-technical/implementation/phase2-regression-roadmap.md +++ b/docs/05-technical/implementation/phase2-regression-roadmap.md @@ -1,3 +1,7 @@ +--- +title: 'Phase 2: Regression Re-enablement Roadmap' +--- + # Phase 2: Regression Re-enablement Roadmap > **Status:** Planned — not started diff --git a/docs/05-technical/implementation/ruflo.md b/docs/05-technical/implementation/ruflo.md index 14372e36f..f8bb8fcfc 100644 --- a/docs/05-technical/implementation/ruflo.md +++ b/docs/05-technical/implementation/ruflo.md @@ -1,3 +1,7 @@ +--- +title: 'Ruflo Development Tooling' +--- + # Ruflo Development Tooling ## What It Is diff --git a/docs/05-technical/implementation/security-scanning.md b/docs/05-technical/implementation/security-scanning.md index b39067ee5..66573c237 100644 --- a/docs/05-technical/implementation/security-scanning.md +++ b/docs/05-technical/implementation/security-scanning.md @@ -1,3 +1,7 @@ +--- +title: 'Security Scanning' +--- + # Security Scanning ## Overview diff --git a/docs/05-technical/implementation/system-limits.md b/docs/05-technical/implementation/system-limits.md index 94b93cedd..1c8203884 100644 --- a/docs/05-technical/implementation/system-limits.md +++ b/docs/05-technical/implementation/system-limits.md @@ -1,3 +1,7 @@ +--- +title: 'System Limits' +--- + # System Limits Comprehensive reference for VariScout's data handling limits, classification thresholds, and display boundaries. All computation runs in-browser JavaScript with no server offload. diff --git a/docs/05-technical/implementation/testing.md b/docs/05-technical/implementation/testing.md index 9651caf0d..2c646054d 100644 --- a/docs/05-technical/implementation/testing.md +++ b/docs/05-technical/implementation/testing.md @@ -1,3 +1,7 @@ +--- +title: 'Testing Strategy' +--- + # Testing Strategy **Status:** Active diff --git a/docs/05-technical/index.md b/docs/05-technical/index.md index 96b87b883..800c2d47c 100644 --- a/docs/05-technical/index.md +++ b/docs/05-technical/index.md @@ -1,3 +1,7 @@ +--- +title: 'Technical Documentation' +--- + # Technical Documentation Technical specifications for VariScout implementation. These documents are designed to be used by developers (human or AI) building the product. @@ -54,14 +58,17 @@ VARISCOUT ARCHITECTURE (Browser-Only) High-level architecture overview and detailed design documents: -| Document | Description | -| -------------------------------------------------------- | -------------------------------------------- | -| [Architecture Overview](architecture.md) | High-level system architecture | -| [Monorepo Structure](architecture/monorepo.md) | pnpm workspaces, package boundaries | -| [Offline-First](architecture/offline-first.md) | PWA, service worker, IndexedDB | -| [Shared Packages](architecture/shared-packages.md) | Package extraction and reuse strategy | -| [Data Flow](architecture/data-flow.md) | Data pipeline from input to visualization | -| [Component Patterns](architecture/component-patterns.md) | Hook integration, colorScheme, base patterns | +| Document | Description | +| --------------------------------------------------------- | ------------------------------------------------- | +| [Architecture Overview](architecture.md) | High-level system architecture | +| [Monorepo Structure](architecture/monorepo.md) | pnpm workspaces, package boundaries | +| [Offline-First](architecture/offline-first.md) | PWA, service worker, IndexedDB | +| [Shared Packages](architecture/shared-packages.md) | Package extraction and reuse strategy | +| [Data Flow](architecture/data-flow.md) | Data pipeline from input to visualization | +| [Component Patterns](architecture/component-patterns.md) | Hook integration, colorScheme, base patterns | +| [Component Map](architecture/component-map.md) | L3 component views per package (internal modules) | +| [LikeC4 Model](../architecture/likec4/) | C4 architecture model (L1-L3) in LikeC4 | +| [Documentation Methodology](documentation-methodology.md) | Diataxis, C4, Docs-as-Code, journey spine | ### Implementation diff --git a/docs/05-technical/integrations/embed-messaging.md b/docs/05-technical/integrations/embed-messaging.md index ebc7fe43b..9eac664f0 100644 --- a/docs/05-technical/integrations/embed-messaging.md +++ b/docs/05-technical/integrations/embed-messaging.md @@ -1,3 +1,7 @@ +--- +title: 'PWA Embed Messaging Protocol' +--- + # PWA Embed Messaging Protocol Communication protocol for iframe-embedded PWA (when used externally). diff --git a/docs/05-technical/integrations/shared-ui.md b/docs/05-technical/integrations/shared-ui.md index d610b16eb..64a0e4376 100644 --- a/docs/05-technical/integrations/shared-ui.md +++ b/docs/05-technical/integrations/shared-ui.md @@ -1,3 +1,7 @@ +--- +title: 'Shared UI Library Strategy' +--- + # Shared UI Library Strategy > [!NOTE] diff --git a/docs/05-technical/statistics-reference.md b/docs/05-technical/statistics-reference.md index be34f46ea..df8528716 100644 --- a/docs/05-technical/statistics-reference.md +++ b/docs/05-technical/statistics-reference.md @@ -1,3 +1,7 @@ +--- +title: 'Statistics & Mindmap Technical Reference' +--- + # Statistics & Mindmap Technical Reference Exact formulas, algorithm choices, and implementation notes for the VariScout statistical engine and the Investigation Mindmap. @@ -67,7 +71,7 @@ MR-bar = (1/(n-1)) Σ MR_i The constant **d2 = 1.128** is the Hartley unbiasing constant for a moving range with span 2. Since VariScout always uses individual measurements (n = 1), the span is always 2 and d2 is fixed. -**Why two sigmas?** σ_within captures short-term, inherent process variation — the variation between consecutive measurements. It excludes between-subgroup shifts. This makes it the correct denominator for Shewhart control limits and capability indices (Wheeler, _Understanding Variation_). σ_overall includes all sources of variation and is used for ANOVA, where both within-group and between-group variation matter. +**Why two sigmas?** σ*within captures short-term, inherent process variation — the variation between consecutive measurements. It excludes between-subgroup shifts. This makes it the correct denominator for Shewhart control limits and capability indices (Wheeler, \_Understanding Variation*). σ_overall includes all sources of variation and is used for ANOVA, where both within-group and between-group variation matter. **Edge case**: when `data.length < 2`, the moving range cannot be computed. The implementation falls back to `d3.deviation(data)` for σ_within and returns `mrBar = 0`. diff --git a/docs/06-design-system/charts/boxplot.md b/docs/06-design-system/charts/boxplot.md index 5ce8c1b97..5edbdd864 100644 --- a/docs/06-design-system/charts/boxplot.md +++ b/docs/06-design-system/charts/boxplot.md @@ -1,3 +1,7 @@ +--- +title: 'Boxplot Charts' +--- + # Boxplot Charts Distribution comparison charts for categorical and multi-channel analysis. diff --git a/docs/06-design-system/charts/capability.md b/docs/06-design-system/charts/capability.md index b2ed5f2d4..4808d673f 100644 --- a/docs/06-design-system/charts/capability.md +++ b/docs/06-design-system/charts/capability.md @@ -1,3 +1,7 @@ +--- +title: 'Capability Histograms' +--- + # Capability Histograms Distribution histograms with specification limit overlays for capability analysis. diff --git a/docs/06-design-system/charts/colors.md b/docs/06-design-system/charts/colors.md index 4978df04f..51fc00928 100644 --- a/docs/06-design-system/charts/colors.md +++ b/docs/06-design-system/charts/colors.md @@ -1,3 +1,7 @@ +--- +title: 'Chart Colors' +--- + # Chart Colors Data visualization colors for VariScout charts. diff --git a/docs/06-design-system/charts/executive-mode.md b/docs/06-design-system/charts/executive-mode.md index 9706072dc..842c204e7 100644 --- a/docs/06-design-system/charts/executive-mode.md +++ b/docs/06-design-system/charts/executive-mode.md @@ -1,3 +1,7 @@ +--- +title: 'Executive Mode' +--- + # Executive Mode Consulting-grade chart styling for professional reports, following top-tier management consulting standards (McKinsey, Bain, BCG). diff --git a/docs/06-design-system/charts/hooks.md b/docs/06-design-system/charts/hooks.md index 0316a0a36..271e07cc4 100644 --- a/docs/06-design-system/charts/hooks.md +++ b/docs/06-design-system/charts/hooks.md @@ -1,3 +1,7 @@ +--- +title: 'Chart Hooks' +--- + # Chart Hooks React hooks for chart layout, tooltips, and selection state in `@variscout/charts`. diff --git a/docs/06-design-system/charts/ichart.md b/docs/06-design-system/charts/ichart.md index 5122d99e7..fe24fa67d 100644 --- a/docs/06-design-system/charts/ichart.md +++ b/docs/06-design-system/charts/ichart.md @@ -1,3 +1,7 @@ +--- +title: 'Individual Control Charts (I-Chart)' +--- + # Individual Control Charts (I-Chart) Time-series control charts for individual measurements with control limits and specification limits. diff --git a/docs/06-design-system/charts/overview.md b/docs/06-design-system/charts/overview.md index 01c65cb2c..0badd2ca0 100644 --- a/docs/06-design-system/charts/overview.md +++ b/docs/06-design-system/charts/overview.md @@ -1,3 +1,7 @@ +--- +title: 'Chart Styling Overview' +--- + # Chart Styling Overview VariScout charts are built with [Visx](https://airbnb.io/visx/) and follow consistent styling patterns. diff --git a/docs/06-design-system/charts/pareto.md b/docs/06-design-system/charts/pareto.md index eed541422..02993f93d 100644 --- a/docs/06-design-system/charts/pareto.md +++ b/docs/06-design-system/charts/pareto.md @@ -1,3 +1,7 @@ +--- +title: 'Pareto Charts' +--- + # Pareto Charts Frequency analysis and ranking charts with cumulative percentage lines. diff --git a/docs/06-design-system/charts/performance-mode.md b/docs/06-design-system/charts/performance-mode.md index 6a3dc1002..6f17512ce 100644 --- a/docs/06-design-system/charts/performance-mode.md +++ b/docs/06-design-system/charts/performance-mode.md @@ -1,3 +1,7 @@ +--- +title: 'Performance Mode Charts' +--- + # Performance Mode Charts Multi-measure analysis charts for comparing performance across multiple measurement channels. diff --git a/docs/06-design-system/charts/probability-plot.md b/docs/06-design-system/charts/probability-plot.md index 501491a39..88fe05f0b 100644 --- a/docs/06-design-system/charts/probability-plot.md +++ b/docs/06-design-system/charts/probability-plot.md @@ -1,3 +1,7 @@ +--- +title: 'Probability Plot' +--- + # Probability Plot Normality assessment chart with 95% confidence intervals following Minitab conventions. diff --git a/docs/06-design-system/charts/responsive.md b/docs/06-design-system/charts/responsive.md index f79a884da..5edb69a8c 100644 --- a/docs/06-design-system/charts/responsive.md +++ b/docs/06-design-system/charts/responsive.md @@ -1,3 +1,7 @@ +--- +title: 'Responsive Charts' +--- + # Responsive Charts Charts adapt to container size using responsive utilities. diff --git a/docs/06-design-system/charts/shared-components.md b/docs/06-design-system/charts/shared-components.md index 5348cb433..9c81f3f95 100644 --- a/docs/06-design-system/charts/shared-components.md +++ b/docs/06-design-system/charts/shared-components.md @@ -1,3 +1,7 @@ +--- +title: 'Shared Chart Components' +--- + # Shared Chart Components Reusable components for building consistent charts in `@variscout/charts`. diff --git a/docs/06-design-system/components/buttons.md b/docs/06-design-system/components/buttons.md index 8b310b53b..1a0d08d57 100644 --- a/docs/06-design-system/components/buttons.md +++ b/docs/06-design-system/components/buttons.md @@ -1,3 +1,7 @@ +--- +title: 'Buttons' +--- + # Buttons Button variants for PWA and Website. diff --git a/docs/06-design-system/components/cards.md b/docs/06-design-system/components/cards.md index cd254fb0d..96c657f06 100644 --- a/docs/06-design-system/components/cards.md +++ b/docs/06-design-system/components/cards.md @@ -1,3 +1,7 @@ +--- +title: 'Cards' +--- + # Cards Card components for grouping related content. diff --git a/docs/06-design-system/components/forms.md b/docs/06-design-system/components/forms.md index eb42352c0..637275ec1 100644 --- a/docs/06-design-system/components/forms.md +++ b/docs/06-design-system/components/forms.md @@ -1,3 +1,7 @@ +--- +title: 'Form Elements' +--- + # Form Elements Form input patterns using semantic Tailwind tokens for theme-aware styling. diff --git a/docs/06-design-system/components/modals.md b/docs/06-design-system/components/modals.md index 908018b51..4409fdf6a 100644 --- a/docs/06-design-system/components/modals.md +++ b/docs/06-design-system/components/modals.md @@ -1,3 +1,7 @@ +--- +title: 'Modals' +--- + # Modals Modal dialog patterns for PWA. diff --git a/docs/06-design-system/components/variation-funnel.md b/docs/06-design-system/components/variation-funnel.md index 20c15be96..704f73563 100644 --- a/docs/06-design-system/components/variation-funnel.md +++ b/docs/06-design-system/components/variation-funnel.md @@ -1,3 +1,7 @@ +--- +title: 'Variation Bar' +--- + # Variation Bar A visual progress bar showing variation scope in the drill-down breadcrumb. diff --git a/docs/06-design-system/components/what-if-simulator.md b/docs/06-design-system/components/what-if-simulator.md index 0eb61e5aa..234cf4148 100644 --- a/docs/06-design-system/components/what-if-simulator.md +++ b/docs/06-design-system/components/what-if-simulator.md @@ -1,3 +1,7 @@ +--- +title: 'What-If Simulator' +--- + # What-If Simulator Interactive component for exploring process improvement scenarios. diff --git a/docs/06-design-system/foundations/accessibility.md b/docs/06-design-system/foundations/accessibility.md index 6b5141ff6..056826e28 100644 --- a/docs/06-design-system/foundations/accessibility.md +++ b/docs/06-design-system/foundations/accessibility.md @@ -1,3 +1,7 @@ +--- +title: 'Accessibility Guidelines' +--- + # Accessibility Guidelines VariScout Lite targets WCAG 2.1 AA compliance to ensure quality professionals with disabilities can effectively analyze variation data. diff --git a/docs/06-design-system/foundations/colors.md b/docs/06-design-system/foundations/colors.md index e3e388162..1f46147c3 100644 --- a/docs/06-design-system/foundations/colors.md +++ b/docs/06-design-system/foundations/colors.md @@ -1,3 +1,7 @@ +--- +title: 'Color System' +--- + # Color System VariScout uses CSS variables with Tailwind semantic classes for theme-aware styling. diff --git a/docs/06-design-system/foundations/spacing.md b/docs/06-design-system/foundations/spacing.md index 3425ab9ee..be7b7e0ef 100644 --- a/docs/06-design-system/foundations/spacing.md +++ b/docs/06-design-system/foundations/spacing.md @@ -1,3 +1,7 @@ +--- +title: 'Spacing' +--- + # Spacing VariScout uses a 4px base unit spacing scale. diff --git a/docs/06-design-system/foundations/typography.md b/docs/06-design-system/foundations/typography.md index b30c61648..24645aa5d 100644 --- a/docs/06-design-system/foundations/typography.md +++ b/docs/06-design-system/foundations/typography.md @@ -1,3 +1,7 @@ +--- +title: 'Typography' +--- + # Typography ## Font Stack diff --git a/docs/06-design-system/index.md b/docs/06-design-system/index.md index 541fe2336..e8db8decc 100644 --- a/docs/06-design-system/index.md +++ b/docs/06-design-system/index.md @@ -1,3 +1,7 @@ +--- +title: 'VariScout Design System' +--- + # VariScout Design System A unified design system for VariScout covering PWA and Azure App platforms. diff --git a/docs/06-design-system/patterns/feedback.md b/docs/06-design-system/patterns/feedback.md index 28dee7a5e..981ae84f2 100644 --- a/docs/06-design-system/patterns/feedback.md +++ b/docs/06-design-system/patterns/feedback.md @@ -1,3 +1,7 @@ +--- +title: 'Feedback Patterns' +--- + # Feedback Patterns Status, loading, and error state patterns. diff --git a/docs/06-design-system/patterns/interactions.md b/docs/06-design-system/patterns/interactions.md index f13700476..d3b49a10c 100644 --- a/docs/06-design-system/patterns/interactions.md +++ b/docs/06-design-system/patterns/interactions.md @@ -1,3 +1,7 @@ +--- +title: 'Interaction Patterns' +--- + # Interaction Patterns Design system reference for interactive component behaviors across VariScout. diff --git a/docs/06-design-system/patterns/layout.md b/docs/06-design-system/patterns/layout.md index 9682bc24d..86b172635 100644 --- a/docs/06-design-system/patterns/layout.md +++ b/docs/06-design-system/patterns/layout.md @@ -1,3 +1,7 @@ +--- +title: 'Layout Patterns' +--- + # Layout Patterns Page and component layout patterns. diff --git a/docs/06-design-system/patterns/navigation.md b/docs/06-design-system/patterns/navigation.md index d2b7af8b1..e4fa7b788 100644 --- a/docs/06-design-system/patterns/navigation.md +++ b/docs/06-design-system/patterns/navigation.md @@ -1,3 +1,7 @@ +--- +title: 'Navigation Patterns' +--- + # Navigation Patterns Navigation patterns used across VariScout applications. diff --git a/docs/06-design-system/patterns/panels-and-drawers.md b/docs/06-design-system/patterns/panels-and-drawers.md index 2a4c46fbb..633507e3a 100644 --- a/docs/06-design-system/patterns/panels-and-drawers.md +++ b/docs/06-design-system/patterns/panels-and-drawers.md @@ -1,3 +1,7 @@ +--- +title: 'Panels and Drawers' +--- + # Panels and Drawers Panel patterns for VariScout, aligned with [Fluent 2 design principles](../../07-decisions/adr-017-fluent-design-alignment.md). Covers when to use each type, CSS patterns, responsive behavior, and dismiss conventions. diff --git a/docs/07-decisions/adr-001-monorepo.md b/docs/07-decisions/adr-001-monorepo.md index 91e618747..821b88b44 100644 --- a/docs/07-decisions/adr-001-monorepo.md +++ b/docs/07-decisions/adr-001-monorepo.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-001: Monorepo with pnpm Workspaces' +--- + # ADR-001: Monorepo with pnpm Workspaces **Status**: Accepted diff --git a/docs/07-decisions/adr-002-visx-charts.md b/docs/07-decisions/adr-002-visx-charts.md index f099e0f1d..3fa459892 100644 --- a/docs/07-decisions/adr-002-visx-charts.md +++ b/docs/07-decisions/adr-002-visx-charts.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-002: Visx for Chart Components' +--- + # ADR-002: Visx for Chart Components **Status**: Accepted diff --git a/docs/07-decisions/adr-003-indexeddb.md b/docs/07-decisions/adr-003-indexeddb.md index 9866bcb6c..33ec50745 100644 --- a/docs/07-decisions/adr-003-indexeddb.md +++ b/docs/07-decisions/adr-003-indexeddb.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-003: IndexedDB for PWA Storage' +--- + # ADR-003: IndexedDB for PWA Storage **Status**: Accepted diff --git a/docs/07-decisions/adr-004-offline-first.md b/docs/07-decisions/adr-004-offline-first.md index b8a295907..4169cc236 100644 --- a/docs/07-decisions/adr-004-offline-first.md +++ b/docs/07-decisions/adr-004-offline-first.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-004: Offline-First Architecture' +--- + # ADR-004: Offline-First Architecture **Status**: Accepted diff --git a/docs/07-decisions/adr-005-props-based-charts.md b/docs/07-decisions/adr-005-props-based-charts.md index f29063fcf..a3facb318 100644 --- a/docs/07-decisions/adr-005-props-based-charts.md +++ b/docs/07-decisions/adr-005-props-based-charts.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-005: Props-Based Charts (vs Context)' +--- + # ADR-005: Props-Based Charts (vs Context) **Status**: Accepted diff --git a/docs/07-decisions/adr-006-edition-system.md b/docs/07-decisions/adr-006-edition-system.md index e584364de..1b7659528 100644 --- a/docs/07-decisions/adr-006-edition-system.md +++ b/docs/07-decisions/adr-006-edition-system.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-006: Edition System' +--- + # ADR-006: Edition System **Status**: Superseded by [ADR-007](adr-007-azure-marketplace-distribution.md) diff --git a/docs/07-decisions/adr-007-azure-marketplace-distribution.md b/docs/07-decisions/adr-007-azure-marketplace-distribution.md index 55b718d7e..e93bbc1bc 100644 --- a/docs/07-decisions/adr-007-azure-marketplace-distribution.md +++ b/docs/07-decisions/adr-007-azure-marketplace-distribution.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-007: Azure Marketplace Distribution Strategy' +--- + # ADR-007: Azure Marketplace Distribution Strategy **Status**: Accepted (Revised 2026-02-27) diff --git a/docs/07-decisions/adr-008-website-content-architecture.md b/docs/07-decisions/adr-008-website-content-architecture.md index e1976efbf..b5fb3adf8 100644 --- a/docs/07-decisions/adr-008-website-content-architecture.md +++ b/docs/07-decisions/adr-008-website-content-architecture.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-008: Website Content Architecture' +--- + # ADR-008: Website Content Architecture **Status**: Accepted diff --git a/docs/07-decisions/adr-009-boxplot-violin-mode.md b/docs/07-decisions/adr-009-boxplot-violin-mode.md index f69599878..4a042d480 100644 --- a/docs/07-decisions/adr-009-boxplot-violin-mode.md +++ b/docs/07-decisions/adr-009-boxplot-violin-mode.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-009: Boxplot Violin Mode' +--- + # ADR-009: Boxplot Violin Mode **Status:** Accepted diff --git a/docs/07-decisions/adr-010-gagerr-deferral.md b/docs/07-decisions/adr-010-gagerr-deferral.md index affc2aa8d..ba53a994b 100644 --- a/docs/07-decisions/adr-010-gagerr-deferral.md +++ b/docs/07-decisions/adr-010-gagerr-deferral.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-010: Defer Gage R&R from Azure App v1' +--- + # ADR-010: Defer Gage R&R from Azure App v1 **Status:** Superseded diff --git a/docs/07-decisions/adr-011-ai-development-tooling.md b/docs/07-decisions/adr-011-ai-development-tooling.md index f52020348..d6efacee1 100644 --- a/docs/07-decisions/adr-011-ai-development-tooling.md +++ b/docs/07-decisions/adr-011-ai-development-tooling.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-011: AI Development Tooling (ruflo)' +--- + # ADR-011: AI Development Tooling (ruflo) **Status:** Accepted diff --git a/docs/07-decisions/adr-012-pwa-browser-only.md b/docs/07-decisions/adr-012-pwa-browser-only.md index 6d46ea9b2..4db5c360a 100644 --- a/docs/07-decisions/adr-012-pwa-browser-only.md +++ b/docs/07-decisions/adr-012-pwa-browser-only.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-012: PWA Browser-Only, Zero Data Collection' +--- + # ADR-012: PWA Browser-Only, Zero Data Collection **Status**: Accepted diff --git a/docs/07-decisions/adr-013-architecture-evaluation-ddd-swarms.md b/docs/07-decisions/adr-013-architecture-evaluation-ddd-swarms.md index d92385eec..a0ae19624 100644 --- a/docs/07-decisions/adr-013-architecture-evaluation-ddd-swarms.md +++ b/docs/07-decisions/adr-013-architecture-evaluation-ddd-swarms.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-013: Architecture Evaluation — DDD and AI Swarms' +--- + # ADR-013: Architecture Evaluation — DDD and AI Swarms **Status:** Accepted diff --git a/docs/07-decisions/adr-014-regression-deferral.md b/docs/07-decisions/adr-014-regression-deferral.md index e452f3483..ac7f2074b 100644 --- a/docs/07-decisions/adr-014-regression-deferral.md +++ b/docs/07-decisions/adr-014-regression-deferral.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-014: Defer Regression to Phase 2' +--- + # ADR-014: Defer Regression to Phase 2 **Status:** Accepted diff --git a/docs/07-decisions/adr-015-investigation-board.md b/docs/07-decisions/adr-015-investigation-board.md index 7df47b58c..8c38e5285 100644 --- a/docs/07-decisions/adr-015-investigation-board.md +++ b/docs/07-decisions/adr-015-investigation-board.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-015: Investigation Board — Finding Status & Comments' +--- + # ADR-015: Investigation Board — Finding Status & Comments **Status:** Accepted (revised 2026-02-26) diff --git a/docs/07-decisions/adr-016-security-evaluation.md b/docs/07-decisions/adr-016-security-evaluation.md index 1bb3709d3..5f89aee69 100644 --- a/docs/07-decisions/adr-016-security-evaluation.md +++ b/docs/07-decisions/adr-016-security-evaluation.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-016 Security Evaluation: Teams Integration' +--- + # ADR-016 Security Evaluation: Teams Integration **Status**: Draft diff --git a/docs/07-decisions/adr-016-teams-integration.md b/docs/07-decisions/adr-016-teams-integration.md index 35d0c1510..1eed24e7d 100644 --- a/docs/07-decisions/adr-016-teams-integration.md +++ b/docs/07-decisions/adr-016-teams-integration.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-016: Microsoft Teams Integration' +--- + # ADR-016: Microsoft Teams Integration **Status**: Accepted diff --git a/docs/07-decisions/adr-017-fluent-design-alignment.md b/docs/07-decisions/adr-017-fluent-design-alignment.md index 5b8604a7b..3b05f57d0 100644 --- a/docs/07-decisions/adr-017-fluent-design-alignment.md +++ b/docs/07-decisions/adr-017-fluent-design-alignment.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-017: Fluent 2 Design Principle Alignment' +--- + # ADR-017: Fluent 2 Design Principle Alignment **Status**: Accepted diff --git a/docs/07-decisions/adr-018-channel-mention-workflow.md b/docs/07-decisions/adr-018-channel-mention-workflow.md index cb0cba6f3..45d871503 100644 --- a/docs/07-decisions/adr-018-channel-mention-workflow.md +++ b/docs/07-decisions/adr-018-channel-mention-workflow.md @@ -1,3 +1,7 @@ +--- +title: 'ADR-018: Channel @Mention Workflow — Mobile Finding to Team Action' +--- + # ADR-018: Channel @Mention Workflow — Mobile Finding to Team Action **Status**: Proposed diff --git a/docs/07-decisions/audit-2026-02-state-of-product.md b/docs/07-decisions/audit-2026-02-state-of-product.md index 38b14d18e..e91e78dc8 100644 --- a/docs/07-decisions/audit-2026-02-state-of-product.md +++ b/docs/07-decisions/audit-2026-02-state-of-product.md @@ -1,3 +1,7 @@ +--- +title: 'State-of-the-Product Audit — February 2026' +--- + # State-of-the-Product Audit — February 2026 **Date**: 2026-02-13 diff --git a/docs/07-decisions/index.md b/docs/07-decisions/index.md index 00a335f7c..e7d077401 100644 --- a/docs/07-decisions/index.md +++ b/docs/07-decisions/index.md @@ -1,3 +1,7 @@ +--- +title: 'Architecture Decision Records' +--- + # Architecture Decision Records This section captures key architectural decisions made during VariScout development. Each decision includes context, the decision made, and consequences. @@ -25,6 +29,65 @@ This section captures key architectural decisions made during VariScout developm | [015](adr-015-investigation-board.md) | Investigation Board | Accepted | 2026-02-26 | | [016](adr-016-teams-integration.md) | Teams Integration | Proposed | 2026-02-27 | | [017](adr-017-fluent-design-alignment.md) | Fluent 2 Design Principle Alignment | Accepted | 2026-03-02 | +| [018](adr-018-channel-mention-workflow.md) | Channel @Mention Workflow | Proposed | 2026-03-02 | + +--- + +## ADR Dependency Map + +```mermaid +flowchart TB + subgraph Architecture["Architecture"] + ADR001["001 Monorepo"] + ADR004["004 Offline-First"] + ADR011["011 AI Tooling"] + ADR013["013 DDD/Swarms"] + ADR001 --> ADR013 + end + + subgraph Charts["Charts & UI"] + ADR002["002 Visx Charts"] + ADR005["005 Props-Based"] + ADR009["009 Violin Mode"] + ADR017["017 Fluent 2"] + ADR002 --> ADR005 + ADR005 --> ADR009 + end + + subgraph Storage["Storage"] + ADR003["003 IndexedDB"] + ADR012["012 PWA Browser-Only"] + ADR003 --> ADR004 + ADR004 --> ADR012 + end + + subgraph Distribution["Distribution"] + ADR006["006 Edition System"] + ADR007["007 Azure Marketplace"] + ADR008["008 Website Architecture"] + ADR006 -.->|superseded| ADR007 + end + + subgraph Features["Features"] + ADR010["010 Gage R&R"] + ADR014["014 Regression Deferral"] + ADR015["015 Investigation Board"] + end + + subgraph Teams["Teams Platform"] + ADR016["016 Teams Integration"] + ADR018["018 Channel @Mention"] + ADR007 --> ADR016 + ADR015 --> ADR016 + ADR016 --> ADR018 + ADR015 --> ADR018 + end + + style ADR006 fill:#94a3b8,color:#fff + style ADR010 fill:#94a3b8,color:#fff +``` + +See also: [Documentation Methodology — ADR Dependency Map](../05-technical/documentation-methodology.md#adr-dependency-map) for the full methodology context. --- diff --git a/docs/08-products/azure/arm-template.md b/docs/08-products/azure/arm-template.md index 3c23ddbb7..d2314de66 100644 --- a/docs/08-products/azure/arm-template.md +++ b/docs/08-products/azure/arm-template.md @@ -1,3 +1,7 @@ +--- +title: 'ARM Template Documentation' +--- + # ARM Template Documentation Azure Resource Manager (ARM) template for VariScout Managed Application deployment. diff --git a/docs/08-products/azure/authentication.md b/docs/08-products/azure/authentication.md index 658d28130..a694e0863 100644 --- a/docs/08-products/azure/authentication.md +++ b/docs/08-products/azure/authentication.md @@ -1,3 +1,7 @@ +--- +title: 'Authentication (EasyAuth)' +--- + # Authentication (EasyAuth) App Service Authentication (EasyAuth) integration for Azure AD SSO. diff --git a/docs/08-products/azure/certification-guide.md b/docs/08-products/azure/certification-guide.md index 03c5c6218..c1df8abaa 100644 --- a/docs/08-products/azure/certification-guide.md +++ b/docs/08-products/azure/certification-guide.md @@ -1,3 +1,7 @@ +--- +title: 'Azure Marketplace Certification Guide' +--- + # Azure Marketplace Certification Guide Permanent reference for what Microsoft evaluates during Managed Application certification review, mapped to VariScout's architecture. diff --git a/docs/08-products/azure/how-it-works.md b/docs/08-products/azure/how-it-works.md index eeed52497..4c5507e51 100644 --- a/docs/08-products/azure/how-it-works.md +++ b/docs/08-products/azure/how-it-works.md @@ -1,3 +1,7 @@ +--- +title: 'How It Works' +--- + # How It Works End-to-end guide to VariScout's Azure architecture — what gets deployed, how users log in, where data lives, and why it's secure. diff --git a/docs/08-products/azure/index.md b/docs/08-products/azure/index.md index c8e2358cf..1247997eb 100644 --- a/docs/08-products/azure/index.md +++ b/docs/08-products/azure/index.md @@ -1,3 +1,7 @@ +--- +title: 'Azure App (Primary Product)' +--- + # Azure App (Primary Product) VariScout for Microsoft 365 enterprises - the only paid product, distributed via Azure Marketplace as a Managed Application. diff --git a/docs/08-products/azure/marketplace.md b/docs/08-products/azure/marketplace.md index a6ebf27ea..4984549cc 100644 --- a/docs/08-products/azure/marketplace.md +++ b/docs/08-products/azure/marketplace.md @@ -1,3 +1,7 @@ +--- +title: 'Azure Marketplace Guide' +--- + # Azure Marketplace Guide How to publish and manage VariScout on Azure Marketplace. diff --git a/docs/08-products/azure/onedrive-sync.md b/docs/08-products/azure/onedrive-sync.md index 06fc1351d..2a0943419 100644 --- a/docs/08-products/azure/onedrive-sync.md +++ b/docs/08-products/azure/onedrive-sync.md @@ -1,3 +1,7 @@ +--- +title: 'OneDrive & SharePoint Sync' +--- + # OneDrive & SharePoint Sync Analysis synchronization with Microsoft OneDrive and SharePoint. diff --git a/docs/08-products/azure/pricing-tiers.md b/docs/08-products/azure/pricing-tiers.md index 1fbe25088..7f0b57e46 100644 --- a/docs/08-products/azure/pricing-tiers.md +++ b/docs/08-products/azure/pricing-tiers.md @@ -1,3 +1,7 @@ +--- +title: 'Pricing' +--- + # Pricing VariScout Azure App pricing structure — two plans differentiated by storage, collaboration, and mobile capabilities. diff --git a/docs/08-products/azure/storage.md b/docs/08-products/azure/storage.md index 121e8514d..001d4e3ea 100644 --- a/docs/08-products/azure/storage.md +++ b/docs/08-products/azure/storage.md @@ -1,3 +1,7 @@ +--- +title: 'Azure App Storage' +--- + # Azure App Storage Offline-first persistence with optional OneDrive cloud sync (Team plan). diff --git a/docs/08-products/azure/submission-checklist.md b/docs/08-products/azure/submission-checklist.md index 3d7260e37..b3e098c3f 100644 --- a/docs/08-products/azure/submission-checklist.md +++ b/docs/08-products/azure/submission-checklist.md @@ -1,3 +1,7 @@ +--- +title: 'Azure Marketplace Submission Checklist' +--- + # Azure Marketplace Submission Checklist Living tracker for Azure Marketplace Managed Application submission. Single source of truth for what's done, what's pending, and what's blocking. diff --git a/docs/08-products/feature-parity.md b/docs/08-products/feature-parity.md index ad4b45f2c..06554c7eb 100644 --- a/docs/08-products/feature-parity.md +++ b/docs/08-products/feature-parity.md @@ -1,3 +1,7 @@ +--- +title: 'Feature Parity Matrix' +--- + # Feature Parity Matrix Complete feature availability across VariScout platforms. diff --git a/docs/08-products/index.md b/docs/08-products/index.md index bcdab77d3..e59c5337b 100644 --- a/docs/08-products/index.md +++ b/docs/08-products/index.md @@ -1,3 +1,7 @@ +--- +title: 'Products' +--- + # Products VariScout is a 2-product model: **free PWA** for learning and training, **paid Azure App** for teams. @@ -35,8 +39,9 @@ flowchart LR | [Power BI](powerbi/index.md) | Planned | AppSource | Dashboard integration | TBD | | [Website](website/index.md) | Production | Public | Marketing & docs | N/A | -!!! tip "Getting Started" +:::tip[Getting Started] **Free**: Start with the [PWA](pwa/index.md) — free training tool with copy-paste input and 16 sample datasets. Upgrade to the [Azure App](azure/index.md) for file upload, save/persistence, Performance Mode, and team features. +::: --- diff --git a/docs/08-products/powerbi/index.md b/docs/08-products/powerbi/index.md index bfc66f6a3..2f09fdbe6 100644 --- a/docs/08-products/powerbi/index.md +++ b/docs/08-products/powerbi/index.md @@ -1,3 +1,7 @@ +--- +title: 'Power BI Custom Visuals' +--- + # Power BI Custom Visuals VariScout charts as Power BI custom visuals. diff --git a/docs/08-products/pwa/index.md b/docs/08-products/pwa/index.md index 271bebcc1..9ad48e268 100644 --- a/docs/08-products/pwa/index.md +++ b/docs/08-products/pwa/index.md @@ -1,3 +1,7 @@ +--- +title: 'PWA (Free Training Tool)' +--- + # PWA (Free Training Tool) > **Role**: Free variation analysis training and education tool for quality professionals, students, and developing countries. diff --git a/docs/08-products/pwa/storage.md b/docs/08-products/pwa/storage.md index 434cb0f79..3ba6456d9 100644 --- a/docs/08-products/pwa/storage.md +++ b/docs/08-products/pwa/storage.md @@ -1,3 +1,7 @@ +--- +title: 'PWA Session Model' +--- + # PWA Session Model The PWA is a free training and education tool — data persistence is intentionally not provided. diff --git a/docs/08-products/website/content-architecture.md b/docs/08-products/website/content-architecture.md index 6f0ba5180..2a873d6be 100644 --- a/docs/08-products/website/content-architecture.md +++ b/docs/08-products/website/content-architecture.md @@ -1,3 +1,7 @@ +--- +title: 'Website Content Architecture' +--- + # Website Content Architecture Technical specification for how content is organized, cross-linked, and rendered on the VariScout website. diff --git a/docs/08-products/website/design-philosophy.md b/docs/08-products/website/design-philosophy.md index 70761ca6d..adefcddd5 100644 --- a/docs/08-products/website/design-philosophy.md +++ b/docs/08-products/website/design-philosophy.md @@ -1,3 +1,7 @@ +--- +title: 'Website Design Philosophy' +--- + # Website Design Philosophy > **"Guided Problem Playground"** — Every page starts with a professional's real problem, proves the solution with a live interactive chart, and offers contextual depth exactly where you need it. diff --git a/docs/08-products/website/index.md b/docs/08-products/website/index.md index 3139e5bd9..25401b6af 100644 --- a/docs/08-products/website/index.md +++ b/docs/08-products/website/index.md @@ -1,3 +1,7 @@ +--- +title: 'Marketing Website' +--- + # Marketing Website The variscout.com website serves three strategic purposes: **lead generation** through SEO-optimized educational content, **product education** through interactive chart demos, and **conversion** by funneling visitors toward the PWA (free) and Azure App (paid). diff --git a/docs/architecture/likec4/charts.c4 b/docs/architecture/likec4/charts.c4 new file mode 100644 index 000000000..95267b512 --- /dev/null +++ b/docs/architecture/likec4/charts.c4 @@ -0,0 +1,94 @@ +/** + * @variscout/charts — L3 Component decomposition + * Visx chart components: standard, performance, and supporting + */ + +model { + extend variscout.charts { + // Standard charts + ichart = component 'IChart' { + description 'Individual control chart with UCL/LCL, Nelson rule violations' + technology 'IChart.tsx' + } + + boxplot = component 'Boxplot' { + description 'Category boxplot with violin mode, sorting, annotations' + technology 'Boxplot.tsx' + } + + pareto = component 'ParetoChart' { + description 'Pareto ranking with cumulative line, annotations' + technology 'ParetoChart.tsx' + } + + capability = component 'CapabilityHistogram' { + description 'Process capability histogram with normal curve overlay' + technology 'CapabilityHistogram.tsx' + } + + probability = component 'ProbabilityPlot' { + description 'Normal probability plot for distribution assessment' + technology 'ProbabilityPlot.tsx' + } + + scatter = component 'ScatterPlot' { + description 'X-Y scatter with trend line' + technology 'ScatterPlot.tsx' + } + + // Performance charts (multi-measure) + perfIchart = component 'PerformanceIChart' { + description 'Cpk scatter plot by channel' + technology 'PerformanceIChart.tsx' + } + + perfBoxplot = component 'PerformanceBoxplot' { + description 'Distribution comparison across channels (max 5)' + technology 'PerformanceBoxplot.tsx' + } + + perfPareto = component 'PerformancePareto' { + description 'Cpk ranking, worst-first (max 20)' + technology 'PerformancePareto.tsx' + } + + perfCapability = component 'PerformanceCapability' { + description 'Single channel histogram drill-down' + technology 'PerformanceCapability.tsx' + } + + // Supporting + statsTable = component 'BoxplotStatsTable' { + description 'Summary statistics table for boxplot view' + technology 'BoxplotStatsTable.tsx' + } + + legend = component 'ChartLegend' { + description 'Shared chart legend component' + technology 'ChartLegend.tsx' + } + + signature = component 'ChartSignature' { + description 'Branding signature for exports' + technology 'ChartSignature.tsx' + } + + sourceBar = component 'ChartSourceBar' { + description 'Footer branding bar (free tier)' + technology 'ChartSourceBar.tsx' + } + } + + // Cross-package dependencies to @variscout/core + variscout.charts.ichart -> variscout.core.types 'uses StatsResult' + variscout.charts.ichart -> variscout.core.stats 'calculates control limits' + variscout.charts.boxplot -> variscout.core.types 'uses DataRow' + variscout.charts.pareto -> variscout.core.types 'uses DataRow' + variscout.charts.capability -> variscout.core.stats 'uses Cp/Cpk' + variscout.charts.probability -> variscout.core.stats 'uses distribution' + variscout.charts.perfIchart -> variscout.core.types 'uses ChannelResult' + variscout.charts.perfBoxplot -> variscout.core.types 'uses ChannelResult' + variscout.charts.perfPareto -> variscout.core.types 'uses ChannelResult' + variscout.charts.perfCapability -> variscout.core.stats 'uses Cp/Cpk' + variscout.charts.sourceBar -> variscout.core.tier 'checks isPaidTier' +} diff --git a/docs/architecture/likec4/core.c4 b/docs/architecture/likec4/core.c4 new file mode 100644 index 000000000..997f1001d --- /dev/null +++ b/docs/architecture/likec4/core.c4 @@ -0,0 +1,63 @@ +/** + * @variscout/core — L3 Component decomposition + * Pure TypeScript modules: statistics, parsing, tier, navigation, variation analysis + */ + +model { + extend variscout.core { + stats = component 'Statistics Engine' { + description 'calculateStats, mean, stddev, Cp, Cpk, ANOVA, Nelson rules' + technology 'stats.ts' + } + + parser = component 'CSV/Excel Parser' { + description 'parseCSV, parseExcel, detectColumns, keyword detection' + technology 'parser.ts' + } + + tier = component 'Tier System' { + description 'getTier, isPaidTier, channel limits, plan gating' + technology 'tier.ts' + } + + navigation = component 'Navigation' { + description 'drill path, filter types, breadcrumb state' + technology 'navigation.ts' + } + + types = component 'Types' { + description 'shared TypeScript interfaces (StatsResult, DataRow, etc.)' + technology 'types.ts' + } + + variation = component 'Variation Analysis' { + description 'contributions, simulation, decomposition, Total SS' + technology 'variation/' + } + + glossary = component 'Glossary' { + description 'terms, types, concept definitions (~20 terms)' + technology 'glossary/' + } + + export = component 'Export' { + description 'CSV export, chart data formatting' + technology 'export/' + } + + utils = component 'Utilities' { + description 'EXIF stripping, data transforms, helpers' + technology 'utils/' + } + } + + // Internal dependencies + variscout.core.stats -> variscout.core.types 'uses' + variscout.core.parser -> variscout.core.types 'uses' + variscout.core.variation -> variscout.core.stats 'uses' + variscout.core.variation -> variscout.core.types 'uses' + variscout.core.export -> variscout.core.types 'uses' + variscout.core.glossary -> variscout.core.types 'uses' + variscout.core.navigation -> variscout.core.types 'uses' + variscout.core.tier -> variscout.core.types 'uses' +} diff --git a/docs/architecture/likec4/hooks.c4 b/docs/architecture/likec4/hooks.c4 new file mode 100644 index 000000000..84071dc09 --- /dev/null +++ b/docs/architecture/likec4/hooks.c4 @@ -0,0 +1,94 @@ +/** + * @variscout/hooks — L3 Component decomposition + * Shared React hooks: state, navigation, chart data, export, tracking + */ + +model { + extend variscout.hooks { + // State + dataState = component 'useDataState' { + description 'Shared DataContext state management' + technology 'useDataState.ts' + } + + useTier = component 'useTier' { + description 'License tier state and limits' + technology 'useTier.ts' + } + + // Navigation + filterNav = component 'useFilterNavigation' { + description 'Filter navigation with multi-select, breadcrumbs' + technology 'useFilterNavigation.ts' + } + + keyboard = component 'useKeyboardNavigation' { + description 'Arrow key focus management' + technology 'useKeyboardNavigation.ts' + } + + // Chart Data + chartScale = component 'useChartScale' { + description 'Y-axis scale calculation' + technology 'useChartScale.ts' + } + + boxplotData = component 'useBoxplotData' { + description 'Shared d3 boxplot computation' + technology 'useBoxplotData.ts' + } + + ichartData = component 'useIChartData' { + description 'Shared I-Chart data transform' + technology 'useIChartData.ts' + } + + margins = component 'useResponsiveChartMargins' { + description 'Dynamic chart margins based on container width' + technology 'useResponsiveChartMargins.ts' + } + + paretoData = component 'useParetoChartData' { + description 'Shared Pareto chart data prep' + technology 'useParetoChartData.ts' + } + + dashboardData = component 'useDashboardComputedData' { + description 'Shared dashboard computed stats' + technology 'useDashboardComputedData.ts' + } + + // Export + chartCopy = component 'useChartCopy' { + description 'Copy-to-clipboard, PNG download, SVG download' + technology 'useChartCopy.ts' + } + + // Tracking + variationTracking = component 'useVariationTracking' { + description 'Cumulative Total SS scope tracking' + technology 'useVariationTracking.ts' + } + + annotationMode = component 'useAnnotationMode' { + description 'Chart annotation state (highlights, text notes)' + technology 'useAnnotationMode.ts' + } + + controlViolations = component 'useControlViolations' { + description 'Control chart violation detection' + technology 'useControlViolations.ts' + } + } + + // Cross-package dependencies to @variscout/core + variscout.hooks.dataState -> variscout.core.types 'uses DataRow, AnalysisState' + variscout.hooks.dataState -> variscout.core.parser 'invokes parseCSV' + variscout.hooks.useTier -> variscout.core.tier 'uses getTier' + variscout.hooks.filterNav -> variscout.core.navigation 'uses filter types' + variscout.hooks.chartScale -> variscout.core.types 'uses StatsResult' + variscout.hooks.boxplotData -> variscout.core.stats 'computes quartiles' + variscout.hooks.ichartData -> variscout.core.stats 'computes control limits' + variscout.hooks.variationTracking -> variscout.core.variation 'uses contributions' + variscout.hooks.controlViolations -> variscout.core.stats 'uses Nelson rules' +} diff --git a/docs/architecture/likec4/model.c4 b/docs/architecture/likec4/model.c4 new file mode 100644 index 000000000..5e7e08767 --- /dev/null +++ b/docs/architecture/likec4/model.c4 @@ -0,0 +1,144 @@ +/** + * VariScout — LikeC4 Architecture Model + * + * Source of truth for C4 architecture topology (L1-L3). + * Human-readable Mermaid views are maintained in: + * - docs/05-technical/architecture/system-map.md (L1 + L2) + * - docs/05-technical/architecture/component-map.md (L3) + * + * To render or export: + * pnpm docs:c4:serve — interactive browser + * pnpm docs:c4 — export to Mermaid + */ + +specification { + element actor + element system + element container + element component +} + +model { + // ────────────────────────────────────────────── + // L1 — People & External Systems + // ────────────────────────────────────────────── + + analyst = actor 'Quality Analyst' { + description 'Analyses process variation using control charts, capability indices, and Pareto rankings' + } + + variscout = system 'VariScout' { + description 'Offline-first variation analysis tool (PWA + Azure App)' + + // ────────────────────────────────────────── + // L2 — Containers + // ────────────────────────────────────────── + + core = container '@variscout/core' { + description 'Pure TypeScript: statistics, parser, tier, navigation, types, variation, glossary, export, utils' + technology 'TypeScript' + } + + charts = container '@variscout/charts' { + description 'React + Visx chart components: I-Chart, Boxplot, Pareto, Capability, Probability, Scatter, Performance variants' + technology 'React, Visx' + } + + hooks = container '@variscout/hooks' { + description 'Shared React hooks: state, navigation, chart data, export, tracking' + technology 'React' + } + + ui = container '@variscout/ui' { + description 'Shared UI components (52): input, data, analysis, charts, navigation, findings, simulation, dashboard, utilities' + technology 'React, Tailwind CSS' + } + + data = container '@variscout/data' { + description 'Pre-computed sample datasets: coffee, journey, bottleneck, sachets' + technology 'TypeScript' + } + + pwa = container 'apps/pwa' { + description 'Free demo tool — session-only storage, 3 factors, 50K rows' + technology 'React, Vite' + } + + azure = container 'apps/azure' { + description 'Paid Azure product — IndexedDB + OneDrive sync, 6 factors, 100K rows, Teams integration' + technology 'React, Vite, EasyAuth' + } + + website = container 'apps/website' { + description 'Marketing site with embedded chart demos' + technology 'Astro, React Islands' + } + + infra = container 'infra/' { + description 'ARM template for Azure Marketplace Managed Application deployment' + technology 'ARM JSON' + } + } + + // External systems + azuread = system 'Azure AD' { + description 'EasyAuth identity provider' + } + + onedrive = system 'Microsoft OneDrive' { + description 'Cloud file sync via Graph API' + } + + teams = system 'Microsoft Teams' { + description 'Channel tabs, SSO, photo capture' + } + + aisearch = system 'Azure AI Search' { + description 'AI-powered analysis suggestions' + } + + // ────────────────────────────────────────────── + // L1 — Relationships + // ────────────────────────────────────────────── + + analyst -> variscout 'Uploads data, reviews charts, investigates variation' + variscout -> azuread 'Authenticates via EasyAuth' + variscout -> onedrive 'Syncs projects (Team plan)' + variscout -> teams 'Embeds as channel tab, captures photos' + variscout -> aisearch 'Queries for AI-assisted analysis' + + // ────────────────────────────────────────────── + // L2 — Container relationships (dependency DAG) + // ────────────────────────────────────────────── + + // Package dependencies + variscout.charts -> variscout.core 'imports types, stats' + variscout.hooks -> variscout.core 'imports types, utilities, tier' + variscout.ui -> variscout.core 'imports types, tier' + variscout.ui -> variscout.hooks 'composes hooks' + variscout.ui -> variscout.charts 'wraps chart components' + + // App dependencies + variscout.pwa -> variscout.core 'imports' + variscout.pwa -> variscout.charts 'imports' + variscout.pwa -> variscout.hooks 'imports' + variscout.pwa -> variscout.ui 'imports' + variscout.pwa -> variscout.data 'loads samples' + + variscout.azure -> variscout.core 'imports' + variscout.azure -> variscout.charts 'imports' + variscout.azure -> variscout.hooks 'imports' + variscout.azure -> variscout.ui 'imports' + variscout.azure -> variscout.data 'loads samples' + + variscout.website -> variscout.charts 'embeds demos' + variscout.website -> variscout.data 'loads samples' + + // External integrations (Azure app only) + variscout.azure -> azuread 'EasyAuth authentication' + variscout.azure -> onedrive 'OneDrive sync (Team plan)' + variscout.azure -> teams 'Teams SDK integration' + variscout.azure -> aisearch 'AI search queries' + + variscout.infra -> variscout.azure 'deploys' +} diff --git a/docs/architecture/likec4/ui.c4 b/docs/architecture/likec4/ui.c4 new file mode 100644 index 000000000..678e14c3d --- /dev/null +++ b/docs/architecture/likec4/ui.c4 @@ -0,0 +1,267 @@ +/** + * @variscout/ui — L3 Component decomposition + * 52 shared UI components across 9 categories + */ + +model { + extend variscout.ui { + // Input (10) + columnMapping = component 'ColumnMapping' { + description 'Data-rich column mapping cards with type badges' + technology 'ColumnMapping/' + } + + createFactor = component 'CreateFactorModal' { + description 'Modal for creating computed factors' + technology 'CreateFactorModal/' + } + + measureSel = component 'MeasureColumnSelector' { + description 'Measure column selection dropdown' + technology 'MeasureColumnSelector/' + } + + charType = component 'CharacteristicTypeSelector' { + description 'Characteristic type (variable/attribute) selector' + technology 'CharacteristicTypeSelector/' + } + + manualEntry = component 'ManualEntryBase' { + description 'Manual data entry form' + technology 'ManualEntryBase/' + } + + manualSetup = component 'ManualEntrySetupBase' { + description 'Manual entry setup configuration' + technology 'ManualEntrySetupBase/' + } + + slider = component 'Slider' { + description 'Range slider component' + technology 'Slider/' + } + + specEditor = component 'SpecEditor' { + description 'Specification limit editor' + technology 'SpecEditor/' + } + + specsPopover = component 'SpecsPopover' { + description 'Specs display popover' + technology 'SpecsPopover/' + } + + pasteScreen = component 'PasteScreenBase' { + description 'Paste data entry screen' + technology 'PasteScreenBase/' + } + + // Data Display (4) + dataQuality = component 'DataQualityBanner' { + description 'Validation summary banner' + technology 'DataQualityBanner/' + } + + dataTable = component 'DataTableBase' { + description 'Shared data table with sorting and filtering' + technology 'DataTableBase/' + } + + perfDetected = component 'PerformanceDetectedModal' { + description 'Wide-format detection modal' + technology 'PerformanceDetectedModal/' + } + + mobileSheet = component 'MobileCategorySheet' { + description 'Bottom action sheet for mobile' + technology 'MobileCategorySheet/' + } + + // Analysis (8) + anova = component 'AnovaResults' { + description 'ANOVA results display' + technology 'AnovaResults/' + } + + statsPanel = component 'StatsPanelBase' { + description 'Statistics panel with 4 basic + 3 spec cards' + technology 'StatsPanelBase/' + } + + variationBar = component 'VariationBar' { + description 'Variation contribution bar' + technology 'VariationBar/' + } + + yAxisPopover = component 'YAxisPopover' { + description 'Y-axis configuration popover' + technology 'YAxisPopover/' + } + + axisEditor = component 'AxisEditor' { + description 'Axis range editor' + technology 'AxisEditor/' + } + + factorSel = component 'FactorSelector' { + description 'Factor selection dropdown' + technology 'FactorSelector/' + } + + investPrompt = component 'InvestigationPrompt' { + description 'Investigation guidance prompt' + technology 'InvestigationPrompt/' + } + + boxplotToggle = component 'BoxplotDisplayToggle' { + description 'Boxplot display options (violin, sort, contribution)' + technology 'BoxplotDisplayToggle/' + } + + // Chart Wrappers (6) + annotationLayer = component 'ChartAnnotationLayer' { + description 'Draggable text annotation overlay' + technology 'ChartAnnotationLayer/' + } + + annotationMenu = component 'AnnotationContextMenu' { + description 'Right-click menu for annotations' + technology 'AnnotationContextMenu/' + } + + chartCard = component 'ChartCard' { + description 'Chart container card' + technology 'ChartCard/' + } + + downloadMenu = component 'ChartDownloadMenu' { + description 'PNG/SVG download dropdown' + technology 'ChartDownloadMenu/' + } + + editTitle = component 'EditableChartTitle' { + description 'Editable chart title component' + technology 'EditableChartTitle/' + } + + focusedView = component 'FocusedChartViewBase' { + description 'Focused chart view overlay' + technology 'FocusedChartViewBase/' + } + + // Navigation (4) + breadcrumb = component 'FilterBreadcrumb' { + description 'Filter chip breadcrumb trail' + technology 'FilterBreadcrumb/' + } + + chipDropdown = component 'FilterChipDropdown' { + description 'Filter chip multi-select dropdown' + technology 'FilterChipDropdown/' + } + + contextBar = component 'FilterContextBar' { + description 'Filter context summary bar' + technology 'FilterContextBar/' + } + + selectionPanel = component 'SelectionPanel' { + description 'Data selection panel' + technology 'SelectionPanel/' + } + + // Findings (8) + findingsLog = component 'FindingsLog' { + description 'Findings list view' + technology 'FindingsLog/' + } + + findingCard = component 'FindingCard' { + description 'Individual finding card' + technology 'FindingCard/' + } + + findingEditor = component 'FindingEditor' { + description 'Finding edit form' + technology 'FindingEditor/' + } + + findingStatus = component 'FindingStatusBadge' { + description 'Status badge (observed/investigating/...)' + technology 'FindingStatusBadge/' + } + + findingComments = component 'FindingComments' { + description 'Finding comments thread' + technology 'FindingComments/' + } + + findingBoard = component 'FindingBoardView' { + description 'Horizontal drag-and-drop board' + technology 'FindingBoardView/' + } + + findingsPanel = component 'FindingsPanel' { + description 'Findings side panel (slide-in/inline)' + technology 'FindingsPanel/' + } + + findingsWindow = component 'FindingsWindow' { + description 'Popout findings window' + technology 'FindingsWindow/' + } + + // Simulation (2) + whatIf = component 'WhatIfSimulator' { + description 'What-If simulation controls' + technology 'WhatIfSimulator/' + } + + whatIfPage = component 'WhatIfPageBase' { + description 'What-If page layout' + technology 'WhatIfPageBase/' + } + + // Dashboard (5) + dashGrid = component 'DashboardGrid' { + description 'Responsive dashboard grid layout' + technology 'DashboardGrid/' + } + + dashCard = component 'DashboardChartCard' { + description 'Dashboard chart card wrapper' + technology 'DashboardChartCard/' + } + + focusedCard = component 'FocusedChartCard' { + description 'Focused chart card (expanded view)' + technology 'FocusedChartCard/' + } + + focusedOverlay = component 'FocusedViewOverlay' { + description 'Full-screen focused view overlay' + technology 'FocusedViewOverlay/' + } + + settingsPanel = component 'SettingsPanelBase' { + description 'Global settings panel' + technology 'SettingsPanelBase/' + } + + // Utilities (3) + helpTooltip = component 'HelpTooltip' { + description 'Help tooltip with glossary integration' + technology 'HelpTooltip/' + } + + upgradePrompt = component 'UpgradePrompt' { + description 'Tier upgrade call-to-action' + technology 'UpgradePrompt/' + } + + errorBoundary = component 'ErrorBoundary' { + description 'React error boundary wrapper' + technology 'ErrorBoundary/' + } + } +} diff --git a/docs/architecture/likec4/views.c4 b/docs/architecture/likec4/views.c4 new file mode 100644 index 000000000..fc167b819 --- /dev/null +++ b/docs/architecture/likec4/views.c4 @@ -0,0 +1,69 @@ +/** + * VariScout — View definitions + * L1 Context, L2 Containers, L3 per package + */ + +views { + // L1 — System Context + view SystemContext of variscout { + title 'VariScout System Context (C4 L1)' + description 'Quality Analyst interacts with VariScout; external Azure integrations' + + include * + autoLayout TopBottom + } + + // L2 — Container (all packages + apps) + view Containers of variscout { + title 'VariScout Container Diagram (C4 L2)' + description 'Monorepo packages, apps, and their dependency relationships' + + include * + autoLayout TopBottom + } + + // L3 — Component: @variscout/core + view CoreComponents of variscout.core { + title '@variscout/core Components (C4 L3)' + description 'Pure TypeScript modules: statistics, parsing, tier, navigation, variation analysis' + + include * + autoLayout TopBottom + } + + // L3 — Component: @variscout/charts + view ChartsComponents of variscout.charts { + title '@variscout/charts Components (C4 L3)' + description 'Visx chart components: standard, performance, and supporting' + + include * + autoLayout TopBottom + } + + // L3 — Component: @variscout/hooks + view HooksComponents of variscout.hooks { + title '@variscout/hooks Components (C4 L3)' + description 'Shared React hooks: state, navigation, chart data, export, tracking' + + include * + autoLayout TopBottom + } + + // L3 — Component: @variscout/ui + view UIComponents of variscout.ui { + title '@variscout/ui Components (C4 L3)' + description '52 shared UI components across 9 categories' + + include * + autoLayout TopBottom + } + + // L3 — Component: @variscout/data + view DataComponents of variscout.data { + title '@variscout/data Components (C4 L3)' + description 'Pre-computed sample datasets for demo and testing' + + include * + autoLayout TopBottom + } +} diff --git a/docs/archive/brushing-usage-example.md b/docs/archive/brushing-usage-example.md index 2edb2b498..c1a7c90ae 100644 --- a/docs/archive/brushing-usage-example.md +++ b/docs/archive/brushing-usage-example.md @@ -1,3 +1,7 @@ +--- +title: 'Minitab-Style Brushing - Usage Example' +--- + > **ARCHIVED**: This document describes historical implementation details. Do not reference for current work. # Minitab-Style Brushing - Usage Example diff --git a/docs/archive/create-factor-guide.md b/docs/archive/create-factor-guide.md index 41cb64ada..3ed97c21d 100644 --- a/docs/archive/create-factor-guide.md +++ b/docs/archive/create-factor-guide.md @@ -1,3 +1,7 @@ +--- +title: 'Create Factor from Selection - User Guide' +--- + > **ARCHIVED**: This document describes historical implementation details. Do not reference for current work. # Create Factor from Selection - User Guide diff --git a/docs/archive/implementation-summary.md b/docs/archive/implementation-summary.md index 1af034f0f..b0cdccf57 100644 --- a/docs/archive/implementation-summary.md +++ b/docs/archive/implementation-summary.md @@ -1,3 +1,7 @@ +--- +title: 'Phase 2 Implementation Summary: Create Factor from Selection' +--- + > **ARCHIVED**: This document describes historical implementation details. Do not reference for current work. # Phase 2 Implementation Summary: Create Factor from Selection diff --git a/docs/archive/minitab-brushing.md b/docs/archive/minitab-brushing.md index d3c4d0f18..3d9848381 100644 --- a/docs/archive/minitab-brushing.md +++ b/docs/archive/minitab-brushing.md @@ -1,3 +1,7 @@ +--- +title: 'Minitab-Style Brushing Feature' +--- + > **ARCHIVED**: This document describes historical implementation details. Do not reference for current work. # Minitab-Style Brushing Feature diff --git a/docs/archive/performance-mode-optimization.md b/docs/archive/performance-mode-optimization.md index 717e73c30..f17b6023f 100644 --- a/docs/archive/performance-mode-optimization.md +++ b/docs/archive/performance-mode-optimization.md @@ -1,3 +1,7 @@ +--- +title: 'Performance Mode Optimization - Implementation Summary' +--- + > **ARCHIVED**: This document describes historical implementation details. Do not reference for current work. # Performance Mode Optimization - Implementation Summary diff --git a/docs/archive/phase1-complete.md b/docs/archive/phase1-complete.md index e8675b9a3..b09f55880 100644 --- a/docs/archive/phase1-complete.md +++ b/docs/archive/phase1-complete.md @@ -1,3 +1,7 @@ +--- +title: 'Phase 1 Complete: Minitab-Style Brushing Implementation' +--- + > **ARCHIVED**: This document describes historical implementation details. Do not reference for current work. # Phase 1 Complete: Minitab-Style Brushing Implementation diff --git a/docs/archive/phases3-5-complete.md b/docs/archive/phases3-5-complete.md index 829c68e67..69faa11f3 100644 --- a/docs/archive/phases3-5-complete.md +++ b/docs/archive/phases3-5-complete.md @@ -1,3 +1,7 @@ +--- +title: 'Phases 3-5 Complete: Data Table Sync + Performance Integration + Polish' +--- + > **ARCHIVED**: This document describes historical implementation details. Do not reference for current work. # Phases 3-5 Complete: Data Table Sync + Performance Integration + Polish diff --git a/docs/archive/regression.md b/docs/archive/regression.md index 840ebe981..db31df583 100644 --- a/docs/archive/regression.md +++ b/docs/archive/regression.md @@ -1,3 +1,7 @@ +--- +title: 'Regression Analysis' +--- + # Regression Analysis Regression is VariScout's tool for exploring relationships between continuous variables. @@ -42,10 +46,11 @@ Regression answers: ## Use in VariScout -!!! note +:::note Regression in VariScout serves as a **first step** to visually check if correlation exists. It answers "is there a relationship?" before investing in deeper predictive modeling. For most variation analysis, the Four Lenses (I-Chart, Boxplot, Pareto, Capability) are sufficient. +::: --- diff --git a/docs/archive/special-cause-education-phase2.md b/docs/archive/special-cause-education-phase2.md index ba93bc4c2..a168306f0 100644 --- a/docs/archive/special-cause-education-phase2.md +++ b/docs/archive/special-cause-education-phase2.md @@ -1,3 +1,7 @@ +--- +title: 'Special Cause Education System - Phase 2 Implementation' +--- + > **ARCHIVED**: This document describes historical implementation details. Do not reference for current work. # Special Cause Education System - Phase 2 Implementation diff --git a/docs/glossary.md b/docs/glossary.md index f4478d8ba..4644cb5b4 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -1,3 +1,7 @@ +--- +title: 'Glossary' +--- + # Glossary Statistical and quality terms used across VariScout. diff --git a/docs/index.md b/docs/index.md index 2744c97be..473210002 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,8 @@ +--- +title: VariScout Documentation +description: Lightweight, offline-first variation analysis for quality professionals +--- + # VariScout Documentation **Lightweight, offline-first variation analysis for quality professionals.** @@ -20,41 +25,10 @@ pnpm --filter @variscout/azure-app dev ## Core Concepts -
- -- :material-chart-line:{ .lg .middle } **Four Lenses** - - *** - - Watson's Four Lenses of Process Knowledge: Change, Flow, Failure, Value - - [:octicons-arrow-right-24: Learn more](01-vision/four-lenses/index.md) - -- :material-bullseye:{ .lg .middle } **Two Voices** - - *** - - Understanding control limits (process voice) vs specification limits (customer voice) - - [:octicons-arrow-right-24: Learn more](01-vision/two-voices/index.md) - -- :material-filter:{ .lg .middle } **Drill-Down Analysis** - - *** - - Progressive stratification to find where variation hides - - [:octicons-arrow-right-24: Learn more](03-features/navigation/drill-down.md) - -- :material-school:{ .lg .middle } **Case Studies** - - *** - - Real-world examples with data files for learning - - [:octicons-arrow-right-24: Browse cases](04-cases/index.md) - -
+- **[Four Lenses](01-vision/four-lenses/index.md)** — Watson's Four Lenses of Process Knowledge: Change, Flow, Failure, Value +- **[Two Voices](01-vision/two-voices/index.md)** — Understanding control limits (process voice) vs specification limits (customer voice) +- **[Drill-Down Analysis](03-features/navigation/drill-down.md)** — Progressive stratification to find where variation hides +- **[Case Studies](04-cases/index.md)** — Real-world examples with data files for learning --- @@ -103,7 +77,7 @@ apps/ A unified design system covers both PWA and Azure App: theme-aware (dark/light), data-focused colors, consistent semantics across platforms, and WCAG AA accessible. -[:octicons-arrow-right-24: Technical documentation](05-technical/index.md) | [:octicons-arrow-right-24: Design system](06-design-system/index.md) +[Technical documentation](05-technical/index.md) | [Design system](06-design-system/index.md) --- @@ -113,4 +87,4 @@ This is a private repository. For contribution guidelines, contact the maintaine --- -_Documentation built with [MkDocs Material](https://squidfunk.github.io/mkdocs-material/)_ +_Documentation built with [Starlight](https://starlight.astro.build/)_ diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css deleted file mode 100644 index 0d188cc3f..000000000 --- a/docs/stylesheets/extra.css +++ /dev/null @@ -1,283 +0,0 @@ -/* VariScout Documentation Custom Styles */ - -/* Primary accent colors matching VariScout brand */ -:root { - --md-primary-fg-color: #3b82f6; - --md-primary-fg-color--light: #60a5fa; - --md-primary-fg-color--dark: #2563eb; - --md-accent-fg-color: #3b82f6; -} - -/* Status colors for documentation */ -.md-typeset .pass { - color: #22c55e; -} - -.md-typeset .fail { - color: #ef4444; -} - -.md-typeset .warning { - color: #f59e0b; -} - -/* Custom admonition for capability metrics */ -.md-typeset .admonition.capability, -.md-typeset details.capability { - border-color: #3b82f6; -} - -.md-typeset .capability > .admonition-title, -.md-typeset .capability > summary { - background-color: rgba(59, 130, 246, 0.1); -} - -.md-typeset .capability > .admonition-title::before, -.md-typeset .capability > summary::before { - background-color: #3b82f6; - -webkit-mask-image: var(--md-admonition-icon--info); - mask-image: var(--md-admonition-icon--info); -} - -/* Custom admonition for methodology concepts */ -.md-typeset .admonition.methodology, -.md-typeset details.methodology { - border-color: #8b5cf6; -} - -.md-typeset .methodology > .admonition-title, -.md-typeset .methodology > summary { - background-color: rgba(139, 92, 246, 0.1); -} - -.md-typeset .methodology > .admonition-title::before, -.md-typeset .methodology > summary::before { - background-color: #8b5cf6; - -webkit-mask-image: var(--md-admonition-icon--abstract); - mask-image: var(--md-admonition-icon--abstract); -} - -/* Table styling for better readability */ -.md-typeset table:not([class]) { - font-size: 0.85rem; -} - -.md-typeset table:not([class]) th { - background-color: var(--md-default-fg-color--lightest); -} - -/* Mermaid diagram sizing */ -.mermaid { - text-align: center; -} - -/* Journey map diagram styling */ -.md-typeset .journey-map { - max-width: 100%; - overflow-x: auto; -} - -/* Code block improvements */ -.md-typeset pre > code { - font-size: 0.8rem; -} - -/* Persona card styling */ -.persona-card { - border-left: 4px solid var(--md-primary-fg-color); - padding-left: 1rem; - margin: 1rem 0; -} - -/* Feature comparison tables */ -.md-typeset .comparison-table td:first-child { - font-weight: 600; -} - -/* Chart color documentation */ -.color-swatch { - display: inline-block; - width: 20px; - height: 20px; - border-radius: 4px; - vertical-align: middle; - margin-right: 8px; - border: 1px solid rgba(0, 0, 0, 0.1); -} - -/* Navigation improvements */ -.md-nav__link--active { - font-weight: 600; -} - -/* Footer customization */ -.md-footer-meta__inner { - display: flex; - flex-wrap: wrap; - justify-content: space-between; -} - -/* ─── Process Map Component ─── */ - -.process-map { - display: flex; - align-items: flex-start; - gap: 0; - overflow-x: auto; - padding: 1rem 0 0.5rem; - -webkit-overflow-scrolling: touch; -} - -.process-step { - display: flex; - flex-direction: column; - align-items: center; - flex-shrink: 0; - min-width: 140px; - max-width: 180px; -} - -.process-step__box { - border: 1px solid #334155; - border-left: 4px solid #64748b; - border-radius: 6px; - padding: 0.6rem 0.75rem; - background: #1e293b; - width: 100%; - text-align: center; -} - -.process-step__box--input { - border-left-color: #94a3b8; -} -.process-step__box--navigate { - border-left-color: #3b82f6; -} -.process-step__box--analyze { - border-left-color: #f59e0b; -} -.process-step__box--read { - border-left-color: #22c55e; - border-style: dashed; - border-left-style: solid; -} -.process-step__box--decision { - border-left-color: #8b5cf6; - border-radius: 2px; - background: linear-gradient(135deg, #1e293b 0%, #2d1b4e 100%); -} - -.process-step__title { - font-weight: 700; - font-size: 0.8rem; - color: #e2e8f0; - line-height: 1.3; -} - -.process-step__detail { - font-size: 0.7rem; - color: #94a3b8; - margin-top: 0.2rem; - line-height: 1.3; -} - -.process-step__clicks { - font-size: 0.65rem; - font-weight: 600; - color: #94a3b8; - background: #0f172a; - border: 1px solid #334155; - border-radius: 10px; - padding: 0.15rem 0.5rem; - margin-top: 0.4rem; - white-space: nowrap; -} - -.process-arrow { - display: flex; - align-items: center; - padding: 0 0.15rem; - flex-shrink: 0; - margin-top: 1.2rem; -} - -.process-arrow::after { - content: '→'; - color: #475569; - font-size: 1.1rem; - font-weight: 700; -} - -.process-summary { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - flex-shrink: 0; - margin-left: 0.5rem; - margin-top: 0.2rem; - padding: 0.6rem 0.75rem; - background: #0f172a; - border: 2px solid #334155; - border-radius: 6px; - min-width: 100px; -} - -.process-summary__total { - font-weight: 700; - font-size: 0.8rem; - color: #e2e8f0; -} - -.process-summary__time { - font-size: 0.7rem; - color: #94a3b8; - margin-top: 0.15rem; -} - -/* Light mode overrides */ -[data-md-color-scheme='default'] .process-step__box { - border-color: #cbd5e1; - background: #f8fafc; -} -[data-md-color-scheme='default'] .process-step__box--decision { - background: linear-gradient(135deg, #f8fafc 0%, #ede9fe 100%); -} -[data-md-color-scheme='default'] .process-step__title { - color: #1e293b; -} -[data-md-color-scheme='default'] .process-step__detail { - color: #64748b; -} -[data-md-color-scheme='default'] .process-step__clicks { - color: #64748b; - background: #f1f5f9; - border-color: #cbd5e1; -} -[data-md-color-scheme='default'] .process-arrow::after { - color: #94a3b8; -} -[data-md-color-scheme='default'] .process-summary { - background: #f1f5f9; - border-color: #cbd5e1; -} -[data-md-color-scheme='default'] .process-summary__total { - color: #1e293b; -} -[data-md-color-scheme='default'] .process-summary__time { - color: #64748b; -} - -/* Responsive: allow scroll on narrow viewports */ -@media (max-width: 768px) { - .process-step { - min-width: 120px; - max-width: 150px; - } - .process-step__title { - font-size: 0.75rem; - } - .process-step__detail { - font-size: 0.65rem; - } -} diff --git a/mkdocs.yml b/mkdocs.yml deleted file mode 100644 index 0ddf1079c..000000000 --- a/mkdocs.yml +++ /dev/null @@ -1,287 +0,0 @@ -site_name: VariScout Documentation -site_description: Lightweight, offline-first variation analysis for quality professionals -site_url: https://docs.variscout.com - -repo_url: https://github.com/variscout/variscout-lite -repo_name: variscout/variscout-lite - -theme: - name: material - palette: - - scheme: slate - primary: blue - accent: blue - toggle: - icon: material/brightness-4 - name: Switch to light mode - - scheme: default - primary: blue - accent: blue - toggle: - icon: material/brightness-7 - name: Switch to dark mode - features: - - navigation.tabs - - navigation.tabs.sticky - - navigation.sections - - navigation.expand - - navigation.indexes - - navigation.top - - search.highlight - - search.share - - content.tabs.link - - content.code.copy - icon: - repo: fontawesome/brands/github - -plugins: - - search - - mermaid2 - - tags - -markdown_extensions: - - admonition - - pymdownx.details - - pymdownx.superfences: - custom_fences: - - name: mermaid - class: mermaid - format: !!python/name:pymdownx.superfences.fence_code_format - - pymdownx.tabbed: - alternate_style: true - - pymdownx.tasklist: - custom_checkbox: true - - attr_list - - md_in_html - - tables - - toc: - permalink: true - - pymdownx.highlight: - anchor_linenums: true - - pymdownx.inlinehilite - - pymdownx.snippets - -extra_css: - - stylesheets/extra.css - -nav: - - Home: index.md - - - Domain: - - 01-vision/index.md - - Philosophy: 01-vision/philosophy.md - - Product Overview: 01-vision/product-overview.md - - Market Analysis: 01-vision/market-analysis.md - - Progressive Stratification: 01-vision/progressive-stratification.md - - Four Lenses: - - 01-vision/four-lenses/index.md - - Change: 01-vision/four-lenses/change.md - - Flow: 01-vision/four-lenses/flow.md - - Failure: 01-vision/four-lenses/failure.md - - Value: 01-vision/four-lenses/value.md - - Drill-Down: 01-vision/four-lenses/drilldown.md - - Two Voices: - - 01-vision/two-voices/index.md - - Control Limits: 01-vision/two-voices/control-limits.md - - Spec Limits: 01-vision/two-voices/spec-limits.md - - Variation Types: 01-vision/two-voices/variation-types.md - - Scenarios: 01-vision/two-voices/scenarios.md - - Evaluations: - - 01-vision/evaluations/index.md - - Investigation Flow Map: 01-vision/evaluations/investigation-flow-map.md - - Design Brief: 01-vision/evaluations/design-brief-guided-investigation.md - - Mindmap Spec: 01-vision/evaluations/design-spec-investigation-mindmap.md - - Competitive: - - Minitab: 01-vision/evaluations/competitive/minitab-benchmark.md - - JMP: 01-vision/evaluations/competitive/jmp-benchmark.md - - Tableau: 01-vision/evaluations/competitive/tableau-benchmark.md - - Power BI: 01-vision/evaluations/competitive/powerbi-benchmark.md - - EDAScout: 01-vision/evaluations/competitive/edascout-benchmark.md - - Other: 01-vision/evaluations/competitive/minor-competitors.md - - Patterns: - - Investigation Mindmap: 01-vision/evaluations/patterns/investigation-mindmap.md - - Investigation Narrative: 01-vision/evaluations/patterns/investigation-narrative.md - - Factor Suggestion: 01-vision/evaluations/patterns/factor-suggestion.md - - Auto Combination: 01-vision/evaluations/patterns/auto-combination-finder.md - - Interaction Heatmap: 01-vision/evaluations/patterns/interaction-heatmap.md - - Sidebar Filter: 01-vision/evaluations/patterns/sidebar-filter-panel.md - - Small Multiples: 01-vision/evaluations/patterns/small-multiples.md - - Factor Map: 01-vision/evaluations/patterns/factor-map.md - - Parallel Paths: 01-vision/evaluations/patterns/parallel-path-comparison.md - - Tensions: - - Discoverability: 01-vision/evaluations/tensions/discoverability.md - - Factor Ordering: 01-vision/evaluations/tensions/factor-ordering.md - - Hierarchy Assumption: 01-vision/evaluations/tensions/hierarchy-assumption.md - - Mobile Screen: 01-vision/evaluations/tensions/mobile-screen-budget.md - - Path Dependency: 01-vision/evaluations/tensions/path-dependency.md - - When to Stop: 01-vision/evaluations/tensions/when-to-stop.md - - Personas: - - Green Belt Gary: 02-journeys/personas/green-belt-gary.md - - Curious Carlos: 02-journeys/personas/curious-carlos.md - - OpEx Olivia: 02-journeys/personas/opex-olivia.md - - Student Sara: 02-journeys/personas/student-sara.md - - Evaluator Erik: 02-journeys/personas/evaluator-erik.md - - Trainer Tina: 02-journeys/personas/trainer-tina.md - - UX Research: 02-journeys/ux-research.md - - Use Cases: - - 02-journeys/use-cases/index.md - - Batch Consistency: 02-journeys/use-cases/batch-consistency.md - - Bottleneck Analysis: 02-journeys/use-cases/bottleneck-analysis.md - - Call Center: 02-journeys/use-cases/call-center-performance.md - - Complaint Investigation: 02-journeys/use-cases/complaint-investigation.md - - Consultant Delivery: 02-journeys/use-cases/consultant-delivery.md - - COPQ Drilldown: 02-journeys/use-cases/copq-drilldown.md - - Lead Time: 02-journeys/use-cases/lead-time-variation.md - - On-Time Delivery: 02-journeys/use-cases/on-time-delivery.md - - Patient Wait Time: 02-journeys/use-cases/patient-wait-time.md - - Pharma OOS: 02-journeys/use-cases/pharma-oos.md - - Supplier PPAP: 02-journeys/use-cases/supplier-ppap.md - - Supplier Performance: 02-journeys/use-cases/supplier-performance.md - - University SPC: 02-journeys/use-cases/university-spc.md - - User Flows: - - SEO Learner: 02-journeys/flows/seo-learner.md - - Social Discovery: 02-journeys/flows/social-discovery.md - - Content & YouTube: 02-journeys/flows/content-youtube.md - - Enterprise: 02-journeys/flows/enterprise.md - - Return Visitor: 02-journeys/flows/return-visitor.md - - Azure First Analysis: 02-journeys/flows/azure-first-analysis.md - - Azure Daily Use: 02-journeys/flows/azure-daily-use.md - - Azure Team Collaboration: 02-journeys/flows/azure-team-collaboration.md - - Case Studies: - - 04-cases/index.md - - Bottleneck: 04-cases/bottleneck/index.md - - Hospital Ward: 04-cases/hospital-ward/index.md - - Coffee: 04-cases/coffee/index.md - - Packaging: 04-cases/packaging/index.md - - Avocado: 04-cases/avocado/index.md - - Machine Utilization: 04-cases/machine-utilization/index.md - - Oven Zones: 04-cases/oven-zones/index.md - - - Features: - - 03-features/index.md - - Specifications: 03-features/specifications.md - - User Guide: 03-features/user-guide.md - - Analysis: - - I-Chart: 03-features/analysis/i-chart.md - - Boxplot: 03-features/analysis/boxplot.md - - Pareto: 03-features/analysis/pareto.md - - Capability: 03-features/analysis/capability.md - - Probability Plot: 03-features/analysis/probability-plot.md - - Regression: 03-features/analysis/regression.md - - Performance Mode: 03-features/analysis/performance-mode.md - - Nelson Rules: 03-features/analysis/nelson-rules.md - - Staged Analysis: 03-features/analysis/staged-analysis.md - - Workflows: - - 03-features/workflows/index.md - - Process Maps: 03-features/workflows/process-maps.md - - Four Lenses: 03-features/workflows/four-lenses-workflow.md - - Drill-Down: 03-features/workflows/drill-down-workflow.md - - Performance Mode: 03-features/workflows/performance-mode-workflow.md - - Quick Check: 03-features/workflows/quick-check.md - - Deep Dive: 03-features/workflows/deep-dive.md - - Decision Trees: 03-features/workflows/decision-trees.md - - Investigation to Action: 03-features/workflows/investigation-to-action.md - - Navigation: - - Drill-Down: 03-features/navigation/drill-down.md - - Linked Filtering: 03-features/navigation/linked-filtering.md - - Breadcrumbs: 03-features/navigation/breadcrumbs.md - - Data: - - Data Input: 03-features/data/data-input.md - - Validation: 03-features/data/validation.md - - Storage: 03-features/data/storage.md - - Learning: - - Glossary Feature: 03-features/learning/glossary.md - - Help Tooltips: 03-features/learning/help-tooltips.md - - Case-Based Learning: 03-features/learning/case-based-learning.md - - Glossary: glossary.md - - - Architecture: - - 05-technical/index.md - - Overview: 05-technical/architecture.md - - Structure: - - Monorepo: 05-technical/architecture/monorepo.md - - Offline-First: 05-technical/architecture/offline-first.md - - Shared Packages: 05-technical/architecture/shared-packages.md - - Data Flow: 05-technical/architecture/data-flow.md - - Component Patterns: 05-technical/architecture/component-patterns.md - - Implementation: - - Deployment: 05-technical/implementation/deployment.md - - Testing: 05-technical/implementation/testing.md - - Data Input: 05-technical/implementation/data-input.md - - System Limits: 05-technical/implementation/system-limits.md - - Security Scanning: 05-technical/implementation/security-scanning.md - - AI Tooling: 05-technical/implementation/ruflo.md - - Integrations: - - Embed Messaging: 05-technical/integrations/embed-messaging.md - - Shared UI: 05-technical/integrations/shared-ui.md - - Design System: - - 06-design-system/index.md - - Foundations: - - Colors: 06-design-system/foundations/colors.md - - Typography: 06-design-system/foundations/typography.md - - Spacing: 06-design-system/foundations/spacing.md - - Accessibility: 06-design-system/foundations/accessibility.md - - Charts: - - Overview: 06-design-system/charts/overview.md - - I-Chart: 06-design-system/charts/ichart.md - - Boxplot: 06-design-system/charts/boxplot.md - - Pareto: 06-design-system/charts/pareto.md - - Capability: 06-design-system/charts/capability.md - - Scatter: 06-design-system/charts/scatter.md - - Probability Plot: 06-design-system/charts/probability-plot.md - - Performance Mode: 06-design-system/charts/performance-mode.md - - Executive Mode: 06-design-system/charts/executive-mode.md - - Colors: 06-design-system/charts/colors.md - - Responsive: 06-design-system/charts/responsive.md - - Hooks: 06-design-system/charts/hooks.md - - Shared Components: 06-design-system/charts/shared-components.md - - Components: - - Buttons: 06-design-system/components/buttons.md - - Cards: 06-design-system/components/cards.md - - Modals: 06-design-system/components/modals.md - - Forms: 06-design-system/components/forms.md - - Variation Funnel: 06-design-system/components/variation-funnel.md - - What-If Simulator: 06-design-system/components/what-if-simulator.md - - Interaction Guidance: 06-design-system/components/interaction-guidance.md - - Patterns: - - Layout: 06-design-system/patterns/layout.md - - Feedback: 06-design-system/patterns/feedback.md - - Navigation: 06-design-system/patterns/navigation.md - - Products: - - 08-products/index.md - - Feature Parity: 08-products/feature-parity.md - - PWA: - - 08-products/pwa/index.md - - Storage: 08-products/pwa/storage.md - - Azure: - - 08-products/azure/index.md - - How It Works: 08-products/azure/how-it-works.md - - Authentication: 08-products/azure/authentication.md - - OneDrive Sync: 08-products/azure/onedrive-sync.md - - Marketplace: 08-products/azure/marketplace.md - - ARM Template: 08-products/azure/arm-template.md - - Pricing Tiers: 08-products/azure/pricing-tiers.md - - Submission Checklist: 08-products/azure/submission-checklist.md - - Power BI: - - 08-products/powerbi/index.md - - Website: - - 08-products/website/index.md - - Design Philosophy: 08-products/website/design-philosophy.md - - Content Architecture: 08-products/website/content-architecture.md - - - Decisions: - - 07-decisions/index.md - - ADR-001 Monorepo: 07-decisions/adr-001-monorepo.md - - ADR-002 Visx Charts: 07-decisions/adr-002-visx-charts.md - - ADR-003 IndexedDB: 07-decisions/adr-003-indexeddb.md - - ADR-004 Offline-First: 07-decisions/adr-004-offline-first.md - - ADR-005 Props-Based Charts: 07-decisions/adr-005-props-based-charts.md - - ADR-006 Edition System: 07-decisions/adr-006-edition-system.md - - ADR-007 Azure Distribution: 07-decisions/adr-007-azure-marketplace-distribution.md - - ADR-008 Website Content: 07-decisions/adr-008-website-content-architecture.md - - ADR-009 Violin Mode: 07-decisions/adr-009-boxplot-violin-mode.md - - ADR-010 Gage R&R: 07-decisions/adr-010-gagerr-deferral.md - - ADR-011 AI Tooling: 07-decisions/adr-011-ai-development-tooling.md - - ADR-012 PWA Browser: 07-decisions/adr-012-pwa-browser-only.md - - ADR-013 Architecture Eval: 07-decisions/adr-013-architecture-evaluation-ddd-swarms.md - - Product Audit Feb 2026: 07-decisions/audit-2026-02-state-of-product.md diff --git a/package.json b/package.json index 153047c6a..67fdb66ae 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,13 @@ "format": "prettier --write \"packages/*/src/**/*.{ts,tsx}\" \"apps/*/src/**/*.{ts,tsx}\"", "format:check": "prettier --check \"packages/*/src/**/*.{ts,tsx}\" \"apps/*/src/**/*.{ts,tsx}\"", "prepare": "husky", - "docs:build": "mkdocs build", - "docs:serve": "mkdocs serve", - "docs:deploy": "mkdocs gh-deploy" + "docs:dev": "pnpm --filter @variscout/docs dev", + "docs:build": "pnpm --filter @variscout/docs build", + "docs:preview": "pnpm --filter @variscout/docs preview", + "docs:c4": "likec4 codegen mermaid --outdir docs/05-technical/architecture/generated/ docs/architecture/likec4/", + "docs:c4:serve": "likec4 serve docs/architecture/likec4/", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "lint-staged": { "**/*.{ts,tsx}": [ @@ -30,6 +34,12 @@ }, "devDependencies": { "@eslint/js": "^9.39.2", + "@storybook/addon-a11y": "^10.2.19", + "@storybook/addon-essentials": "^8.6.14", + "@storybook/addon-themes": "^10.2.19", + "@storybook/blocks": "^8.6.14", + "@storybook/react": "^10.2.19", + "@storybook/react-vite": "^10.2.19", "@typescript-eslint/eslint-plugin": "^8.56.1", "@typescript-eslint/parser": "^8.56.1", "@vitest/coverage-v8": "^4.0.18", @@ -38,8 +48,10 @@ "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^7.0.1", "husky": "^9.1.7", + "likec4": "^1.52.0", "lint-staged": "^16.2.7", "prettier": "^3.8.1", + "storybook": "^10.2.19", "typescript": "^5.8.3" }, "pnpm": { diff --git a/packages/core/package.json b/packages/core/package.json index 310930c6a..194e27725 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -14,7 +14,8 @@ "./responsive": "./src/responsive.ts" }, "scripts": { - "test": "vitest" + "test": "vitest", + "docs": "typedoc" }, "dependencies": { "d3-array": "^3.2.4", @@ -24,6 +25,8 @@ "devDependencies": { "@types/d3-array": "^3.2.1", "@types/papaparse": "^5.5.2", + "typedoc": "^0.28.17", + "typedoc-plugin-markdown": "^4.10.0", "typescript": "^5.8.3", "vitest": "^4.0.18" } diff --git a/packages/core/typedoc.json b/packages/core/typedoc.json new file mode 100644 index 000000000..1c0cb92bb --- /dev/null +++ b/packages/core/typedoc.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "entryPoints": ["src/index.ts"], + "out": "../../docs/05-technical/api/core", + "plugin": ["typedoc-plugin-markdown"], + "outputFileStrategy": "modules", + "hidePageHeader": true, + "hideBreadcrumbs": true, + "excludePrivate": true, + "excludeInternal": true, + "readme": "none", + "tsconfig": "../../tsconfig.json" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac0521399..99e90c2a3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,6 +22,24 @@ importers: '@eslint/js': specifier: ^9.39.2 version: 9.39.2 + '@storybook/addon-a11y': + specifier: ^10.2.19 + version: 10.2.19(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/addon-essentials': + specifier: ^8.6.14 + version: 8.6.14(@types/react@19.2.7)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/addon-themes': + specifier: ^10.2.19 + version: 10.2.19(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/blocks': + specifier: ^8.6.14 + version: 8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/react': + specifier: ^10.2.19 + version: 10.2.19(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3) + '@storybook/react-vite': + specifier: ^10.2.19 + version: 10.2.19(esbuild@0.27.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.59.0)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) '@typescript-eslint/eslint-plugin': specifier: ^8.56.1 version: 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) @@ -46,12 +64,18 @@ importers: husky: specifier: ^9.1.7 version: 9.1.7 + likec4: + specifier: ^1.52.0 + version: 1.52.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(picomatch@4.0.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.59.0)(terser@5.44.1)(yaml@2.8.2) lint-staged: specifier: ^16.2.7 version: 16.2.7 prettier: specifier: ^3.8.1 version: 3.8.1 + storybook: + specifier: ^10.2.19 + version: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) typescript: specifier: ^5.8.3 version: 5.9.3 @@ -124,7 +148,7 @@ importers: version: 18.3.7(@types/react@18.3.27) '@vitejs/plugin-react': specifier: ^4.4.1 - version: 4.7.0(vite@6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + version: 4.7.0(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) autoprefixer: specifier: ^10.4.23 version: 10.4.23(postcss@8.5.6) @@ -142,10 +166,25 @@ importers: version: 5.9.3 vite: specifier: ^6.3.0 - version: 6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + version: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) vitest: specifier: ^4.0.18 - version: 4.0.18(@types/node@25.0.3)(jiti@1.21.7)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + version: 4.0.18(@types/node@25.0.3)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + + apps/docs: + dependencies: + '@astrojs/starlight': + specifier: ^0.34.0 + version: 0.34.8(astro@5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2)) + astro: + specifier: ^5.10.0 + version: 5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2) + rehype-mermaid: + specifier: ^3.0.0 + version: 3.0.0(playwright@1.58.2) + sharp: + specifier: ^0.33.0 + version: 0.33.5 apps/pwa: dependencies: @@ -363,6 +402,12 @@ importers: '@types/papaparse': specifier: ^5.5.2 version: 5.5.2 + typedoc: + specifier: ^0.28.17 + version: 0.28.17(typescript@5.9.3) + typedoc-plugin-markdown: + specifier: ^4.10.0 + version: 4.10.0(typedoc@0.28.17(typescript@5.9.3)) typescript: specifier: ^5.8.3 version: 5.9.3 @@ -467,7 +512,7 @@ importers: version: 18.3.7(@types/react@18.3.27) '@vitejs/plugin-react': specifier: ^4.4.1 - version: 4.7.0(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + version: 4.7.0(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) autoprefixer: specifier: ^10.4.23 version: 10.4.23(postcss@8.5.6) @@ -485,13 +530,13 @@ importers: version: 5.9.3 vite: specifier: ^6.3.0 - version: 6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + version: 6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) vite-plugin-dts: specifier: ^4.5.0 - version: 4.5.4(@types/node@20.19.27)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + version: 4.5.4(@types/node@20.19.27)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) vitest: specifier: ^4.0.18 - version: 4.0.18(@types/node@20.19.27)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + version: 4.0.18(@types/node@20.19.27)(jiti@1.21.7)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) packages: @@ -505,6 +550,9 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + '@antfu/utils@0.7.10': resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} @@ -530,9 +578,21 @@ packages: '@astrojs/internal-helpers@0.7.5': resolution: {integrity: sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==} + '@astrojs/internal-helpers@0.7.6': + resolution: {integrity: sha512-GOle7smBWKfMSP8osUIGOlB5kaHdQLV3foCsf+5Q9Wsuu+C6Fs3Ez/ttXmhjZ1HkSgsogcM1RXSjjOVieHq16Q==} + '@astrojs/markdown-remark@6.3.10': resolution: {integrity: sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A==} + '@astrojs/markdown-remark@6.3.11': + resolution: {integrity: sha512-hcaxX/5aC6lQgHeGh1i+aauvSwIT6cfyFjKWvExYSxUhZZBBdvCliOtu06gbQyhbe0pGJNoNmqNlQZ5zYUuIyQ==} + + '@astrojs/mdx@4.3.14': + resolution: {integrity: sha512-FBrqJQORVm+rkRa2TS5CjU9PBA6hkhrwLVBSS9A77gN2+iehvjq1w6yya/d0YKC7osiVorKkr3Qd9wNbl0ZkGA==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + peerDependencies: + astro: ^5.0.0 + '@astrojs/prism@3.3.0': resolution: {integrity: sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} @@ -549,6 +609,11 @@ packages: '@astrojs/sitemap@3.7.0': resolution: {integrity: sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA==} + '@astrojs/starlight@0.34.8': + resolution: {integrity: sha512-XuYz0TfCZhje2u1Q9FNtmTdm7/B9QP91RDI1VkPgYvDhSYlME3k8gwgcBMHnR9ASDo2p9gskrqe7t1Pub/qryg==} + peerDependencies: + astro: ^5.5.0 + '@astrojs/telemetry@3.3.0': resolution: {integrity: sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} @@ -625,18 +690,34 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.28.5': resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + '@babel/core@7.28.5': resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} engines: {node: '>=6.9.0'} + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.28.5': resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} engines: {node: '>=6.9.0'} + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} @@ -645,6 +726,10 @@ packages: resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + '@babel/helper-create-class-features-plugin@7.28.5': resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==} engines: {node: '>=6.9.0'} @@ -674,12 +759,22 @@ packages: resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-transforms@7.28.3': resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-optimise-call-expression@7.27.1': resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} @@ -724,11 +819,20 @@ packages: resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.28.5': resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} engines: {node: '>=6.9.0'} @@ -1120,18 +1224,33 @@ packages: resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.28.5': resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} + '@braintree/sanitize-url@7.1.2': + resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} + '@bramus/specificity@2.4.2': resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} hasBin: true @@ -1143,6 +1262,21 @@ packages: resolution: {integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==} engines: {node: '>=18'} + '@chevrotain/cst-dts-gen@11.1.2': + resolution: {integrity: sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==} + + '@chevrotain/gast@11.1.2': + resolution: {integrity: sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==} + + '@chevrotain/regexp-to-ast@11.1.2': + resolution: {integrity: sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==} + + '@chevrotain/types@11.1.2': + resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} + + '@chevrotain/utils@11.1.2': + resolution: {integrity: sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==} + '@csstools/color-helpers@6.0.2': resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==} engines: {node: '>=20.19.0'} @@ -1174,6 +1308,10 @@ packages: resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} engines: {node: '>=20.19.0'} + '@ctrl/tinycolor@4.2.0': + resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==} + engines: {node: '>=14'} + '@emnapi/runtime@1.8.1': resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} @@ -1542,12 +1680,34 @@ packages: '@noble/hashes': optional: true + '@expressive-code/core@0.41.7': + resolution: {integrity: sha512-ck92uZYZ9Wba2zxkiZLsZGi9N54pMSAVdrI9uW3Oo9AtLglD5RmrdTwbYPCT2S/jC36JGB2i+pnQtBm/Ib2+dg==} + + '@expressive-code/plugin-frames@0.41.7': + resolution: {integrity: sha512-diKtxjQw/979cTglRFaMCY/sR6hWF0kSMg8jsKLXaZBSfGS0I/Hoe7Qds3vVEgeoW+GHHQzMcwvgx/MOIXhrTA==} + + '@expressive-code/plugin-shiki@0.41.7': + resolution: {integrity: sha512-DL605bLrUOgqTdZ0Ot5MlTaWzppRkzzqzeGEu7ODnHF39IkEBbFdsC7pbl3LbUQ1DFtnfx6rD54k/cdofbW6KQ==} + + '@expressive-code/plugin-text-markers@0.41.7': + resolution: {integrity: sha512-Ewpwuc5t6eFdZmWlFyeuy3e1PTQC0jFvw2Q+2bpcWXbOZhPLsT7+h8lsSIJxb5mS7wZko7cKyQ2RLYDyK6Fpmw==} + '@fast-csv/format@4.3.5': resolution: {integrity: sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==} '@fast-csv/parse@4.3.6': resolution: {integrity: sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==} + '@fortawesome/fontawesome-free@6.7.2': + resolution: {integrity: sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==} + engines: {node: '>=6'} + + '@gerrit0/mini-shiki@3.23.0': + resolution: {integrity: sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==} + + '@hpcc-js/wasm-graphviz@1.21.0': + resolution: {integrity: sha512-BQ06v/foSTxtwUyIdJYRz+S++/fHQuPVsFmX+pI3G66cANi1mQvsgToaN5deZ6ALEDUHsfHVMYlowNiimoET5g==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1564,37 +1724,75 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.1.0': + resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} + '@img/colour@1.0.0': resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} engines: {node: '>=18'} + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + '@img/sharp-darwin-arm64@0.34.5': resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + '@img/sharp-darwin-x64@0.34.5': resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + '@img/sharp-libvips-darwin-arm64@1.2.4': resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} cpu: [arm64] os: [darwin] + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + '@img/sharp-libvips-darwin-x64@1.2.4': resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} cpu: [x64] os: [darwin] + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + '@img/sharp-libvips-linux-arm64@1.2.4': resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] @@ -1610,32 +1808,64 @@ packages: cpu: [riscv64] os: [linux] + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -1654,30 +1884,59 @@ packages: cpu: [riscv64] os: [linux] + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + '@img/sharp-wasm32@0.34.5': resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -1689,12 +1948,24 @@ packages: cpu: [arm64] os: [win32] + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + '@img/sharp-win32-ia32@0.34.5': resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@img/sharp-win32-x64@0.34.5': resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -1705,6 +1976,15 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.4': + resolution: {integrity: sha512-6PyZBYKnnVNqOSB0YFly+62R7dmov8segT27A+RVTBVd4iAE6kbW9QBJGlyR2yG4D4ohzhZSTIu7BK1UTtmFFA==} + peerDependencies: + typescript: '>= 4.3.x' + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + typescript: + optional: true + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1724,6 +2004,27 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@likec4/core@1.52.0': + resolution: {integrity: sha512-hvEsJc2emXSSYELkE6sLPZP/DaUHoOZmFb4mnuvE0E67y/rYyxjq5GsoowH8la8CZzON6VwIAdS5rAks+INLXw==} + + '@likec4/icons@1.46.4': + resolution: {integrity: sha512-GAL7aW53Mq3RnbFGK8BxHi/vGf73F7ODqgf7yPqfv/Kslt7KxHoxr/ZDIHcSo0oF4tXhpL7GYlpsgY71UJseqw==} + peerDependencies: + react: ^18.x || ^19.x + react-dom: ^18.x || ^19.x + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + + '@mermaid-js/parser@1.0.1': + resolution: {integrity: sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==} + '@microsoft/api-extractor-model@7.33.3': resolution: {integrity: sha512-EMwfPbyt0bAxPEOf2skhaURyNayxSDinjyInOuZJleG1Zb4YmDrKpNP9XRI01jfJCT1OKdUyEIuX5GYHi11y2A==} @@ -1755,6 +2056,39 @@ packages: '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + '@pagefind/darwin-arm64@1.4.0': + resolution: {integrity: sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==} + cpu: [arm64] + os: [darwin] + + '@pagefind/darwin-x64@1.4.0': + resolution: {integrity: sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==} + cpu: [x64] + os: [darwin] + + '@pagefind/default-ui@1.4.0': + resolution: {integrity: sha512-wie82VWn3cnGEdIjh4YwNESyS1G6vRHwL6cNjy9CFgNnWW/PGRjsLq300xjVH5sfPFK3iK36UxvIBymtQIEiSQ==} + + '@pagefind/freebsd-x64@1.4.0': + resolution: {integrity: sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==} + cpu: [x64] + os: [freebsd] + + '@pagefind/linux-arm64@1.4.0': + resolution: {integrity: sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==} + cpu: [arm64] + os: [linux] + + '@pagefind/linux-x64@1.4.0': + resolution: {integrity: sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==} + cpu: [x64] + os: [linux] + + '@pagefind/windows-x64@1.4.0': + resolution: {integrity: sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==} + cpu: [x64] + os: [win32] + '@playwright/test@1.57.0': resolution: {integrity: sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==} engines: {node: '>=18'} @@ -1763,6 +2097,9 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + '@rolldown/pluginutils@1.0.0-rc.3': + resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} + '@rollup/plugin-babel@5.3.1': resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} @@ -1976,21 +2313,183 @@ packages: '@shikijs/engine-oniguruma@3.21.0': resolution: {integrity: sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==} + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} + '@shikijs/langs@3.21.0': resolution: {integrity: sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==} + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} + '@shikijs/themes@3.21.0': resolution: {integrity: sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==} + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} + '@shikijs/types@3.21.0': resolution: {integrity: sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==} + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} + '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@storybook/addon-a11y@10.2.19': + resolution: {integrity: sha512-SJGf1ghCoRVlwyiRwz5GiHuNvu7C5iCDNIRJW8WGOJlnoQa3rYaY7WJ/8a/eT9N8buIscL9AYWudhh5zsI1W3g==} + peerDependencies: + storybook: ^10.2.19 + + '@storybook/addon-actions@8.6.14': + resolution: {integrity: sha512-mDQxylxGGCQSK7tJPkD144J8jWh9IU9ziJMHfB84PKpI/V5ZgqMDnpr2bssTrUaGDqU5e1/z8KcRF+Melhs9pQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-backgrounds@8.6.14': + resolution: {integrity: sha512-l9xS8qWe5n4tvMwth09QxH2PmJbCctEvBAc1tjjRasAfrd69f7/uFK4WhwJAstzBTNgTc8VXI4w8ZR97i1sFbg==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-controls@8.6.14': + resolution: {integrity: sha512-IiQpkNJdiRyA4Mq9mzjZlvQugL/aE7hNgVxBBGPiIZG6wb6Ht9hNnBYpap5ZXXFKV9p2qVI0FZK445ONmAa+Cw==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-docs@8.6.14': + resolution: {integrity: sha512-Obpd0OhAF99JyU5pp5ci17YmpcQtMNgqW2pTXV8jAiiipWpwO++hNDeQmLmlSXB399XjtRDOcDVkoc7rc6JzdQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-essentials@8.6.14': + resolution: {integrity: sha512-5ZZSHNaW9mXMOFkoPyc3QkoNGdJHETZydI62/OASR0lmPlJ1065TNigEo5dJddmZNn0/3bkE8eKMAzLnO5eIdA==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-highlight@8.6.14': + resolution: {integrity: sha512-4H19OJlapkofiE9tM6K/vsepf4ir9jMm9T+zw5L85blJZxhKZIbJ6FO0TCG9PDc4iPt3L6+aq5B0X29s9zicNQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-measure@8.6.14': + resolution: {integrity: sha512-1Tlyb72NX8aAqm6I6OICsUuGOP6hgnXcuFlXucyhKomPa6j3Eu2vKu561t/f0oGtAK2nO93Z70kVaEh5X+vaGw==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-outline@8.6.14': + resolution: {integrity: sha512-CW857JvN6OxGWElqjlzJO2S69DHf+xO3WsEfT5mT3ZtIjmsvRDukdWfDU9bIYUFyA2lFvYjncBGjbK+I91XR7w==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-themes@10.2.19': + resolution: {integrity: sha512-TzcX/aqzZrQUypDATywLOenVoa1CTXBthODoY9odLsLLrxVaoeqsAdulkmOjeppKR1FigcERyIjIWPB8W48dag==} + peerDependencies: + storybook: ^10.2.19 + + '@storybook/addon-toolbars@8.6.14': + resolution: {integrity: sha512-W/wEXT8h3VyZTVfWK/84BAcjAxTdtRiAkT2KAN0nbSHxxB5KEM1MjKpKu2upyzzMa3EywITqbfy4dP6lpkVTwQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-viewport@8.6.14': + resolution: {integrity: sha512-gNzVQbMqRC+/4uQTPI2ZrWuRHGquTMZpdgB9DrD88VTEjNudP+J6r8myLfr2VvGksBbUMHkGHMXHuIhrBEnXYA==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/blocks@8.6.14': + resolution: {integrity: sha512-rBMHAfA39AGHgkrDze4RmsnQTMw1ND5fGWobr9pDcJdnDKWQWNRD7Nrlxj0gFlN3n4D9lEZhWGdFrCbku7FVAQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^8.6.14 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/builder-vite@10.2.19': + resolution: {integrity: sha512-a59xALzM9GeYh6p+wzAeBbDyIe+qyrC4nxS3QNzb5i2ZOhrq1iIpvnDaOWe80NC8mV3IlqUEGY8Uawkf//1Rmg==} + peerDependencies: + storybook: ^10.2.19 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@storybook/csf-plugin@10.2.19': + resolution: {integrity: sha512-BpjYIOdyQn/Rm6MjUAc5Gl8HlARZrskD/OhUNShiOh2fznb523dHjiE5mbU1kKM/+L1uvRlEqqih40rTx+xCrg==} + peerDependencies: + esbuild: '*' + rollup: 4.59.0 + storybook: ^10.2.19 + vite: '*' + webpack: '*' + peerDependenciesMeta: + esbuild: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + + '@storybook/csf-plugin@8.6.14': + resolution: {integrity: sha512-dErtc9teAuN+eelN8FojzFE635xlq9cNGGGEu0WEmMUQ4iJ8pingvBO1N8X3scz4Ry7KnxX++NNf3J3gpxS8qQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/global@5.0.0': + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + + '@storybook/icons@1.6.0': + resolution: {integrity: sha512-hcFZIjW8yQz8O8//2WTIXylm5Xsgc+lW9ISLgUk1xGmptIJQRdlhVIXCpSyLrQaaRiyhQRaVg7l3BD9S216BHw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + + '@storybook/icons@2.0.1': + resolution: {integrity: sha512-/smVjw88yK3CKsiuR71vNgWQ9+NuY2L+e8X7IMrFjexjm6ZR8ULrV2DRkTA61aV6ryefslzHEGDInGpnNeIocg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@storybook/react-dom-shim@10.2.19': + resolution: {integrity: sha512-BXCEfBGVBRYBTYeBeH/PJsy0Bq5MERe/HiaylR+ah/XrvIr2Z9bkne1J8yYiXCjiyq5HQa7Bj11roz0+vyUaEw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.2.19 + + '@storybook/react-dom-shim@8.6.14': + resolution: {integrity: sha512-0hixr3dOy3f3M+HBofp3jtMQMS+sqzjKNgl7Arfuj3fvjmyXOks/yGjDImySR4imPtEllvPZfhiQNlejheaInw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.6.14 + + '@storybook/react-vite@10.2.19': + resolution: {integrity: sha512-2/yMKrK4IqMIZicRpPMoIg+foBuWnkaEWt0R4V4hjErDj/SC3D9ov+GUqhjKJ81TegijhKzNpwnSD7Nf87haKw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.2.19 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@storybook/react@10.2.19': + resolution: {integrity: sha512-gm2qxLyYSsGp7fee5i+d8jSVUKMla8yRaTJ1wxPEnyaJMd0QUu6U2v3p2rW7PH1DWop3D6NqWOY8kmZjmSZKlA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.2.19 + typescript: '>= 4.9.x' + peerDependenciesMeta: + typescript: + optional: true + '@surma/rollup-plugin-off-main-thread@2.2.3': resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} @@ -2107,6 +2606,12 @@ packages: '@types/react-dom': optional: true + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + '@types/argparse@1.0.38': resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} @@ -2257,6 +2762,12 @@ packages: '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/doctrine@0.0.9': + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + '@types/estree@0.0.39': resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} @@ -2269,6 +2780,9 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -2278,6 +2792,9 @@ packages: '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} @@ -2327,9 +2844,15 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/uuid@9.0.8': + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + '@typescript-eslint/eslint-plugin@8.56.1': resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2396,6 +2919,9 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@upsetjs/venn.js@2.0.0': + resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} + '@visx/axis@3.12.0': resolution: {integrity: sha512-8MoWpfuaJkhm2Yg+HwyytK8nk+zDugCqTT/tRmQX7gW4LYrHYLXFUXOzbDyyBakCVaUbUaAhVFxpMASJiQKf7A==} peerDependencies: @@ -2469,6 +2995,12 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + '@vitejs/plugin-react@5.2.0': + resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + '@vitest/coverage-v8@4.0.18': resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==} peerDependencies: @@ -2478,6 +3010,9 @@ packages: '@vitest/browser': optional: true + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/expect@4.0.18': resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} @@ -2492,6 +3027,9 @@ packages: vite: optional: true + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/pretty-format@4.0.18': resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} @@ -2501,9 +3039,15 @@ packages: '@vitest/snapshot@4.0.18': resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/spy@4.0.18': resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@vitest/utils@4.0.18': resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} @@ -2672,9 +3216,22 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + ast-v8-to-istanbul@0.3.11: resolution: {integrity: sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==} + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + astro-expressive-code@0.41.7: + resolution: {integrity: sha512-hUpogGc6DdAd+I7pPXsctyYPRBJDK7Q7d06s4cyP0Vz3OcbziP3FNzN0jZci1BpCvLn9675DvS7B9ctKKX64JQ==} + peerDependencies: + astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta + astro@5.18.0: resolution: {integrity: sha512-CHiohwJIS4L0G6/IzE1Fx3dgWqXBCXus/od0eGUfxrZJD2um2pE7ehclMmgL/fXqbU7NfE1Ze2pq34h2QaA6iQ==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} @@ -2702,6 +3259,10 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + axe-core@4.11.1: + resolution: {integrity: sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==} + engines: {node: '>=4'} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -2790,6 +3351,12 @@ packages: resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} hasBin: true + bcp-47-match@2.0.3: + resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} + + bcp-47@2.1.0: + resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==} + bidi-js@1.0.3: resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} @@ -2860,6 +3427,12 @@ packages: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -2894,7 +3467,11 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - chai@6.2.2: + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} + + chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} @@ -2918,6 +3495,21 @@ packages: character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} + engines: {node: '>= 16'} + + chevrotain-allstar@0.3.1: + resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} + peerDependencies: + chevrotain: ^11.0.0 + + chevrotain@11.1.2: + resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -2948,6 +3540,10 @@ packages: resolution: {integrity: sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==} engines: {node: '>=20'} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + cliui@9.0.1: resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} engines: {node: '>=20'} @@ -2956,6 +3552,9 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -2991,6 +3590,14 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + common-ancestor-path@1.0.1: resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} @@ -3034,6 +3641,12 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} @@ -3057,6 +3670,9 @@ packages: css-select@5.2.2: resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + css-selector-parser@3.3.0: + resolution: {integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==} + css-tree@2.2.1: resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} @@ -3088,6 +3704,23 @@ packages: csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.33.1: + resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + d3-array@3.2.1: resolution: {integrity: sha512-gUY/qeHq/yNqqoCKNq4vtpFLdoCdvyNpWoC/KNjhGbhDuQpAM9sIQQKkXSNpXa9h5KySs/gzm7R88WkUutgwWQ==} engines: {node: '>=12'} @@ -3096,14 +3729,55 @@ packages: resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} engines: {node: '>=12'} + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + d3-color@3.1.0: resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} engines: {node: '>=12'} + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + d3-delaunay@6.0.2: resolution: {integrity: sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==} engines: {node: '>=12'} + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + d3-format@3.1.0: resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} engines: {node: '>=12'} @@ -3112,6 +3786,10 @@ packages: resolution: {integrity: sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==} engines: {node: '>=12'} + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + d3-interpolate@3.0.1: resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} engines: {node: '>=12'} @@ -3119,13 +3797,44 @@ packages: d3-path@1.0.9: resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + d3-scale@4.0.2: resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} engines: {node: '>=12'} + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + d3-shape@1.3.7: resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + d3-time-format@4.1.0: resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} engines: {node: '>=12'} @@ -3134,6 +3843,27 @@ packages: resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} engines: {node: '>=12'} + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.14: + resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} + data-urls@7.0.0: resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -3183,6 +3913,10 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -3251,6 +3985,10 @@ packages: resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} engines: {node: '>=0.3.1'} + direction@2.0.1: + resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} + hasBin: true + dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} @@ -3258,6 +3996,10 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -3274,6 +4016,9 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} + dompurify@3.3.3: + resolution: {integrity: sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==} + domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -3311,6 +4056,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -3369,6 +4118,12 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + esbuild@0.25.12: resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} engines: {node: '>=18'} @@ -3439,6 +4194,11 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -3451,6 +4211,24 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + estree-walker@1.0.1: resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} @@ -3486,6 +4264,9 @@ packages: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} + expressive-code@0.41.7: + resolution: {integrity: sha512-2wZjC8OQ3TaVEMcBtYY4Va3lo6J+Ai9jf3d4dbhURMJcU4Pbqe6EcHe424MIZI0VHUA1bR6xdpoHYi3yxokWqA==} + exsolve@1.0.8: resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} @@ -3525,6 +4306,14 @@ packages: fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fdir@6.4.0: + resolution: {integrity: sha512-3oB133prH1o4j/L5lLW7uOCF1PlD+/It2L0eL/iAqWMB91RBbqTewABqxhj0ibBd90EEmWZq7ntIWzVaWcXTGQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -3668,6 +4457,10 @@ packages: deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me @@ -3690,6 +4483,9 @@ packages: h3@1.15.5: resolution: {integrity: sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==} + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -3717,27 +4513,63 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-embedded@3.0.0: + resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} + + hast-util-format@1.1.0: + resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} + + hast-util-from-dom@5.0.1: + resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} + + hast-util-from-html-isomorphic@2.0.0: + resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} + hast-util-from-html@2.0.3: resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} hast-util-from-parse5@8.0.3: resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + + hast-util-is-body-ok-link@3.0.1: + resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} + hast-util-is-element@3.0.0: resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + hast-util-minify-whitespace@1.0.1: + resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} + hast-util-parse-selector@4.0.0: resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + hast-util-phrasing@3.0.1: + resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} + hast-util-raw@9.1.0: resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + hast-util-select@6.0.4: + resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + hast-util-to-html@9.0.5: resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + hast-util-to-parse5@8.0.1: resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + hast-util-to-text@4.0.2: resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} @@ -3773,6 +4605,9 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + html-whitespace-sensitive-tag-names@3.0.1: + resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} + http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} @@ -3789,9 +4624,16 @@ packages: engines: {node: '>=18'} hasBin: true + i18next@23.16.8: + resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} + ico-endec@0.1.6: resolution: {integrity: sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + idb@7.1.1: resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} @@ -3809,6 +4651,9 @@ packages: immediate@3.0.6: resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + immer@11.1.4: + resolution: {integrity: sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw==} + import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -3838,10 +4683,16 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + internmap@2.0.3: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} @@ -3849,6 +4700,12 @@ packages: iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -3888,6 +4745,9 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + is-docker@3.0.0: resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -3917,6 +4777,9 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-in-ssh@1.0.0: resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} engines: {node: '>=20'} @@ -4117,16 +4980,37 @@ packages: jws@4.0.1: resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + katex@0.16.38: + resolution: {integrity: sha512-cjHooZUmIAUmDsHBN+1n8LaZdpmbj03LtYeYPyuYB7OuloiaeaV6N4LcfjcnHVzGWjVQmKrxxTrpDcmSzEZQwQ==} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} + klona@2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} + kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + langium@4.2.1: + resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==} + engines: {node: '>=20.10.0', npm: '>=10.2.3'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + lazystream@1.0.1: resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} engines: {node: '>= 0.6.3'} @@ -4212,6 +5096,14 @@ packages: resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} engines: {node: '>= 12.0.0'} + likec4@1.52.0: + resolution: {integrity: sha512-2f1QRGGwdEbVKMT3gfkAqAuMAhASlCS1mr/38EyRZDqMk567IqEjAQ2wTQdf7pA/Xzj4SAsimkcR1CirHtfLKQ==} + engines: {node: '>=22.22.1'} + hasBin: true + peerDependencies: + react: ^18.x || ^19.x + react-dom: ^18.x || ^19.x + lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -4219,6 +5111,9 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + lint-staged@16.2.7: resolution: {integrity: sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==} engines: {node: '>=20.17'} @@ -4231,6 +5126,10 @@ packages: resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==} engines: {node: '>=20.0.0'} + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + local-pkg@1.1.2: resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} engines: {node: '>=14'} @@ -4239,6 +5138,9 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash-es@4.17.23: + resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} + lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -4317,6 +5219,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lru-cache@11.2.4: resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} @@ -4343,6 +5248,9 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -4360,9 +5268,25 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} + map-or-similar@1.5.0: + resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-it@14.1.1: + resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} + hasBin: true + markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + marked@16.4.2: + resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} + engines: {node: '>= 20'} + hasBin: true + math-expression-evaluator@1.4.0: resolution: {integrity: sha512-4vRUvPyxdO8cWULGTh9dZWL2tZK6LDBvj+OGHBER7poH9Qdt7kXEoj20wiz4lQUbUXQZFjPbe5mVDo9nutizCw==} @@ -4373,6 +5297,9 @@ packages: mdast-util-definitions@6.0.0: resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + mdast-util-find-and-replace@3.0.2: resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} @@ -4397,6 +5324,18 @@ packages: mdast-util-gfm@3.1.0: resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + mdast-util-phrasing@4.1.0: resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} @@ -4415,13 +5354,33 @@ packages: mdn-data@2.12.2: resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + memoizerific@1.11.3: + resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + mermaid-isomorphic@3.1.0: + resolution: {integrity: sha512-mzrvfEVjnJIkJlEqxp3eMuR1wS0TeLCH1VK5E/T5yzWaBwI3JqjJuw70yUIThSCDJ5bRs6O3rgfp00oBAbvSeQ==} + peerDependencies: + playwright: '1' + peerDependenciesMeta: + playwright: + optional: true + + mermaid@11.13.0: + resolution: {integrity: sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==} + micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + micromark-extension-gfm-autolink-literal@2.1.0: resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} @@ -4443,12 +5402,30 @@ packages: micromark-extension-gfm@3.0.0: resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + micromark-factory-destination@2.0.1: resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} micromark-factory-label@2.0.1: resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + micromark-factory-space@2.0.1: resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} @@ -4479,6 +5456,9 @@ packages: micromark-util-encode@2.0.1: resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + micromark-util-html-tag-name@2.0.1: resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} @@ -4519,6 +5499,10 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + mini-svg-data-uri@1.4.4: + resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} + hasBin: true + minimatch@10.2.4: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} @@ -4537,8 +5521,8 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} mkdirp-classic@0.5.3: @@ -4705,6 +5689,10 @@ packages: package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + pagefind@1.4.0: + resolution: {integrity: sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==} + hasBin: true + pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -4715,6 +5703,9 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse-latin@7.0.0: resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} @@ -4727,6 +5718,9 @@ packages: path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -4742,13 +5736,17 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@2.0.1: - resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} - engines: {node: 20 || >=22} + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + piccolore@0.1.3: resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} @@ -4787,11 +5785,31 @@ packages: engines: {node: '>=18'} hasBin: true + playwright-core@1.58.2: + resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} + engines: {node: '>=18'} + hasBin: true + playwright@1.57.0: resolution: {integrity: sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==} engines: {node: '>=18'} hasBin: true + playwright@1.58.2: + resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==} + engines: {node: '>=18'} + hasBin: true + + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + + polished@4.3.1: + resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} + engines: {node: '>=10'} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -4894,6 +5912,10 @@ packages: pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -4911,6 +5933,15 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true + react-docgen-typescript@2.4.0: + resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} + peerDependencies: + typescript: '>= 4.3.x' + + react-docgen@8.0.3: + resolution: {integrity: sha512-aEZ9qP+/M+58x2qgfSFEWH1BxLyHe5+qkLNJOZQb5iGS017jpbRnoKhNRrXPeA6RfBrZO5wZrT9DMC1UqE1f1w==} + engines: {node: ^20.9.0 || >=22} + react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -4931,6 +5962,10 @@ packages: resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} engines: {node: '>=0.10.0'} + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + react-use-measure@2.1.7: resolution: {integrity: sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==} peerDependencies: @@ -4969,6 +6004,24 @@ packages: resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} engines: {node: '>= 20.19.0'} + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -5014,21 +6067,44 @@ packages: resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} hasBin: true + rehype-expressive-code@0.41.7: + resolution: {integrity: sha512-25f8ZMSF1d9CMscX7Cft0TSQIqdwjce2gDOvQ+d/w0FovsMwrSt3ODP4P3Z7wO1jsIJ4eYyaDRnIR/27bd/EMQ==} + + rehype-format@5.0.1: + resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} + + rehype-mermaid@3.0.0: + resolution: {integrity: sha512-fxrD5E4Fa1WXUjmjNDvLOMT4XB1WaxcfycFIWiYU0yEMQhcTDElc9aDFnbDFRLxG1Cfo1I3mfD5kg4sjlWaB+Q==} + peerDependencies: + playwright: '1' + peerDependenciesMeta: + playwright: + optional: true + rehype-parse@9.0.1: resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} rehype-raw@7.0.0: resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + rehype-stringify@10.0.1: resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} rehype@13.0.2: resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + remark-gfm@4.0.1: resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + remark-parse@11.0.0: resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} @@ -5042,6 +6118,10 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} @@ -5113,6 +6193,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + run-applescript@7.1.0: resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} engines: {node: '>=18'} @@ -5120,6 +6203,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + safe-array-concat@1.1.3: resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} @@ -5138,6 +6224,9 @@ packages: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sax@1.4.3: resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} @@ -5199,6 +6288,10 @@ packages: resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} engines: {node: '>=14.15.0'} + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + sharp@0.34.5: resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -5305,6 +6398,15 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + storybook@10.2.19: + resolution: {integrity: sha512-UUm5eGSm6BLhkcFP0WbxkmAHJZfVN2ViLpIZOqiIPS++q32VYn+CLFC0lrTYTDqYvaG7i4BK4uowXYujzE4NdQ==} + hasBin: true + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + stream-replace-string@2.0.0: resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} @@ -5371,6 +6473,10 @@ packages: resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + strip-comments@2.0.1: resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==} engines: {node: '>=10'} @@ -5379,6 +6485,10 @@ packages: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} + strip-indent@4.1.1: + resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} + engines: {node: '>=12'} + strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -5390,6 +6500,15 @@ packages: strnum@2.1.2: resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + stylis@4.3.6: + resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} + sucrase@3.35.1: resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} engines: {node: '>=16 || 14 >=14.17'} @@ -5471,6 +6590,9 @@ packages: tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -5482,10 +6604,18 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + tinyrainbow@3.0.3: resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} engines: {node: '>=14.0.0'} + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + engines: {node: '>=14.0.0'} + tldts-core@7.0.19: resolution: {integrity: sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==} @@ -5530,6 +6660,10 @@ packages: peerDependencies: typescript: '>=4.8.4' + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -5543,6 +6677,10 @@ packages: typescript: optional: true + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -5577,6 +6715,19 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} + typedoc-plugin-markdown@4.10.0: + resolution: {integrity: sha512-psrg8Rtnv4HPWCsoxId+MzEN8TVK5jeKCnTbnGAbTBqcDapR9hM41bJT/9eAyKn9C2MDG9Qjh3MkltAYuLDoXg==} + engines: {node: '>= 18'} + peerDependencies: + typedoc: 0.28.x + + typedoc@0.28.17: + resolution: {integrity: sha512-ZkJ2G7mZrbxrKxinTQMjFqsCoYY6a5Luwv2GKbTnBCEgV2ihYm5CflA9JnJAwH0pZWavqfYxmDkFHPt4yx2oDQ==} + engines: {node: '>= 18', pnpm: '>= 10'} + hasBin: true + peerDependencies: + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x + typescript@5.8.2: resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} engines: {node: '>=14.17'} @@ -5587,6 +6738,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} @@ -5648,6 +6802,9 @@ packages: unist-util-modify-children@4.0.0: resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + unist-util-position@5.0.0: resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} @@ -5670,6 +6827,14 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} + engines: {node: '>=14.0.0'} + + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + unstorage@1.17.4: resolution: {integrity: sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==} peerDependencies: @@ -5748,13 +6913,26 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - uuid@8.3.2: + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + vfile-location@5.0.3: resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} @@ -5785,6 +6963,13 @@ packages: '@vite-pwa/assets-generator': optional: true + vite-plugin-singlefile@2.3.2: + resolution: {integrity: sha512-b8SxCi/gG7K298oJDcKOuZeU6gf6wIcCJAaEqUmmZXdjfuONlkyNyWZC3tEbN6QockRCNUd3it9eGTtpHGoYmg==} + engines: {node: '>18.0.0'} + peerDependencies: + rollup: 4.59.0 + vite: ^5.4.11 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vite@6.4.1: resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -5825,6 +7010,46 @@ packages: yaml: optional: true + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vitefu@1.1.1: resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} peerDependencies: @@ -5867,6 +7092,23 @@ packages: jsdom: optional: true + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} @@ -5884,6 +7126,9 @@ packages: resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} engines: {node: '>=20'} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-mimetype@5.0.0: resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} engines: {node: '>=20'} @@ -5997,6 +7242,18 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + wsl-utils@0.1.0: resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} engines: {node: '>=18'} @@ -6038,6 +7295,10 @@ packages: resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + yargs@18.0.0: resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} @@ -6096,6 +7357,11 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.6.0 + tinyexec: 1.0.2 + '@antfu/utils@0.7.10': optional: true @@ -6128,6 +7394,8 @@ snapshots: '@astrojs/internal-helpers@0.7.5': {} + '@astrojs/internal-helpers@0.7.6': {} + '@astrojs/markdown-remark@6.3.10': dependencies: '@astrojs/internal-helpers': 0.7.5 @@ -6154,6 +7422,51 @@ snapshots: transitivePeerDependencies: - supports-color + '@astrojs/markdown-remark@6.3.11': + dependencies: + '@astrojs/internal-helpers': 0.7.6 + '@astrojs/prism': 3.3.0 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-to-text: 4.0.2 + import-meta-resolve: 4.2.0 + js-yaml: 4.1.1 + mdast-util-definitions: 6.0.0 + rehype-raw: 7.0.0 + rehype-stringify: 10.0.1 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remark-smartypants: 3.0.2 + shiki: 3.21.0 + smol-toml: 1.6.0 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.0.0 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/mdx@4.3.14(astro@5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2))': + dependencies: + '@astrojs/markdown-remark': 6.3.11 + '@mdx-js/mdx': 3.1.1 + acorn: 8.15.0 + astro: 5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2) + es-module-lexer: 1.7.0 + estree-util-visit: 2.0.0 + hast-util-to-html: 9.0.5 + piccolore: 0.1.3 + rehype-raw: 7.0.0 + remark-gfm: 4.0.1 + remark-smartypants: 3.0.2 + source-map: 0.7.6 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + '@astrojs/prism@3.3.0': dependencies: prismjs: 1.30.0 @@ -6187,6 +7500,39 @@ snapshots: stream-replace-string: 2.0.0 zod: 3.25.76 + '@astrojs/starlight@0.34.8(astro@5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2))': + dependencies: + '@astrojs/markdown-remark': 6.3.10 + '@astrojs/mdx': 4.3.14(astro@5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2)) + '@astrojs/sitemap': 3.7.0 + '@pagefind/default-ui': 1.4.0 + '@types/hast': 3.0.4 + '@types/js-yaml': 4.0.9 + '@types/mdast': 4.0.4 + astro: 5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2) + astro-expressive-code: 0.41.7(astro@5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2)) + bcp-47: 2.1.0 + hast-util-from-html: 2.0.3 + hast-util-select: 6.0.4 + hast-util-to-string: 3.0.1 + hastscript: 9.0.1 + i18next: 23.16.8 + js-yaml: 4.1.1 + klona: 2.0.6 + mdast-util-directive: 3.1.0 + mdast-util-to-markdown: 2.1.2 + mdast-util-to-string: 4.0.0 + pagefind: 1.4.0 + rehype: 13.0.2 + rehype-format: 5.0.1 + remark-directive: 3.0.1 + ultrahtml: 1.6.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + '@astrojs/telemetry@3.3.0': dependencies: ci-info: 4.3.1 @@ -6364,8 +7710,16 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/compat-data@7.28.5': {} + '@babel/compat-data@7.29.0': {} + '@babel/core@7.28.5': dependencies: '@babel/code-frame': 7.27.1 @@ -6386,6 +7740,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/generator@7.28.5': dependencies: '@babel/parser': 7.28.5 @@ -6394,9 +7768,17 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helper-compilation-targets@7.27.2': dependencies: @@ -6406,30 +7788,38 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.5)': + '@babel/helper-compilation-targets@7.28.6': dependencies: - '@babel/core': 7.28.5 + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.29.0) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.28.5)': + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.5)': + '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.27.1 debug: 4.4.3 lodash.debounce: 4.0.8 @@ -6441,8 +7831,8 @@ snapshots: '@babel/helper-member-expression-to-functions@7.28.5': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -6453,6 +7843,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 @@ -6462,34 +7859,43 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.5)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-wrap-function': 7.28.3 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -6501,9 +7907,9 @@ snapshots: '@babel/helper-wrap-function@7.28.3': dependencies: - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -6512,329 +7918,338 @@ snapshots: '@babel/template': 7.27.2 '@babel/types': 7.28.5 + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + '@babel/parser@7.28.5': dependencies: '@babel/types': 7.28.5 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.28.5)': + '@babel/parser@7.29.2': dependencies: - '@babel/core': 7.28.5 + '@babel/types': 7.29.0 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.5)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 - '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.5)': + '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) - '@babel/traverse': 7.28.5 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-block-scoping@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-block-scoping@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.5)': + '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.5)': + '@babel/plugin-transform-classes@7.28.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-globals': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) - '@babel/traverse': 7.28.5 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/template': 7.27.2 + '@babel/template': 7.28.6 - '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.5)': + '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-exponentiation-operator@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-exponentiation-operator@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-logical-assignment-operators@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-logical-assignment-operators@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.5)': + '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) - '@babel/traverse': 7.28.5 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-optional-chaining@7.28.5(@babel/core@7.28.5)': + '@babel/plugin-transform-optional-chaining@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.5)': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': @@ -6842,159 +8257,169 @@ snapshots: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': dependencies: '@babel/core': 7.28.5 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.5)': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.27.1 - '@babel/preset-env@7.28.5(@babel/core@7.28.5)': + '@babel/preset-env@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/compat-data': 7.28.5 - '@babel/core': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.5) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5) - '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.5) - '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.5) - '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-block-scoping': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.5) - '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.5) - '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.5) - '@babel/plugin-transform-exponentiation-operator': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-logical-assignment-operators': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.5) - '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) - '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.5) - '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.5) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.5) - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) - babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-exponentiation-operator': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.29.0) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.29.0) + '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.29.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.29.0) core-js-compat: 3.47.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.5)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 esutils: 2.0.3 '@babel/runtime@7.28.4': {} @@ -7005,6 +8430,12 @@ snapshots: '@babel/parser': 7.28.5 '@babel/types': 7.28.5 + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@babel/traverse@7.28.5': dependencies: '@babel/code-frame': 7.27.1 @@ -7017,13 +8448,32 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + '@babel/types@7.28.5': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@bcoe/v8-coverage@1.0.2': {} + '@braintree/sanitize-url@7.1.2': {} + '@bramus/specificity@2.4.2': dependencies: css-tree: 3.1.0 @@ -7035,6 +8485,23 @@ snapshots: dependencies: fontkitten: 1.0.2 + '@chevrotain/cst-dts-gen@11.1.2': + dependencies: + '@chevrotain/gast': 11.1.2 + '@chevrotain/types': 11.1.2 + lodash-es: 4.17.23 + + '@chevrotain/gast@11.1.2': + dependencies: + '@chevrotain/types': 11.1.2 + lodash-es: 4.17.23 + + '@chevrotain/regexp-to-ast@11.1.2': {} + + '@chevrotain/types@11.1.2': {} + + '@chevrotain/utils@11.1.2': {} + '@csstools/color-helpers@6.0.2': {} '@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': @@ -7057,6 +8524,8 @@ snapshots: '@csstools/css-tokenizer@4.0.0': {} + '@ctrl/tinycolor@4.2.0': {} + '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 @@ -7271,6 +8740,31 @@ snapshots: '@exodus/bytes@1.14.1': {} + '@expressive-code/core@0.41.7': + dependencies: + '@ctrl/tinycolor': 4.2.0 + hast-util-select: 6.0.4 + hast-util-to-html: 9.0.5 + hast-util-to-text: 4.0.2 + hastscript: 9.0.1 + postcss: 8.5.6 + postcss-nested: 6.2.0(postcss@8.5.6) + unist-util-visit: 5.0.0 + unist-util-visit-parents: 6.0.2 + + '@expressive-code/plugin-frames@0.41.7': + dependencies: + '@expressive-code/core': 0.41.7 + + '@expressive-code/plugin-shiki@0.41.7': + dependencies: + '@expressive-code/core': 0.41.7 + shiki: 3.21.0 + + '@expressive-code/plugin-text-markers@0.41.7': + dependencies: + '@expressive-code/core': 0.41.7 + '@fast-csv/format@4.3.5': dependencies: '@types/node': 14.18.63 @@ -7290,6 +8784,18 @@ snapshots: lodash.isundefined: 3.0.1 lodash.uniq: 4.5.0 + '@fortawesome/fontawesome-free@6.7.2': {} + + '@gerrit0/mini-shiki@3.23.0': + dependencies: + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@hpcc-js/wasm-graphviz@1.21.0': {} + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -7301,28 +8807,58 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.1.0': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/types': 2.0.0 + mlly: 1.8.0 + '@img/colour@1.0.0': optional: true + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + '@img/sharp-darwin-arm64@0.34.5': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.2.4 optional: true + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + '@img/sharp-darwin-x64@0.34.5': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.2.4 optional: true + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + '@img/sharp-libvips-darwin-arm64@1.2.4': optional: true + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + '@img/sharp-libvips-darwin-x64@1.2.4': optional: true + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + '@img/sharp-libvips-linux-arm64@1.2.4': optional: true + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + '@img/sharp-libvips-linux-arm@1.2.4': optional: true @@ -7332,23 +8868,45 @@ snapshots: '@img/sharp-libvips-linux-riscv64@1.2.4': optional: true + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + '@img/sharp-libvips-linux-s390x@1.2.4': optional: true + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + '@img/sharp-libvips-linux-x64@1.2.4': optional: true + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': optional: true + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + '@img/sharp-libvips-linuxmusl-x64@1.2.4': optional: true + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + '@img/sharp-linux-arm64@0.34.5': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.2.4 optional: true + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + '@img/sharp-linux-arm@0.34.5': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.2.4 @@ -7364,26 +8922,51 @@ snapshots: '@img/sharp-libvips-linux-riscv64': 1.2.4 optional: true + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + '@img/sharp-linux-s390x@0.34.5': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.2.4 optional: true + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + '@img/sharp-linux-x64@0.34.5': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.2.4 optional: true + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + '@img/sharp-linuxmusl-arm64@0.34.5': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 optional: true + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + '@img/sharp-linuxmusl-x64@0.34.5': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.2.4 optional: true + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.8.1 + optional: true + '@img/sharp-wasm32@0.34.5': dependencies: '@emnapi/runtime': 1.8.1 @@ -7392,9 +8975,15 @@ snapshots: '@img/sharp-win32-arm64@0.34.5': optional: true + '@img/sharp-win32-ia32@0.33.5': + optional: true + '@img/sharp-win32-ia32@0.34.5': optional: true + '@img/sharp-win32-x64@0.33.5': + optional: true + '@img/sharp-win32-x64@0.34.5': optional: true @@ -7407,6 +8996,14 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': + dependencies: + glob: 13.0.6 + react-docgen-typescript: 2.4.0(typescript@5.9.3) + vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + optionalDependencies: + typescript: 5.9.3 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -7431,6 +9028,57 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@likec4/core@1.52.0': + dependencies: + immer: 11.1.4 + type-fest: 4.41.0 + zod: 3.25.76 + + '@likec4/icons@1.46.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.15.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.15.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.2.7 + react: 19.2.3 + + '@mermaid-js/parser@1.0.1': + dependencies: + langium: 4.2.1 + '@microsoft/api-extractor-model@7.33.3(@types/node@20.19.27)': dependencies: '@microsoft/tsdoc': 0.16.0 @@ -7488,16 +9136,38 @@ snapshots: '@oslojs/encoding@1.1.0': {} + '@pagefind/darwin-arm64@1.4.0': + optional: true + + '@pagefind/darwin-x64@1.4.0': + optional: true + + '@pagefind/default-ui@1.4.0': {} + + '@pagefind/freebsd-x64@1.4.0': + optional: true + + '@pagefind/linux-arm64@1.4.0': + optional: true + + '@pagefind/linux-x64@1.4.0': + optional: true + + '@pagefind/windows-x64@1.4.0': + optional: true + '@playwright/test@1.57.0': dependencies: playwright: 1.57.0 '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rollup/plugin-babel@5.3.1(@babel/core@7.28.5)(@types/babel__core@7.20.5)(rollup@2.80.0)': + '@rolldown/pluginutils@1.0.0-rc.3': {} + + '@rollup/plugin-babel@5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@2.80.0)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 '@rollup/pluginutils': 3.1.0(rollup@2.80.0) rollup: 2.80.0 optionalDependencies: @@ -7627,79 +9297,279 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true - '@rushstack/node-core-library@5.20.3(@types/node@20.19.27)': + '@rushstack/node-core-library@5.20.3(@types/node@20.19.27)': + dependencies: + ajv: 8.18.0 + ajv-draft-04: 1.0.0(ajv@8.18.0) + ajv-formats: 3.0.1(ajv@8.18.0) + fs-extra: 11.3.3 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.22.11 + semver: 7.5.4 + optionalDependencies: + '@types/node': 20.19.27 + + '@rushstack/problem-matcher@0.2.1(@types/node@20.19.27)': + optionalDependencies: + '@types/node': 20.19.27 + + '@rushstack/rig-package@0.7.2': + dependencies: + resolve: 1.22.11 + strip-json-comments: 3.1.1 + + '@rushstack/terminal@0.22.3(@types/node@20.19.27)': + dependencies: + '@rushstack/node-core-library': 5.20.3(@types/node@20.19.27) + '@rushstack/problem-matcher': 0.2.1(@types/node@20.19.27) + supports-color: 8.1.1 + optionalDependencies: + '@types/node': 20.19.27 + + '@rushstack/ts-command-line@5.3.3(@types/node@20.19.27)': + dependencies: + '@rushstack/terminal': 0.22.3(@types/node@20.19.27) + '@types/argparse': 1.0.38 + argparse: 1.0.10 + string-argv: 0.3.2 + transitivePeerDependencies: + - '@types/node' + + '@shikijs/core@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.4 + + '@shikijs/engine-oniguruma@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/engine-oniguruma@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + + '@shikijs/langs@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/themes@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + + '@shikijs/themes@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/types@3.21.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/types@3.23.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@standard-schema/spec@1.1.0': {} + + '@storybook/addon-a11y@10.2.19(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + '@storybook/global': 5.0.0 + axe-core: 4.11.1 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + + '@storybook/addon-actions@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + '@storybook/global': 5.0.0 + '@types/uuid': 9.0.8 + dequal: 2.0.3 + polished: 4.3.1 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + uuid: 9.0.1 + + '@storybook/addon-backgrounds@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + ts-dedent: 2.2.0 + + '@storybook/addon-controls@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + '@storybook/global': 5.0.0 + dequal: 2.0.3 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + ts-dedent: 2.2.0 + + '@storybook/addon-docs@8.6.14(@types/react@19.2.7)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + '@mdx-js/react': 3.1.1(@types/react@19.2.7)(react@19.2.3) + '@storybook/blocks': 8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/csf-plugin': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/react-dom-shim': 8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + + '@storybook/addon-essentials@8.6.14(@types/react@19.2.7)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + '@storybook/addon-actions': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/addon-backgrounds': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/addon-controls': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/addon-docs': 8.6.14(@types/react@19.2.7)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/addon-highlight': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/addon-measure': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/addon-outline': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/addon-toolbars': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + '@storybook/addon-viewport': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + + '@storybook/addon-highlight@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + '@storybook/global': 5.0.0 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + + '@storybook/addon-measure@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + '@storybook/global': 5.0.0 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + tiny-invariant: 1.3.3 + + '@storybook/addon-outline@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + '@storybook/global': 5.0.0 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + ts-dedent: 2.2.0 + + '@storybook/addon-themes@10.2.19(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: - ajv: 8.18.0 - ajv-draft-04: 1.0.0(ajv@8.18.0) - ajv-formats: 3.0.1(ajv@8.18.0) - fs-extra: 11.3.3 - import-lazy: 4.0.0 - jju: 1.4.0 - resolve: 1.22.11 - semver: 7.5.4 - optionalDependencies: - '@types/node': 20.19.27 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + ts-dedent: 2.2.0 - '@rushstack/problem-matcher@0.2.1(@types/node@20.19.27)': - optionalDependencies: - '@types/node': 20.19.27 + '@storybook/addon-toolbars@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': + dependencies: + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@rushstack/rig-package@0.7.2': + '@storybook/addon-viewport@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: - resolve: 1.22.11 - strip-json-comments: 3.1.1 + memoizerific: 1.11.3 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@rushstack/terminal@0.22.3(@types/node@20.19.27)': + '@storybook/blocks@8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: - '@rushstack/node-core-library': 5.20.3(@types/node@20.19.27) - '@rushstack/problem-matcher': 0.2.1(@types/node@20.19.27) - supports-color: 8.1.1 + '@storybook/icons': 1.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + ts-dedent: 2.2.0 optionalDependencies: - '@types/node': 20.19.27 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) - '@rushstack/ts-command-line@5.3.3(@types/node@20.19.27)': + '@storybook/builder-vite@10.2.19(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: - '@rushstack/terminal': 0.22.3(@types/node@20.19.27) - '@types/argparse': 1.0.38 - argparse: 1.0.10 - string-argv: 0.3.2 + '@storybook/csf-plugin': 10.2.19(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + ts-dedent: 2.2.0 + vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) transitivePeerDependencies: - - '@types/node' + - esbuild + - rollup + - webpack - '@shikijs/core@3.21.0': + '@storybook/csf-plugin@10.2.19(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: - '@shikijs/types': 3.21.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - hast-util-to-html: 9.0.5 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + unplugin: 2.3.11 + optionalDependencies: + esbuild: 0.27.3 + rollup: 4.59.0 + vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) - '@shikijs/engine-javascript@3.21.0': + '@storybook/csf-plugin@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: - '@shikijs/types': 3.21.0 - '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 4.3.4 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + unplugin: 1.16.1 - '@shikijs/engine-oniguruma@3.21.0': + '@storybook/global@5.0.0': {} + + '@storybook/icons@1.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@shikijs/types': 3.21.0 - '@shikijs/vscode-textmate': 10.0.2 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) - '@shikijs/langs@3.21.0': + '@storybook/icons@2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: - '@shikijs/types': 3.21.0 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) - '@shikijs/themes@3.21.0': + '@storybook/react-dom-shim@10.2.19(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: - '@shikijs/types': 3.21.0 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@shikijs/types@3.21.0': + '@storybook/react-dom-shim@8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@shikijs/vscode-textmate@10.0.2': {} + '@storybook/react-vite@10.2.19(esbuild@0.27.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.59.0)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': + dependencies: + '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + '@rollup/pluginutils': 5.3.0(rollup@4.59.0) + '@storybook/builder-vite': 10.2.19(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + '@storybook/react': 10.2.19(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3) + empathic: 2.0.0 + magic-string: 0.30.21 + react: 19.2.3 + react-docgen: 8.0.3 + react-dom: 19.2.3(react@19.2.3) + resolve: 1.22.11 + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + tsconfig-paths: 4.2.0 + vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + transitivePeerDependencies: + - esbuild + - rollup + - supports-color + - typescript + - webpack - '@standard-schema/spec@1.1.0': {} + '@storybook/react@10.2.19(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/react-dom-shim': 10.2.19(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) + react: 19.2.3 + react-docgen: 8.0.3 + react-dom: 19.2.3(react@19.2.3) + storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color '@surma/rollup-plugin-off-main-thread@2.2.3': dependencies: @@ -7816,6 +9686,10 @@ snapshots: '@types/react': 18.3.27 '@types/react-dom': 19.2.3(@types/react@18.3.27) + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': + dependencies: + '@testing-library/dom': 10.4.1 + '@types/argparse@1.0.38': {} '@types/aria-query@5.0.4': {} @@ -7995,6 +9869,12 @@ snapshots: '@types/deep-eql@4.0.2': {} + '@types/doctrine@0.0.9': {} + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + '@types/estree@0.0.39': {} '@types/estree@1.0.8': {} @@ -8005,6 +9885,8 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/js-yaml@4.0.9': {} + '@types/json-schema@7.0.15': {} '@types/lodash@4.17.21': {} @@ -8013,6 +9895,8 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/mdx@2.0.13': {} + '@types/ms@2.1.0': {} '@types/nlcst@2.0.3': @@ -8071,8 +9955,12 @@ snapshots: '@types/trusted-types@2.0.7': {} + '@types/unist@2.0.11': {} + '@types/unist@3.0.3': {} + '@types/uuid@9.0.8': {} + '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -8175,6 +10063,11 @@ snapshots: '@ungap/structured-clone@1.3.0': {} + '@upsetjs/venn.js@2.0.0': + optionalDependencies: + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + '@visx/axis@3.12.0(react@19.2.3)': dependencies: '@types/react': 18.3.27 @@ -8329,7 +10222,7 @@ snapshots: - react-native-b4a optional: true - '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) @@ -8337,11 +10230,11 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + vite: 6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) @@ -8349,19 +10242,19 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': + '@vitejs/plugin-react@5.2.0(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) - '@rolldown/pluginutils': 1.0.0-beta.27 + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.3 '@types/babel__core': 7.20.5 - react-refresh: 0.17.0 - vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + react-refresh: 0.18.0 + vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -8379,6 +10272,14 @@ snapshots: tinyrainbow: 3.0.3 vitest: 4.0.18(@types/node@25.0.3)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.3 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + tinyrainbow: 2.0.0 + '@vitest/expect@4.0.18': dependencies: '@standard-schema/spec': 1.1.0 @@ -8388,21 +10289,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.18(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': - dependencies: - '@vitest/spy': 4.0.18 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) - - '@vitest/mocker@4.0.18(vite@6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + vite: 6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) '@vitest/mocker@4.0.18(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: @@ -8412,6 +10305,10 @@ snapshots: optionalDependencies: vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + '@vitest/pretty-format@4.0.18': dependencies: tinyrainbow: 3.0.3 @@ -8427,8 +10324,18 @@ snapshots: magic-string: 0.30.21 pathe: 2.0.3 + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.4 + '@vitest/spy@4.0.18': {} + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + '@vitest/utils@4.0.18': dependencies: '@vitest/pretty-format': 4.0.18 @@ -8649,12 +10556,23 @@ snapshots: assertion-error@2.0.1: {} + ast-types@0.16.1: + dependencies: + tslib: 2.8.1 + ast-v8-to-istanbul@0.3.11: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 js-tokens: 10.0.0 + astring@1.9.0: {} + + astro-expressive-code@0.41.7(astro@5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2)): + dependencies: + astro: 5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2) + rehype-expressive-code: 0.41.7 + astro@5.18.0(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1)(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.59.0)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.2): dependencies: '@astrojs/compiler': 2.13.0 @@ -8776,32 +10694,34 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 + axe-core@4.11.1: {} + axobject-query@4.1.0: {} b4a@1.7.3: optional: true - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5): + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.29.0): dependencies: - '@babel/compat-data': 7.28.5 - '@babel/core': 7.28.5 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.29.0) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.5): + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): dependencies: - '@babel/core': 7.28.5 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.29.0) core-js-compat: 3.47.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.5): + babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.29.0): dependencies: - '@babel/core': 7.28.5 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.29.0) transitivePeerDependencies: - supports-color @@ -8857,6 +10777,14 @@ snapshots: baseline-browser-mapping@2.9.11: {} + bcp-47-match@2.0.3: {} + + bcp-47@2.1.0: + dependencies: + is-alphabetical: 2.0.1 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + bidi-js@1.0.3: dependencies: require-from-string: 2.0.2 @@ -8936,6 +10864,11 @@ snapshots: dependencies: run-applescript: 7.1.0 + bundle-require@5.1.0(esbuild@0.27.3): + dependencies: + esbuild: 0.27.3 + load-tsconfig: 0.2.5 + cac@6.7.14: optional: true @@ -8966,6 +10899,14 @@ snapshots: ccount@2.0.1: {} + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.3 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + chai@6.2.2: {} chainsaw@0.1.0: @@ -8985,6 +10926,24 @@ snapshots: character-entities@2.0.2: {} + character-reference-invalid@2.0.1: {} + + check-error@2.1.3: {} + + chevrotain-allstar@0.3.1(chevrotain@11.1.2): + dependencies: + chevrotain: 11.1.2 + lodash-es: 4.17.23 + + chevrotain@11.1.2: + dependencies: + '@chevrotain/cst-dts-gen': 11.1.2 + '@chevrotain/gast': 11.1.2 + '@chevrotain/regexp-to-ast': 11.1.2 + '@chevrotain/types': 11.1.2 + '@chevrotain/utils': 11.1.2 + lodash-es: 4.17.23 + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -9019,6 +10978,12 @@ snapshots: slice-ansi: 7.1.2 string-width: 8.1.0 + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + cliui@9.0.1: dependencies: string-width: 7.2.0 @@ -9027,6 +10992,8 @@ snapshots: clsx@2.1.1: {} + collapse-white-space@2.1.0: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -9037,13 +11004,11 @@ snapshots: dependencies: color-name: 1.1.4 simple-swizzle: 0.2.4 - optional: true color@4.2.3: dependencies: color-convert: 2.0.1 color-string: 1.9.1 - optional: true colorette@2.0.20: {} @@ -9057,6 +11022,10 @@ snapshots: commander@4.1.1: {} + commander@7.2.0: {} + + commander@8.3.0: {} + common-ancestor-path@1.0.1: {} common-tags@1.8.2: {} @@ -9091,6 +11060,14 @@ snapshots: core-util-is@1.0.3: {} + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + crc-32@1.2.2: {} crc32-stream@4.0.3: @@ -9118,6 +11095,8 @@ snapshots: domutils: 3.2.2 nth-check: 2.1.1 + css-selector-parser@3.3.0: {} + css-tree@2.2.1: dependencies: mdn-data: 2.0.28 @@ -9147,6 +11126,22 @@ snapshots: csstype@3.2.3: {} + cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.33.1 + + cytoscape-fcose@2.2.0(cytoscape@3.33.1): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.33.1 + + cytoscape@3.33.1: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + d3-array@3.2.1: dependencies: internmap: 2.0.3 @@ -9155,24 +11150,87 @@ snapshots: dependencies: internmap: 2.0.3 + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + d3-color@3.1.0: {} + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-delaunay@6.0.2: dependencies: delaunator: 5.0.1 + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + d3-format@3.1.0: {} d3-geo@3.1.0: dependencies: d3-array: 3.2.4 + d3-hierarchy@3.1.2: {} + d3-interpolate@3.0.1: dependencies: d3-color: 3.1.0 d3-path@1.0.9: {} + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + d3-scale@4.0.2: dependencies: d3-array: 3.2.4 @@ -9181,10 +11239,16 @@ snapshots: d3-time: 3.1.0 d3-time-format: 4.1.0 + d3-selection@3.0.0: {} + d3-shape@1.3.7: dependencies: d3-path: 1.0.9 + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + d3-time-format@4.1.0: dependencies: d3-time: 3.1.0 @@ -9193,6 +11257,63 @@ snapshots: dependencies: d3-array: 3.2.4 + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.2 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.0 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.14: + dependencies: + d3: 7.9.0 + lodash-es: 4.17.23 + data-urls@7.0.0: dependencies: whatwg-mimetype: 5.0.0 @@ -9250,6 +11371,8 @@ snapshots: mimic-response: 3.1.0 optional: true + deep-eql@5.0.2: {} + deep-extend@0.6.0: optional: true @@ -9306,12 +11429,18 @@ snapshots: diff@8.0.3: {} + direction@2.0.1: {} + dlv@1.1.3: {} doctrine@2.1.0: dependencies: esutils: 2.0.3 + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} @@ -9328,6 +11457,10 @@ snapshots: dependencies: domelementtype: 2.3.0 + dompurify@3.3.3: + optionalDependencies: + '@types/trusted-types': 2.0.7 + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 @@ -9365,6 +11498,8 @@ snapshots: emoji-regex@9.2.2: {} + empathic@2.0.0: {} + end-of-stream@1.4.5: dependencies: once: 1.4.0 @@ -9485,6 +11620,20 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.15.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + esbuild@0.25.12: optionalDependencies: '@esbuild/aix-ppc64': 0.25.12 @@ -9644,6 +11793,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 4.2.1 + esprima@4.0.1: {} + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -9652,7 +11803,36 @@ snapshots: dependencies: estraverse: 5.3.0 - estraverse@5.3.0: {} + estraverse@5.3.0: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 estree-walker@1.0.1: {} @@ -9693,6 +11873,13 @@ snapshots: expect-type@1.3.0: {} + expressive-code@0.41.7: + dependencies: + '@expressive-code/core': 0.41.7 + '@expressive-code/plugin-frames': 0.41.7 + '@expressive-code/plugin-shiki': 0.41.7 + '@expressive-code/plugin-text-markers': 0.41.7 + exsolve@1.0.8: {} extend@3.0.2: {} @@ -9734,6 +11921,10 @@ snapshots: dependencies: reusify: 1.1.0 + fdir@6.4.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -9878,9 +12069,15 @@ snapshots: foreground-child: 3.3.1 jackspeak: 4.1.1 minimatch: 10.2.4 - minipass: 7.1.2 + minipass: 7.1.3 package-json-from-dist: 1.0.1 - path-scurry: 2.0.1 + path-scurry: 2.0.2 + + glob@13.0.6: + dependencies: + minimatch: 10.2.4 + minipass: 7.1.3 + path-scurry: 2.0.2 glob@7.2.3: dependencies: @@ -9914,6 +12111,8 @@ snapshots: ufo: 1.6.3 uncrypto: 0.1.3 + hachure-fill@0.5.2: {} + has-bigints@1.1.0: {} has-flag@4.0.0: {} @@ -9936,6 +12135,34 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-embedded@3.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-is-element: 3.0.0 + + hast-util-format@1.1.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-minify-whitespace: 1.0.1 + hast-util-phrasing: 3.0.1 + hast-util-whitespace: 3.0.0 + html-whitespace-sensitive-tag-names: 3.0.1 + unist-util-visit-parents: 6.0.2 + + hast-util-from-dom@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hastscript: 9.0.1 + web-namespaces: 2.0.1 + + hast-util-from-html-isomorphic@2.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-dom: 5.0.1 + hast-util-from-html: 2.0.3 + unist-util-remove-position: 5.0.0 + hast-util-from-html@2.0.3: dependencies: '@types/hast': 3.0.4 @@ -9956,14 +12183,38 @@ snapshots: vfile-location: 5.0.3 web-namespaces: 2.0.1 + hast-util-has-property@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-body-ok-link@3.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-is-element@3.0.0: dependencies: '@types/hast': 3.0.4 + hast-util-minify-whitespace@1.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-is-element: 3.0.0 + hast-util-whitespace: 3.0.0 + unist-util-is: 6.0.1 + hast-util-parse-selector@4.0.0: dependencies: '@types/hast': 3.0.4 + hast-util-phrasing@3.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-has-property: 3.0.0 + hast-util-is-body-ok-link: 3.0.1 + hast-util-is-element: 3.0.0 + hast-util-raw@9.1.0: dependencies: '@types/hast': 3.0.4 @@ -9980,6 +12231,45 @@ snapshots: web-namespaces: 2.0.1 zwitch: 2.0.4 + hast-util-select@6.0.4: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + bcp-47-match: 2.0.3 + comma-separated-tokens: 2.0.3 + css-selector-parser: 3.3.0 + devlop: 1.1.0 + direction: 2.0.1 + hast-util-has-property: 3.0.0 + hast-util-to-string: 3.0.1 + hast-util-whitespace: 3.0.0 + nth-check: 2.1.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + hast-util-to-html@9.0.5: dependencies: '@types/hast': 3.0.4 @@ -9994,6 +12284,26 @@ snapshots: stringify-entities: 4.0.4 zwitch: 2.0.4 + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + hast-util-to-parse5@8.0.1: dependencies: '@types/hast': 3.0.4 @@ -10004,6 +12314,10 @@ snapshots: web-namespaces: 2.0.1 zwitch: 2.0.4 + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-text@4.0.2: dependencies: '@types/hast': 3.0.4 @@ -10045,6 +12359,8 @@ snapshots: html-void-elements@3.0.0: {} + html-whitespace-sensitive-tag-names@3.0.1: {} + http-cache-semantics@4.2.0: {} http-proxy-agent@7.0.2: @@ -10063,9 +12379,17 @@ snapshots: husky@9.1.7: {} + i18next@23.16.8: + dependencies: + '@babel/runtime': 7.28.4 + ico-endec@0.1.6: optional: true + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + idb@7.1.1: {} ieee754@1.2.1: {} @@ -10076,6 +12400,8 @@ snapshots: immediate@3.0.6: {} + immer@11.1.4: {} + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -10099,24 +12425,34 @@ snapshots: ini@1.3.8: optional: true + inline-style-parser@0.2.7: {} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 hasown: 2.0.2 side-channel: 1.1.0 + internmap@1.0.1: {} + internmap@2.0.3: {} iron-webcrypto@1.2.1: {} + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 get-intrinsic: 1.3.0 - is-arrayish@0.3.4: - optional: true + is-arrayish@0.3.4: {} is-async-function@2.1.1: dependencies: @@ -10156,6 +12492,8 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-decimal@2.0.1: {} + is-docker@3.0.0: {} is-extglob@2.1.1: {} @@ -10182,6 +12520,8 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-hexadecimal@2.0.1: {} + is-in-ssh@1.0.0: {} is-inside-container@1.0.0: @@ -10396,14 +12736,34 @@ snapshots: safe-buffer: 5.2.1 optional: true + katex@0.16.38: + dependencies: + commander: 8.3.0 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 + khroma@2.1.0: {} + kleur@3.0.3: {} + klona@2.0.6: {} + kolorist@1.8.0: {} + langium@4.2.1: + dependencies: + chevrotain: 11.1.2 + chevrotain-allstar: 0.3.1(chevrotain@11.1.2) + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + lazystream@1.0.1: dependencies: readable-stream: 2.3.8 @@ -10468,10 +12828,49 @@ snapshots: lightningcss-win32-arm64-msvc: 1.31.1 lightningcss-win32-x64-msvc: 1.31.1 + likec4@1.52.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(picomatch@4.0.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.59.0)(terser@5.44.1)(yaml@2.8.2): + dependencies: + '@hpcc-js/wasm-graphviz': 1.21.0 + '@likec4/core': 1.52.0 + '@likec4/icons': 1.46.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@vitejs/plugin-react': 5.2.0(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + bundle-require: 5.1.0(esbuild@0.27.3) + chokidar: 5.0.0 + esbuild: 0.27.3 + fdir: 6.4.0(picomatch@4.0.3) + nano-spawn: 2.0.0 + playwright: 1.58.2 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + std-env: 3.10.0 + type-fest: 4.41.0 + vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + vite-plugin-singlefile: 2.3.2(rollup@4.59.0)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - picomatch + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + lint-staged@16.2.7: dependencies: commander: 14.0.2 @@ -10493,6 +12892,8 @@ snapshots: rfdc: 1.4.1 wrap-ansi: 9.0.2 + load-tsconfig@0.2.5: {} + local-pkg@1.1.2: dependencies: mlly: 1.8.0 @@ -10503,6 +12904,8 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash-es@4.17.23: {} + lodash.debounce@4.0.8: {} lodash.defaults@4.2.0: {} @@ -10566,6 +12969,8 @@ snapshots: dependencies: js-tokens: 4.0.0 + loupe@3.2.1: {} + lru-cache@11.2.4: {} lru-cache@11.2.6: {} @@ -10586,6 +12991,8 @@ snapshots: dependencies: react: 18.3.1 + lunr@2.3.9: {} + lz-string@1.5.0: {} magic-string@0.25.9: @@ -10606,8 +13013,23 @@ snapshots: dependencies: semver: 7.7.3 + map-or-similar@1.5.0: {} + + markdown-extensions@2.0.0: {} + + markdown-it@14.1.1: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + markdown-table@3.0.4: {} + marked@16.4.2: {} + math-expression-evaluator@1.4.0: {} math-intrinsics@1.1.0: {} @@ -10618,6 +13040,20 @@ snapshots: '@types/unist': 3.0.3 unist-util-visit: 5.0.0 + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color + mdast-util-find-and-replace@3.0.2: dependencies: '@types/mdast': 4.0.4 @@ -10699,6 +13135,55 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + mdast-util-phrasing@4.1.0: dependencies: '@types/mdast': 4.0.4 @@ -10736,8 +13221,46 @@ snapshots: mdn-data@2.12.2: {} + mdurl@2.0.0: {} + + memoizerific@1.11.3: + dependencies: + map-or-similar: 1.5.0 + merge2@1.4.1: {} + mermaid-isomorphic@3.1.0(playwright@1.58.2): + dependencies: + '@fortawesome/fontawesome-free': 6.7.2 + katex: 0.16.38 + mermaid: 11.13.0 + optionalDependencies: + playwright: 1.58.2 + + mermaid@11.13.0: + dependencies: + '@braintree/sanitize-url': 7.1.2 + '@iconify/utils': 3.1.0 + '@mermaid-js/parser': 1.0.1 + '@types/d3': 7.4.3 + '@upsetjs/venn.js': 2.0.0 + cytoscape: 3.33.1 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) + cytoscape-fcose: 2.2.0(cytoscape@3.33.1) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.14 + dayjs: 1.11.19 + dompurify: 3.3.3 + katex: 0.16.38 + khroma: 2.1.0 + lodash-es: 4.17.23 + marked: 16.4.2 + roughjs: 4.6.6 + stylis: 4.3.6 + ts-dedent: 2.2.0 + uuid: 11.1.0 + micromark-core-commonmark@2.0.3: dependencies: decode-named-character-reference: 1.2.0 @@ -10757,6 +13280,16 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + micromark-extension-gfm-autolink-literal@2.1.0: dependencies: micromark-util-character: 2.1.1 @@ -10778,40 +13311,91 @@ snapshots: micromark-extension-gfm-strikethrough@2.1.0: dependencies: devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-resolve-all: 2.0.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 - micromark-extension-gfm-table@2.1.1: + micromark-extension-mdx-jsx@3.0.2: dependencies: + '@types/estree': 1.0.8 devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 + vfile-message: 4.0.3 - micromark-extension-gfm-tagfilter@2.0.0: + micromark-extension-mdx-md@2.0.0: dependencies: micromark-util-types: 2.0.2 - micromark-extension-gfm-task-list-item@2.1.0: + micromark-extension-mdxjs-esm@3.0.0: dependencies: + '@types/estree': 1.0.8 devlop: 1.1.0 - micromark-factory-space: 2.0.1 + micromark-core-commonmark: 2.0.3 micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 - micromark-extension-gfm@3.0.0: + micromark-extension-mdxjs@3.0.0: dependencies: - micromark-extension-gfm-autolink-literal: 2.1.0 - micromark-extension-gfm-footnote: 2.1.0 - micromark-extension-gfm-strikethrough: 2.1.0 - micromark-extension-gfm-table: 2.1.1 - micromark-extension-gfm-tagfilter: 2.0.0 - micromark-extension-gfm-task-list-item: 2.1.0 + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 micromark-util-combine-extensions: 2.0.1 micromark-util-types: 2.0.2 @@ -10828,6 +13412,18 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + micromark-factory-space@2.0.1: dependencies: micromark-util-character: 2.1.1 @@ -10880,6 +13476,16 @@ snapshots: micromark-util-encode@2.0.1: {} + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + micromark-util-html-tag-name@2.0.1: {} micromark-util-normalize-identifier@2.0.1: @@ -10941,6 +13547,8 @@ snapshots: min-indent@1.0.1: {} + mini-svg-data-uri@1.4.4: {} + minimatch@10.2.4: dependencies: brace-expansion: 5.0.3 @@ -10959,7 +13567,7 @@ snapshots: minimist@1.2.8: {} - minipass@7.1.2: {} + minipass@7.1.3: {} mkdirp-classic@0.5.3: optional: true @@ -11092,7 +13700,6 @@ snapshots: define-lazy-prop: 3.0.0 is-inside-container: 1.0.0 wsl-utils: 0.1.0 - optional: true open@11.0.0: dependencies: @@ -11141,6 +13748,15 @@ snapshots: package-manager-detector@1.6.0: {} + pagefind@1.4.0: + optionalDependencies: + '@pagefind/darwin-arm64': 1.4.0 + '@pagefind/darwin-x64': 1.4.0 + '@pagefind/freebsd-x64': 1.4.0 + '@pagefind/linux-arm64': 1.4.0 + '@pagefind/linux-x64': 1.4.0 + '@pagefind/windows-x64': 1.4.0 + pako@1.0.11: {} papaparse@5.5.3: {} @@ -11149,6 +13765,16 @@ snapshots: dependencies: callsites: 3.1.0 + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.2.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + parse-latin@7.0.0: dependencies: '@types/nlcst': 2.0.3 @@ -11168,6 +13794,8 @@ snapshots: path-browserify@1.0.1: {} + path-data-parser@0.1.0: {} + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -11176,13 +13804,15 @@ snapshots: path-parse@1.0.7: {} - path-scurry@2.0.1: + path-scurry@2.0.2: dependencies: lru-cache: 11.2.6 - minipass: 7.1.2 + minipass: 7.1.3 pathe@2.0.3: {} + pathval@2.0.1: {} + piccolore@0.1.3: {} picocolors@1.1.1: {} @@ -11211,12 +13841,31 @@ snapshots: playwright-core@1.57.0: {} + playwright-core@1.58.2: {} + playwright@1.57.0: dependencies: playwright-core: 1.57.0 optionalDependencies: fsevents: 2.3.2 + playwright@1.58.2: + dependencies: + playwright-core: 1.58.2 + optionalDependencies: + fsevents: 2.3.2 + + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + + polished@4.3.1: + dependencies: + '@babel/runtime': 7.28.4 + possible-typed-array-names@1.1.0: {} postcss-import@15.1.0(postcss@8.5.6): @@ -11312,6 +13961,8 @@ snapshots: once: 1.4.0 optional: true + punycode.js@2.3.1: {} + punycode@2.3.1: {} quansync@0.2.11: {} @@ -11328,6 +13979,25 @@ snapshots: strip-json-comments: 2.0.1 optional: true + react-docgen-typescript@2.4.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + react-docgen@8.0.3: + dependencies: + '@babel/core': 7.28.5 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + '@types/doctrine': 0.0.9 + '@types/resolve': 1.20.2 + doctrine: 3.0.0 + resolve: 1.22.11 + strip-indent: 4.1.1 + transitivePeerDependencies: + - supports-color + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 @@ -11345,6 +14015,8 @@ snapshots: react-refresh@0.17.0: {} + react-refresh@0.18.0: {} + react-use-measure@2.1.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3): dependencies: react: 19.2.3 @@ -11387,6 +14059,43 @@ snapshots: readdirp@5.0.0: {} + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + redent@3.0.0: dependencies: indent-string: 4.0.0 @@ -11453,6 +14162,29 @@ snapshots: dependencies: jsesc: 3.1.0 + rehype-expressive-code@0.41.7: + dependencies: + expressive-code: 0.41.7 + + rehype-format@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-format: 1.1.0 + + rehype-mermaid@3.0.0(playwright@1.58.2): + dependencies: + '@types/hast': 3.0.4 + hast-util-from-html-isomorphic: 2.0.0 + hast-util-to-text: 4.0.2 + mermaid-isomorphic: 3.1.0(playwright@1.58.2) + mini-svg-data-uri: 1.4.4 + space-separated-tokens: 2.0.2 + unified: 11.0.5 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + optionalDependencies: + playwright: 1.58.2 + rehype-parse@9.0.1: dependencies: '@types/hast': 3.0.4 @@ -11465,6 +14197,14 @@ snapshots: hast-util-raw: 9.1.0 vfile: 6.0.3 + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + rehype-stringify@10.0.1: dependencies: '@types/hast': 3.0.4 @@ -11478,6 +14218,15 @@ snapshots: rehype-stringify: 10.0.1 unified: 11.0.5 + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + remark-gfm@4.0.1: dependencies: '@types/mdast': 4.0.4 @@ -11489,6 +14238,13 @@ snapshots: transitivePeerDependencies: - supports-color + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + remark-parse@11.0.0: dependencies: '@types/mdast': 4.0.4 @@ -11519,6 +14275,8 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 + require-directory@2.1.1: {} + require-from-string@2.0.2: {} resolve-from@4.0.0: {} @@ -11619,12 +14377,21 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + run-applescript@7.1.0: {} run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 + rw@1.3.3: {} + safe-array-concat@1.1.3: dependencies: call-bind: 1.0.8 @@ -11648,6 +14415,8 @@ snapshots: es-errors: 1.3.0 is-regex: 1.2.1 + safer-buffer@2.1.2: {} + sax@1.4.3: {} sax@1.5.0: {} @@ -11704,7 +14473,7 @@ snapshots: dependencies: decode-ico: 0.4.1 ico-endec: 0.1.6 - sharp: 0.34.5 + sharp: 0.33.5 optional: true sharp@0.32.6: @@ -11723,6 +14492,32 @@ snapshots: - react-native-b4a optional: true + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.1.2 + semver: 7.7.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + sharp@0.34.5: dependencies: '@img/colour': 1.0.0 @@ -11817,7 +14612,6 @@ snapshots: simple-swizzle@0.2.4: dependencies: is-arrayish: 0.3.4 - optional: true sisteransi@1.0.5: {} @@ -11867,6 +14661,29 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@storybook/global': 5.0.0 + '@storybook/icons': 2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@testing-library/jest-dom': 6.9.1 + '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) + '@vitest/expect': 3.2.4 + '@vitest/spy': 3.2.4 + esbuild: 0.27.3 + open: 10.2.0 + recast: 0.23.11 + semver: 7.7.3 + use-sync-external-store: 1.6.0(react@19.2.3) + ws: 8.19.0 + optionalDependencies: + prettier: 3.8.1 + transitivePeerDependencies: + - '@testing-library/dom' + - bufferutil + - react + - react-dom + - utf-8-validate + stream-replace-string@2.0.0: {} streamx@2.23.0: @@ -11975,12 +14792,16 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-bom@3.0.0: {} + strip-comments@2.0.1: {} strip-indent@3.0.0: dependencies: min-indent: 1.0.1 + strip-indent@4.1.1: {} + strip-json-comments@2.0.1: optional: true @@ -11989,6 +14810,16 @@ snapshots: strnum@2.1.2: optional: true + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + stylis@4.3.6: {} + sucrase@3.35.1: dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -12129,6 +14960,8 @@ snapshots: tiny-inflate@1.0.3: {} + tiny-invariant@1.3.3: {} + tinybench@2.9.0: {} tinyexec@1.0.2: {} @@ -12138,8 +14971,12 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyrainbow@2.0.0: {} + tinyrainbow@3.0.3: {} + tinyspy@4.0.4: {} + tldts-core@7.0.19: {} tldts@7.0.19: @@ -12177,14 +15014,21 @@ snapshots: dependencies: typescript: 5.9.3 + ts-dedent@2.2.0: {} + ts-interface-checker@0.1.13: {} tsconfck@3.1.6(typescript@5.9.3): optionalDependencies: typescript: 5.9.3 - tslib@2.8.1: - optional: true + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} tunnel-agent@0.6.0: dependencies: @@ -12232,10 +15076,25 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 + typedoc-plugin-markdown@4.10.0(typedoc@0.28.17(typescript@5.9.3)): + dependencies: + typedoc: 0.28.17(typescript@5.9.3) + + typedoc@0.28.17(typescript@5.9.3): + dependencies: + '@gerrit0/mini-shiki': 3.23.0 + lunr: 2.3.9 + markdown-it: 14.1.1 + minimatch: 9.0.9 + typescript: 5.9.3 + yaml: 2.8.2 + typescript@5.8.2: {} typescript@5.9.3: {} + uc.micro@2.1.0: {} + ufo@1.6.3: {} ultrahtml@1.6.0: {} @@ -12307,6 +15166,10 @@ snapshots: '@types/unist': 3.0.3 array-iterate: 2.0.1 + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-position@5.0.0: dependencies: '@types/unist': 3.0.3 @@ -12337,6 +15200,18 @@ snapshots: universalify@2.0.1: {} + unplugin@1.16.1: + dependencies: + acorn: 8.15.0 + webpack-virtual-modules: 0.6.2 + + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + unstorage@1.17.4(@azure/identity@4.13.0)(@azure/storage-blob@12.29.1): dependencies: anymatch: 3.1.3 @@ -12376,10 +15251,18 @@ snapshots: dependencies: punycode: 2.3.1 + use-sync-external-store@1.6.0(react@19.2.3): + dependencies: + react: 19.2.3 + util-deprecate@1.0.2: {} + uuid@11.1.0: {} + uuid@8.3.2: {} + uuid@9.0.1: {} + vfile-location@5.0.3: dependencies: '@types/unist': 3.0.3 @@ -12395,7 +15278,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-plugin-dts@4.5.4(@types/node@20.19.27)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)): + vite-plugin-dts@4.5.4(@types/node@20.19.27)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)): dependencies: '@microsoft/api-extractor': 7.57.5(@types/node@20.19.27) '@rollup/pluginutils': 5.3.0(rollup@4.59.0) @@ -12408,7 +15291,7 @@ snapshots: magic-string: 0.30.21 typescript: 5.9.3 optionalDependencies: - vite: 6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + vite: 6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - rollup @@ -12427,7 +15310,13 @@ snapshots: transitivePeerDependencies: - supports-color - vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): + vite-plugin-singlefile@2.3.2(rollup@4.59.0)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)): + dependencies: + micromatch: 4.0.8 + rollup: 4.59.0 + vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + + vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -12438,12 +15327,12 @@ snapshots: optionalDependencies: '@types/node': 20.19.27 fsevents: 2.3.3 - jiti: 2.6.1 + jiti: 1.21.7 lightningcss: 1.31.1 terser: 5.44.1 yaml: 2.8.2 - vite@6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): + vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -12454,14 +15343,14 @@ snapshots: optionalDependencies: '@types/node': 25.0.3 fsevents: 2.3.3 - jiti: 1.21.7 + jiti: 2.6.1 lightningcss: 1.31.1 terser: 5.44.1 yaml: 2.8.2 - vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): + vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): dependencies: - esbuild: 0.25.12 + esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -12479,10 +15368,10 @@ snapshots: optionalDependencies: vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) - vitest@4.0.18(@types/node@20.19.27)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): + vitest@4.0.18(@types/node@20.19.27)(jiti@1.21.7)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -12499,7 +15388,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + vite: 6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 20.19.27 @@ -12517,44 +15406,6 @@ snapshots: - tsx - yaml - vitest@4.0.18(@types/node@25.0.3)(jiti@1.21.7)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): - dependencies: - '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) - '@vitest/pretty-format': 4.0.18 - '@vitest/runner': 4.0.18 - '@vitest/snapshot': 4.0.18 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 - es-module-lexer: 1.7.0 - expect-type: 1.3.0 - magic-string: 0.30.21 - obug: 2.1.1 - pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.10.0 - tinybench: 2.9.0 - tinyexec: 1.0.2 - tinyglobby: 0.2.15 - tinyrainbow: 3.0.3 - vite: 6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 25.0.3 - jsdom: 28.1.0 - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - yaml - vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 @@ -12593,6 +15444,21 @@ snapshots: - tsx - yaml + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + vscode-uri@3.1.0: {} w3c-xmlserializer@5.0.0: @@ -12605,6 +15471,8 @@ snapshots: webidl-conversions@8.0.1: {} + webpack-virtual-modules@0.6.2: {} + whatwg-mimetype@5.0.0: {} whatwg-url@16.0.1: @@ -12691,10 +15559,10 @@ snapshots: workbox-build@7.4.0(@types/babel__core@7.20.5): dependencies: '@apideck/better-ajv-errors': 0.3.6(ajv@8.18.0) - '@babel/core': 7.28.5 - '@babel/preset-env': 7.28.5(@babel/core@7.28.5) + '@babel/core': 7.29.0 + '@babel/preset-env': 7.28.5(@babel/core@7.29.0) '@babel/runtime': 7.28.4 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.28.5)(@types/babel__core@7.20.5)(rollup@2.80.0) + '@rollup/plugin-babel': 5.3.1(@babel/core@7.29.0)(@types/babel__core@7.20.5)(rollup@2.80.0) '@rollup/plugin-node-resolve': 15.3.1(rollup@2.80.0) '@rollup/plugin-replace': 2.4.2(rollup@2.80.0) '@rollup/plugin-terser': 0.4.4(rollup@2.80.0) @@ -12812,10 +15680,11 @@ snapshots: wrappy@1.0.2: {} + ws@8.19.0: {} + wsl-utils@0.1.0: dependencies: is-wsl: 3.1.0 - optional: true wsl-utils@0.3.1: dependencies: @@ -12840,6 +15709,16 @@ snapshots: yargs-parser@22.0.0: {} + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + yargs@18.0.0: dependencies: cliui: 9.0.1 From 6b5fb78fb804720d944b7cec354fad12916315e9 Mon Sep 17 00:00:00 2001 From: Jukka-Matti Turtiainen Date: Tue, 17 Mar 2026 18:43:57 +0200 Subject: [PATCH 2/3] fix: upgrade Storybook config to v10 (remove bundled addons, fix imports) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit addon-essentials and blocks are bundled into storybook core in v10 — remove the separate packages and update manager/preview imports to use the new storybook/* entry points. Delete orphaned ScatterPlot placeholder story. Co-Authored-By: Claude Opus 4.6 (1M context) --- .storybook/main.ts | 2 +- .storybook/manager.ts | 4 +- .storybook/preview.tsx | 2 +- .../stories/charts/ScatterPlot.stories.tsx | 56 --- package.json | 2 - pnpm-lock.yaml | 350 +++++------------- 6 files changed, 95 insertions(+), 321 deletions(-) delete mode 100644 .storybook/stories/charts/ScatterPlot.stories.tsx diff --git a/.storybook/main.ts b/.storybook/main.ts index 28d3ca28c..874ba20af 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -2,7 +2,7 @@ import type { StorybookConfig } from '@storybook/react-vite'; const config: StorybookConfig = { stories: ['./stories/**/*.stories.@(ts|tsx)'], - addons: ['@storybook/addon-essentials', '@storybook/addon-a11y', '@storybook/addon-themes'], + addons: ['@storybook/addon-a11y', '@storybook/addon-themes'], framework: { name: '@storybook/react-vite', options: {}, diff --git a/.storybook/manager.ts b/.storybook/manager.ts index 9ef875bd9..85ba2ef07 100644 --- a/.storybook/manager.ts +++ b/.storybook/manager.ts @@ -1,5 +1,5 @@ -import { addons } from '@storybook/manager-api'; -import { themes } from '@storybook/theming'; +import { addons } from 'storybook/manager-api'; +import { themes } from 'storybook/theming'; addons.setConfig({ theme: { diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index deb004d23..dee3fd778 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,4 +1,4 @@ -import type { Preview } from '@storybook/react'; +import type { Preview } from 'storybook/preview-api'; import '../packages/ui/src/styles/theme.css'; import '../packages/ui/src/styles/components.css'; diff --git a/.storybook/stories/charts/ScatterPlot.stories.tsx b/.storybook/stories/charts/ScatterPlot.stories.tsx deleted file mode 100644 index d78f6fd31..000000000 --- a/.storybook/stories/charts/ScatterPlot.stories.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -/** - * ScatterPlot is not a standalone export from @variscout/charts. - * Scatter-like visualization is handled via PerformanceIChart (Cpk scatter) - * or regression plots. This story serves as a placeholder for future - * standalone scatter plot extraction. - */ - -// Placeholder until ScatterPlot is extracted as a standalone component -const ScatterPlotPlaceholder = ({ - width = 600, - height = 400, -}: { - width?: number; - height?: number; -}) => ( -
-
-

ScatterPlot

-

- Scatter visualization is provided by PerformanceIChart (Cpk scatter). -

-

See Charts/PerformanceIChart for the live component.

-
-
-); - -const meta = { - title: 'Charts/ScatterPlot', - component: ScatterPlotPlaceholder, - tags: ['autodocs'], - parameters: { layout: 'padded' }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Placeholder: Story = { - args: { - width: 600, - height: 400, - }, -}; diff --git a/package.json b/package.json index 67fdb66ae..7b5517fbf 100644 --- a/package.json +++ b/package.json @@ -35,9 +35,7 @@ "devDependencies": { "@eslint/js": "^9.39.2", "@storybook/addon-a11y": "^10.2.19", - "@storybook/addon-essentials": "^8.6.14", "@storybook/addon-themes": "^10.2.19", - "@storybook/blocks": "^8.6.14", "@storybook/react": "^10.2.19", "@storybook/react-vite": "^10.2.19", "@typescript-eslint/eslint-plugin": "^8.56.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 99e90c2a3..4794f9fc6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,15 +25,9 @@ importers: '@storybook/addon-a11y': specifier: ^10.2.19 version: 10.2.19(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/addon-essentials': - specifier: ^8.6.14 - version: 8.6.14(@types/react@19.2.7)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) '@storybook/addon-themes': specifier: ^10.2.19 version: 10.2.19(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/blocks': - specifier: ^8.6.14 - version: 8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) '@storybook/react': specifier: ^10.2.19 version: 10.2.19(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3) @@ -148,7 +142,7 @@ importers: version: 18.3.7(@types/react@18.3.27) '@vitejs/plugin-react': specifier: ^4.4.1 - version: 4.7.0(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + version: 4.7.0(vite@6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) autoprefixer: specifier: ^10.4.23 version: 10.4.23(postcss@8.5.6) @@ -166,10 +160,10 @@ importers: version: 5.9.3 vite: specifier: ^6.3.0 - version: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + version: 6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) vitest: specifier: ^4.0.18 - version: 4.0.18(@types/node@25.0.3)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + version: 4.0.18(@types/node@25.0.3)(jiti@1.21.7)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) apps/docs: dependencies: @@ -512,7 +506,7 @@ importers: version: 18.3.7(@types/react@18.3.27) '@vitejs/plugin-react': specifier: ^4.4.1 - version: 4.7.0(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + version: 4.7.0(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) autoprefixer: specifier: ^10.4.23 version: 10.4.23(postcss@8.5.6) @@ -530,13 +524,13 @@ importers: version: 5.9.3 vite: specifier: ^6.3.0 - version: 6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + version: 6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) vite-plugin-dts: specifier: ^4.5.0 - version: 4.5.4(@types/node@20.19.27)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + version: 4.5.4(@types/node@20.19.27)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) vitest: specifier: ^4.0.18 - version: 4.0.18(@types/node@20.19.27)(jiti@1.21.7)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + version: 4.0.18(@types/node@20.19.27)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) packages: @@ -2016,12 +2010,6 @@ packages: '@mdx-js/mdx@3.1.1': resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} - '@mdx-js/react@3.1.1': - resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} - peerDependencies: - '@types/react': '>=16' - react: '>=16' - '@mermaid-js/parser@1.0.1': resolution: {integrity: sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==} @@ -2345,73 +2333,11 @@ packages: peerDependencies: storybook: ^10.2.19 - '@storybook/addon-actions@8.6.14': - resolution: {integrity: sha512-mDQxylxGGCQSK7tJPkD144J8jWh9IU9ziJMHfB84PKpI/V5ZgqMDnpr2bssTrUaGDqU5e1/z8KcRF+Melhs9pQ==} - peerDependencies: - storybook: ^8.6.14 - - '@storybook/addon-backgrounds@8.6.14': - resolution: {integrity: sha512-l9xS8qWe5n4tvMwth09QxH2PmJbCctEvBAc1tjjRasAfrd69f7/uFK4WhwJAstzBTNgTc8VXI4w8ZR97i1sFbg==} - peerDependencies: - storybook: ^8.6.14 - - '@storybook/addon-controls@8.6.14': - resolution: {integrity: sha512-IiQpkNJdiRyA4Mq9mzjZlvQugL/aE7hNgVxBBGPiIZG6wb6Ht9hNnBYpap5ZXXFKV9p2qVI0FZK445ONmAa+Cw==} - peerDependencies: - storybook: ^8.6.14 - - '@storybook/addon-docs@8.6.14': - resolution: {integrity: sha512-Obpd0OhAF99JyU5pp5ci17YmpcQtMNgqW2pTXV8jAiiipWpwO++hNDeQmLmlSXB399XjtRDOcDVkoc7rc6JzdQ==} - peerDependencies: - storybook: ^8.6.14 - - '@storybook/addon-essentials@8.6.14': - resolution: {integrity: sha512-5ZZSHNaW9mXMOFkoPyc3QkoNGdJHETZydI62/OASR0lmPlJ1065TNigEo5dJddmZNn0/3bkE8eKMAzLnO5eIdA==} - peerDependencies: - storybook: ^8.6.14 - - '@storybook/addon-highlight@8.6.14': - resolution: {integrity: sha512-4H19OJlapkofiE9tM6K/vsepf4ir9jMm9T+zw5L85blJZxhKZIbJ6FO0TCG9PDc4iPt3L6+aq5B0X29s9zicNQ==} - peerDependencies: - storybook: ^8.6.14 - - '@storybook/addon-measure@8.6.14': - resolution: {integrity: sha512-1Tlyb72NX8aAqm6I6OICsUuGOP6hgnXcuFlXucyhKomPa6j3Eu2vKu561t/f0oGtAK2nO93Z70kVaEh5X+vaGw==} - peerDependencies: - storybook: ^8.6.14 - - '@storybook/addon-outline@8.6.14': - resolution: {integrity: sha512-CW857JvN6OxGWElqjlzJO2S69DHf+xO3WsEfT5mT3ZtIjmsvRDukdWfDU9bIYUFyA2lFvYjncBGjbK+I91XR7w==} - peerDependencies: - storybook: ^8.6.14 - '@storybook/addon-themes@10.2.19': resolution: {integrity: sha512-TzcX/aqzZrQUypDATywLOenVoa1CTXBthODoY9odLsLLrxVaoeqsAdulkmOjeppKR1FigcERyIjIWPB8W48dag==} peerDependencies: storybook: ^10.2.19 - '@storybook/addon-toolbars@8.6.14': - resolution: {integrity: sha512-W/wEXT8h3VyZTVfWK/84BAcjAxTdtRiAkT2KAN0nbSHxxB5KEM1MjKpKu2upyzzMa3EywITqbfy4dP6lpkVTwQ==} - peerDependencies: - storybook: ^8.6.14 - - '@storybook/addon-viewport@8.6.14': - resolution: {integrity: sha512-gNzVQbMqRC+/4uQTPI2ZrWuRHGquTMZpdgB9DrD88VTEjNudP+J6r8myLfr2VvGksBbUMHkGHMXHuIhrBEnXYA==} - peerDependencies: - storybook: ^8.6.14 - - '@storybook/blocks@8.6.14': - resolution: {integrity: sha512-rBMHAfA39AGHgkrDze4RmsnQTMw1ND5fGWobr9pDcJdnDKWQWNRD7Nrlxj0gFlN3n4D9lEZhWGdFrCbku7FVAQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^8.6.14 - peerDependenciesMeta: - react: - optional: true - react-dom: - optional: true - '@storybook/builder-vite@10.2.19': resolution: {integrity: sha512-a59xALzM9GeYh6p+wzAeBbDyIe+qyrC4nxS3QNzb5i2ZOhrq1iIpvnDaOWe80NC8mV3IlqUEGY8Uawkf//1Rmg==} peerDependencies: @@ -2436,21 +2362,9 @@ packages: webpack: optional: true - '@storybook/csf-plugin@8.6.14': - resolution: {integrity: sha512-dErtc9teAuN+eelN8FojzFE635xlq9cNGGGEu0WEmMUQ4iJ8pingvBO1N8X3scz4Ry7KnxX++NNf3J3gpxS8qQ==} - peerDependencies: - storybook: ^8.6.14 - '@storybook/global@5.0.0': resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} - '@storybook/icons@1.6.0': - resolution: {integrity: sha512-hcFZIjW8yQz8O8//2WTIXylm5Xsgc+lW9ISLgUk1xGmptIJQRdlhVIXCpSyLrQaaRiyhQRaVg7l3BD9S216BHw==} - engines: {node: '>=14.0.0'} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - '@storybook/icons@2.0.1': resolution: {integrity: sha512-/smVjw88yK3CKsiuR71vNgWQ9+NuY2L+e8X7IMrFjexjm6ZR8ULrV2DRkTA61aV6ryefslzHEGDInGpnNeIocg==} peerDependencies: @@ -2464,13 +2378,6 @@ packages: react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 storybook: ^10.2.19 - '@storybook/react-dom-shim@8.6.14': - resolution: {integrity: sha512-0hixr3dOy3f3M+HBofp3jtMQMS+sqzjKNgl7Arfuj3fvjmyXOks/yGjDImySR4imPtEllvPZfhiQNlejheaInw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.6.14 - '@storybook/react-vite@10.2.19': resolution: {integrity: sha512-2/yMKrK4IqMIZicRpPMoIg+foBuWnkaEWt0R4V4hjErDj/SC3D9ov+GUqhjKJ81TegijhKzNpwnSD7Nf87haKw==} peerDependencies: @@ -2850,9 +2757,6 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - '@types/uuid@9.0.8': - resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} - '@typescript-eslint/eslint-plugin@8.56.1': resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5268,9 +5172,6 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - map-or-similar@1.5.0: - resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} - markdown-extensions@2.0.0: resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} engines: {node: '>=16'} @@ -5357,9 +5258,6 @@ packages: mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - memoizerific@1.11.3: - resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -5806,10 +5704,6 @@ packages: points-on-path@0.2.1: resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} - polished@4.3.1: - resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} - engines: {node: '>=10'} - possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -6827,10 +6721,6 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - unplugin@1.16.1: - resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} - engines: {node: '>=14.0.0'} - unplugin@2.3.11: resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} @@ -6929,10 +6819,6 @@ packages: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - vfile-location@5.0.3: resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} @@ -9069,12 +8955,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.3)': - dependencies: - '@types/mdx': 2.0.13 - '@types/react': 19.2.7 - react: 19.2.3 - '@mermaid-js/parser@1.0.1': dependencies: langium: 4.2.1 @@ -9395,98 +9275,11 @@ snapshots: axe-core: 4.11.1 storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@storybook/addon-actions@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - '@storybook/global': 5.0.0 - '@types/uuid': 9.0.8 - dequal: 2.0.3 - polished: 4.3.1 - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - uuid: 9.0.1 - - '@storybook/addon-backgrounds@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - '@storybook/global': 5.0.0 - memoizerific: 1.11.3 - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - ts-dedent: 2.2.0 - - '@storybook/addon-controls@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - '@storybook/global': 5.0.0 - dequal: 2.0.3 - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - ts-dedent: 2.2.0 - - '@storybook/addon-docs@8.6.14(@types/react@19.2.7)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - '@mdx-js/react': 3.1.1(@types/react@19.2.7)(react@19.2.3) - '@storybook/blocks': 8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/csf-plugin': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/react-dom-shim': 8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - ts-dedent: 2.2.0 - transitivePeerDependencies: - - '@types/react' - - '@storybook/addon-essentials@8.6.14(@types/react@19.2.7)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - '@storybook/addon-actions': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/addon-backgrounds': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/addon-controls': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/addon-docs': 8.6.14(@types/react@19.2.7)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/addon-highlight': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/addon-measure': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/addon-outline': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/addon-toolbars': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - '@storybook/addon-viewport': 8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)) - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - ts-dedent: 2.2.0 - transitivePeerDependencies: - - '@types/react' - - '@storybook/addon-highlight@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - '@storybook/global': 5.0.0 - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - - '@storybook/addon-measure@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - '@storybook/global': 5.0.0 - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - tiny-invariant: 1.3.3 - - '@storybook/addon-outline@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - '@storybook/global': 5.0.0 - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - ts-dedent: 2.2.0 - '@storybook/addon-themes@10.2.19(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': dependencies: storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) ts-dedent: 2.2.0 - '@storybook/addon-toolbars@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - - '@storybook/addon-viewport@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - memoizerific: 1.11.3 - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - - '@storybook/blocks@8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - '@storybook/icons': 1.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - ts-dedent: 2.2.0 - optionalDependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - '@storybook/builder-vite@10.2.19(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: '@storybook/csf-plugin': 10.2.19(esbuild@0.27.3)(rollup@4.59.0)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) @@ -9507,18 +9300,8 @@ snapshots: rollup: 4.59.0 vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) - '@storybook/csf-plugin@8.6.14(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - unplugin: 1.16.1 - '@storybook/global@5.0.0': {} - '@storybook/icons@1.6.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - '@storybook/icons@2.0.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': dependencies: react: 19.2.3 @@ -9530,12 +9313,6 @@ snapshots: react-dom: 19.2.3(react@19.2.3) storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@storybook/react-dom-shim@8.6.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))': - dependencies: - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - storybook: 10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@storybook/react-vite@10.2.19(esbuild@0.27.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.59.0)(storybook@10.2.19(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) @@ -9959,8 +9736,6 @@ snapshots: '@types/unist@3.0.3': {} - '@types/uuid@9.0.8': {} - '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -10222,7 +9997,19 @@ snapshots: - react-native-b4a optional: true - '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) + '@rolldown/pluginutils': 1.0.0-beta.27 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) @@ -10230,7 +10017,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + vite: 6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -10289,13 +10076,21 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.18(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': + dependencies: + '@vitest/spy': 4.0.18 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + + '@vitest/mocker@4.0.18(vite@6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + vite: 6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) '@vitest/mocker@4.0.18(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2))': dependencies: @@ -13013,8 +12808,6 @@ snapshots: dependencies: semver: 7.7.3 - map-or-similar@1.5.0: {} - markdown-extensions@2.0.0: {} markdown-it@14.1.1: @@ -13223,10 +13016,6 @@ snapshots: mdurl@2.0.0: {} - memoizerific@1.11.3: - dependencies: - map-or-similar: 1.5.0 - merge2@1.4.1: {} mermaid-isomorphic@3.1.0(playwright@1.58.2): @@ -13862,10 +13651,6 @@ snapshots: path-data-parser: 0.1.0 points-on-curve: 0.2.0 - polished@4.3.1: - dependencies: - '@babel/runtime': 7.28.4 - possible-typed-array-names@1.1.0: {} postcss-import@15.1.0(postcss@8.5.6): @@ -15200,11 +14985,6 @@ snapshots: universalify@2.0.1: {} - unplugin@1.16.1: - dependencies: - acorn: 8.15.0 - webpack-virtual-modules: 0.6.2 - unplugin@2.3.11: dependencies: '@jridgewell/remapping': 2.3.5 @@ -15261,8 +15041,6 @@ snapshots: uuid@8.3.2: {} - uuid@9.0.1: {} - vfile-location@5.0.3: dependencies: '@types/unist': 3.0.3 @@ -15278,7 +15056,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-plugin-dts@4.5.4(@types/node@20.19.27)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)): + vite-plugin-dts@4.5.4(@types/node@20.19.27)(rollup@4.59.0)(typescript@5.9.3)(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)): dependencies: '@microsoft/api-extractor': 7.57.5(@types/node@20.19.27) '@rollup/pluginutils': 5.3.0(rollup@4.59.0) @@ -15291,7 +15069,7 @@ snapshots: magic-string: 0.30.21 typescript: 5.9.3 optionalDependencies: - vite: 6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + vite: 6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - rollup @@ -15316,7 +15094,7 @@ snapshots: rollup: 4.59.0 vite: 7.3.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) - vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): + vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -15327,6 +15105,22 @@ snapshots: optionalDependencies: '@types/node': 20.19.27 fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.31.1 + terser: 5.44.1 + yaml: 2.8.2 + + vite@6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.59.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 25.0.3 + fsevents: 2.3.3 jiti: 1.21.7 lightningcss: 1.31.1 terser: 5.44.1 @@ -15368,10 +15162,10 @@ snapshots: optionalDependencies: vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) - vitest@4.0.18(@types/node@20.19.27)(jiti@1.21.7)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): + vitest@4.0.18(@types/node@20.19.27)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(vite@6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -15388,7 +15182,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 6.4.1(@types/node@20.19.27)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + vite: 6.4.1(@types/node@20.19.27)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 20.19.27 @@ -15406,6 +15200,44 @@ snapshots: - tsx - yaml + vitest@4.0.18(@types/node@25.0.3)(jiti@1.21.7)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): + dependencies: + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(vite@6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 6.4.1(@types/node@25.0.3)(jiti@1.21.7)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.0.3 + jsdom: 28.1.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + vitest@4.0.18(@types/node@25.0.3)(jiti@2.6.1)(jsdom@28.1.0)(lightningcss@1.31.1)(terser@5.44.1)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 From 4010f3f8fd4afcf820b0e547f6d0b573e75d2148 Mon Sep 17 00:00:00 2001 From: Jukka-Matti Turtiainen Date: Tue, 17 Mar 2026 19:15:02 +0200 Subject: [PATCH 3/3] chore: add storybook-static/ to .gitignore Co-Authored-By: Claude Opus 4.6 (1M context) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 88cff5416..392d84568 100644 --- a/.gitignore +++ b/.gitignore @@ -148,4 +148,5 @@ vite.config.ts.timestamp* # Build output site/ +storybook-static/